diff options
| -rw-r--r-- | api/settings.ts | 39 | ||||
| -rw-r--r-- | app/(tabs)/settings.tsx | 55 | ||||
| -rw-r--r-- | lib/locales.ts | 11 |
3 files changed, 105 insertions, 0 deletions
diff --git a/api/settings.ts b/api/settings.ts index 2823afa..217be01 100644 --- a/api/settings.ts +++ b/api/settings.ts @@ -5,6 +5,13 @@ interface VerifyEmailResponse { reason?: string; } +interface KidLinkCodeResponse { + success: boolean; + code?: string; + expiresInSeconds?: number; + reason?: string; +} + export async function verifyEmail( code: string, ): Promise<{ success: boolean; error?: string }> { @@ -23,6 +30,38 @@ export async function verifyEmail( } } +export async function requestKidLinkCode(): Promise<{ + success: boolean; + code?: string; + expiresInSeconds?: number; + error?: string; +}> { + try { + const response: KidLinkCodeResponse = await apiClient.post( + "/parent/kid-link-code", + ); + + if (!response.success || !response.code) { + return { + success: false, + error: response.reason || "Failed to generate link code", + }; + } + + return { + success: true, + code: response.code, + expiresInSeconds: response.expiresInSeconds, + }; + } catch (e) { + console.error("Failed to request kid link code", e); + return { + success: false, + error: e instanceof Error ? e.message : "Failed to generate link code", + }; + } +} + export interface UserProfile { email: string; emailVerified: boolean; diff --git a/app/(tabs)/settings.tsx b/app/(tabs)/settings.tsx index b4493b4..c19da37 100644 --- a/app/(tabs)/settings.tsx +++ b/app/(tabs)/settings.tsx @@ -5,6 +5,7 @@ import { Device, getDevices, getUserProfile, + requestKidLinkCode, renameDevice, UserProfile, verifyEmail, @@ -38,6 +39,12 @@ export default function SettingsScreen() { success: boolean; message: string; }>({ visible: false, success: false, message: "" }); + const [kidLinkCodeResult, setKidLinkCodeResult] = useState<{ + visible: boolean; + success: boolean; + title: string; + message: string; + }>({ visible: false, success: false, title: "", message: "" }); const showNotWired = () => setAlertVisible(true); @@ -86,6 +93,32 @@ export default function SettingsScreen() { setVerifyEmailVisible(false); }; + const handleGenerateKidLinkCode = async () => { + const result = await requestKidLinkCode(); + + if (result.success && result.code) { + const expiresMinutes = Math.max( + 1, + Math.ceil((result.expiresInSeconds ?? 300) / 60), + ); + + setKidLinkCodeResult({ + visible: true, + success: true, + title: t("kidLinkCodeTitle"), + message: `${result.code}\n${t("kidLinkCodeExpiresIn")} ${expiresMinutes} min`, + }); + return; + } + + setKidLinkCodeResult({ + visible: true, + success: false, + title: t("error"), + message: result.error || t("failedToGenerateKidLinkCode"), + }); + }; + return ( <Screen> <AlertDialog @@ -122,6 +155,15 @@ export default function SettingsScreen() { } /> + <AlertDialog + visible={kidLinkCodeResult.visible} + title={kidLinkCodeResult.title} + message={kidLinkCodeResult.message} + onClose={() => + setKidLinkCodeResult({ ...kidLinkCodeResult, visible: false }) + } + /> + <Card> <Row left={ @@ -198,6 +240,19 @@ export default function SettingsScreen() { <Card> <H2>{t("account")}</H2> <Divider /> + <ActionRow + title={t("generateKidLinkCode")} + subtitle={t("generateKidLinkCodeSubtitle")} + onPress={handleGenerateKidLinkCode} + right={ + <Ionicons + name="key-outline" + size={18} + color={colors.onSurfaceVariant} + /> + } + /> + <Divider /> {profile && !profile.emailVerified && ( <> <ActionRow diff --git a/lib/locales.ts b/lib/locales.ts index 9ba29ba..9d05382 100644 --- a/lib/locales.ts +++ b/lib/locales.ts @@ -116,6 +116,11 @@ const en = { account: "Account", verifyEmail: "Verify E-Mail", verifyYourEmailAddress: "Verify your email address.", + generateKidLinkCode: "Generate link code", + generateKidLinkCodeSubtitle: "Create a one-time code for the kid app.", + kidLinkCodeTitle: "Kid link code", + kidLinkCodeExpiresIn: "Expires in", + failedToGenerateKidLinkCode: "Failed to generate kid link code", signOut: "Sign Out", notWiredYet: "Not wired yet", hookThisUpLater: "Hook this up later.", @@ -263,6 +268,12 @@ const hr: typeof en = { account: "Račun", verifyEmail: "Potvrdi e-mail", verifyYourEmailAddress: "Potvrdite svoju e-mail adresu.", + generateKidLinkCode: "Generiraj kod za povezivanje", + generateKidLinkCodeSubtitle: + "Izradi jednokratni kod za dječju aplikaciju.", + kidLinkCodeTitle: "Kod za povezivanje uređaja", + kidLinkCodeExpiresIn: "Istječe za", + failedToGenerateKidLinkCode: "Generiranje koda nije uspjelo", signOut: "Odjava", notWiredYet: "Još nije povezano", hookThisUpLater: "Povežite ovo kasnije.", |