41 lines
1.9 KiB
TypeScript
41 lines
1.9 KiB
TypeScript
import { useLocalSearchParams } from "expo-router";
|
|
import React, { useEffect, useState } from "react";
|
|
import { Text, View } from "react-native";
|
|
import { useApp } from "../../src/app-context";
|
|
import type { Consents } from "../../src/types";
|
|
import { Button, ErrorNotice, Loading, styles } from "../../src/ui";
|
|
|
|
export default function AuthCallbackScreen() {
|
|
const params = useLocalSearchParams<{ code?: string; state?: string; error?: string }>();
|
|
const app = useApp();
|
|
const [error, setError] = useState<unknown>();
|
|
const retry = () => {
|
|
if (!params.code || !params.state || typeof window === "undefined") return;
|
|
const raw = window.sessionStorage.getItem("han.pending-consents");
|
|
if (!raw) return;
|
|
setError(undefined);
|
|
void app.finishCallback(params.code, params.state, JSON.parse(raw) as Consents).catch(setError);
|
|
};
|
|
useEffect(() => {
|
|
if (params.error) {
|
|
setError(new Error("Авторизация отменена или отклонена."));
|
|
return;
|
|
}
|
|
if (!params.code || !params.state) return;
|
|
const raw = typeof window !== "undefined" ? window.sessionStorage.getItem("han.pending-consents") : null;
|
|
if (!raw) {
|
|
setError(new Error("Не найдены локально принятые согласия. Начните вход заново."));
|
|
return;
|
|
}
|
|
const consents = JSON.parse(raw) as Consents;
|
|
void app.finishCallback(params.code, params.state, consents)
|
|
.then(() => window.sessionStorage.removeItem("han.pending-consents"))
|
|
.catch(setError);
|
|
}, [params.code, params.state, params.error]);
|
|
return <View style={styles.page}>
|
|
<Text accessibilityRole="header" style={styles.title}>Завершение входа</Text>
|
|
{!error && <Loading />}
|
|
{error && <><ErrorNotice error={error} /><Button title="Повторить bootstrap" onPress={retry} /></>}
|
|
</View>;
|
|
}
|