Files
Cibello-app/apps/mobile/src/app/(auth)/reset-password.tsx
T
Sven (AAMOS AI) 5f9526cb07
CI / Typecheck, test & build (push) Successful in 1m40s
fix(mobile): keyboard-avoidance i Screen så formulär inte göms bakom tangentbordet (FAS 35)
2026-08-14 04:01:44 +07:00

77 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
}