77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
import { useState } from "react";
|
||
import { Text } from "react-native";
|
||
import { Link, router, useLocalSearchParams } from "expo-router";
|
||
import { api } from "@/lib/api";
|
||
import { t } from "@/lib/i18n";
|
||
import { Body, Button, Input, Screen, Spacer, Title } from "@/components/ui";
|
||
import { colors, spacing } from "@/lib/theme";
|
||
|
||
/**
|
||
* Glömt lösenord (steg 2): öppnas via app-länken i mejlet
|
||
* (urlScheme://reset-password?token=…). Token kan även klistras in manuellt.
|
||
* Efter lyckad återställning loggas ALLA sessioner ut – användaren loggar in
|
||
* på nytt med sitt nya lösenord.
|
||
*/
|
||
export default function ResetPasswordScreen() {
|
||
const params = useLocalSearchParams<{ token?: string }>();
|
||
const [token, setToken] = useState(params.token ?? "");
|
||
const [password, setPassword] = useState("");
|
||
const [done, setDone] = useState(false);
|
||
const [error, setError] = useState<string | null>(null);
|
||
const [busy, setBusy] = useState(false);
|
||
|
||
const submit = async () => {
|
||
setBusy(true);
|
||
setError(null);
|
||
try {
|
||
await api("/v1/auth/reset-password", {
|
||
method: "POST",
|
||
body: { token: token.trim(), newPassword: password },
|
||
});
|
||
setDone(true);
|
||
} catch (err) {
|
||
setError(err instanceof Error ? err.message : t("common.error"));
|
||
} finally {
|
||
setBusy(false);
|
||
}
|
||
};
|
||
|
||
if (done) {
|
||
return (
|
||
<Screen style={{ flexGrow: 1, justifyContent: "center", gap: spacing.md }}>
|
||
<Title>{t("auth.resetDoneTitle")}</Title>
|
||
<Body muted>{t("auth.resetDoneBody")}</Body>
|
||
<Spacer size={spacing.sm} />
|
||
<Button label={t("auth.login")} onPress={() => router.replace("/(auth)/login")} />
|
||
</Screen>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<Screen style={{ flexGrow: 1, justifyContent: "center", gap: spacing.md }}>
|
||
<Title>{t("auth.resetTitle")}</Title>
|
||
<Body muted>{t("auth.resetBody")}</Body>
|
||
{!params.token && (
|
||
<Input
|
||
placeholder={t("auth.resetTokenPlaceholder")}
|
||
autoCapitalize="none"
|
||
value={token}
|
||
onChangeText={setToken}
|
||
/>
|
||
)}
|
||
<Input
|
||
placeholder={t("auth.newPassword")}
|
||
secureTextEntry
|
||
value={password}
|
||
onChangeText={setPassword}
|
||
/>
|
||
{error && <Text style={{ color: colors.danger }}>{error}</Text>}
|
||
<Button label={t("auth.resetSubmit")} onPress={() => void submit()} loading={busy} />
|
||
<Spacer size={spacing.sm} />
|
||
<Link href="/(auth)/login" style={{ textAlign: "center", color: colors.primaryDark }}>
|
||
{t("auth.backToLogin")}
|
||
</Link>
|
||
</Screen>
|
||
);
|
||
}
|