64 lines
3.6 KiB
TypeScript
64 lines
3.6 KiB
TypeScript
import { useQuery } from "@tanstack/react-query";
|
|
import { Link } from "expo-router";
|
|
import React, { useState } from "react";
|
|
import { ScrollView, Text, View } from "react-native";
|
|
import { useApp } from "../src/app-context";
|
|
import { profileApi } from "../src/services";
|
|
import { Button, ErrorNotice, Header, Loading, styles } from "../src/ui";
|
|
|
|
export default function ProfileScreen() {
|
|
const app = useApp();
|
|
const enabled = app.authStatus === "authenticated";
|
|
const profile = useQuery({ queryKey: ["profile"], queryFn: profileApi.me, enabled });
|
|
const documents = useQuery({ queryKey: ["documents"], queryFn: profileApi.documents, enabled });
|
|
const [downloadError, setDownloadError] = useState<unknown>();
|
|
|
|
const download = async (id: string) => {
|
|
try {
|
|
const result = await profileApi.documentUrl(id);
|
|
if (typeof window !== "undefined") window.location.assign(result.download_url);
|
|
} catch (error) { setDownloadError(error); }
|
|
};
|
|
|
|
if (!enabled) return <ScrollView contentContainerStyle={styles.page}>
|
|
<Header status={app.authStatus} realtime={app.realtimeState} />
|
|
<Text accessibilityRole="header" style={styles.title}>Профиль</Text>
|
|
<Text style={styles.text}>Профиль доступен после авторизации.</Text>
|
|
<Link href="/" style={styles.link}>Перейти в чат для входа</Link>
|
|
</ScrollView>;
|
|
|
|
const personal = profile.data?.profile.personal_data;
|
|
return <ScrollView contentContainerStyle={styles.page}>
|
|
<Header status={app.authStatus} realtime={app.realtimeState} onLogout={() => void app.signOut()} />
|
|
<Text accessibilityRole="header" style={styles.title}>Профиль</Text>
|
|
{(profile.isLoading || documents.isLoading) && <Loading />}
|
|
{(profile.error || documents.error) && <ErrorNotice error={profile.error ?? documents.error} retry={() => { void profile.refetch(); void documents.refetch(); }} />}
|
|
<View style={styles.card}>
|
|
<Text accessibilityRole="header" style={styles.heading}>Личные данные</Text>
|
|
<Row label="ФИО" value={personal?.full_name} />
|
|
<Row label="Гражданство" value={personal?.citizenship} />
|
|
<Row label="Телефон в РФ" value={personal?.russian_phone} />
|
|
<Row label="Зарубежный телефон" value={personal?.foreign_phone} />
|
|
<Row label="Email" value={personal?.email} />
|
|
<Text style={styles.muted}>Редактирование профиля недоступно. Для изменения данных напишите оператору.</Text>
|
|
<Link href="/" style={styles.link}>Написать оператору</Link>
|
|
</View>
|
|
<View style={styles.card}>
|
|
<Text accessibilityRole="header" style={styles.heading}>Документы</Text>
|
|
{!documents.data?.items.length && <Text style={styles.muted}>Документов пока нет.</Text>}
|
|
{documents.data?.items.map((document) => <View key={document.document_id} style={styles.row}>
|
|
<View style={{ flex: 1 }}>
|
|
<Text style={styles.text}>{document.name}</Text>
|
|
<Text style={styles.muted}>{new Date(document.sent_at).toLocaleDateString("ru-RU")}</Text>
|
|
</View>
|
|
<Button title="Скачать" secondary onPress={() => void download(document.document_id)} />
|
|
</View>)}
|
|
{downloadError && <ErrorNotice error={downloadError} />}
|
|
</View>
|
|
</ScrollView>;
|
|
}
|
|
|
|
function Row({ label, value }: { label: string; value: string | null | undefined }) {
|
|
return <View><Text style={styles.muted}>{label}</Text><Text style={styles.text}>{value || "Не указано"}</Text></View>;
|
|
}
|