Разработана первая версия приложений

This commit is contained in:
mi
2026-07-10 18:06:14 +03:00
parent aa8761d1b3
commit 8c7b4074c4
162 changed files with 12178 additions and 16 deletions
@@ -0,0 +1,46 @@
import React, { useEffect, useState } from "react";
import { ScrollView, Text, View } from "react-native";
import { getDiagnostics, sessionMemory } from "../src/api";
import { getTokenInfo } from "../src/auth";
import { useApp } from "../src/app-context";
import { isProduction } from "../src/config";
import { getRealtimeDiagnostics } from "../src/realtime";
import { Header, styles } from "../src/ui";
export default function DiagnosticsScreen() {
const app = useApp();
const [, render] = useState(0);
useEffect(() => {
const timer = setInterval(() => render((value) => value + 1), 1000);
return () => clearInterval(timer);
}, []);
if (isProduction) return <ScrollView contentContainerStyle={styles.page}>
<Header status={app.authStatus} realtime={app.realtimeState} />
<Text accessibilityRole="header" style={styles.title}>Диагностика</Text>
<Text style={styles.error}>Экран отключён в production.</Text>
</ScrollView>;
const token = getTokenInfo();
return <ScrollView contentContainerStyle={styles.page}>
<Header status={app.authStatus} realtime={app.realtimeState} onLogout={app.authStatus === "authenticated" ? () => void app.signOut() : undefined} />
<Text accessibilityRole="header" style={styles.title}>Безопасная диагностика</Text>
<View style={styles.card}>
<Text style={styles.text}>Режим: {app.authStatus}</Text>
<Text style={styles.text}>Realtime: {app.realtimeState}</Text>
<Text style={styles.text}>UX-сессия: {sessionMemory.id ?? "нет"}</Text>
<Text style={styles.text}>Access token истекает: {token ? new Date(token.expiresAt).toLocaleString("ru-RU") : "нет"}</Text>
{getRealtimeDiagnostics().map((item) =>
<Text key={item.dialog} style={styles.text}>Cursor {item.dialog}: {item.cursor}</Text>,
)}
<Text style={styles.muted}>Токены, OTP, персональные данные, сообщения и presigned URL здесь никогда не отображаются.</Text>
</View>
<View style={styles.card}>
<Text accessibilityRole="header" style={styles.heading}>Последние запросы</Text>
{!getDiagnostics().length && <Text style={styles.muted}>Запросов ещё нет.</Text>}
{getDiagnostics().map((item) => <View key={`${item.at}-${item.requestId}`} style={styles.row}>
<Text style={styles.badge}>{item.status}</Text>
<Text style={styles.text}>{item.method} {item.path}</Text>
<Text style={styles.muted}>request_id: {item.requestId}</Text>
</View>)}
</View>
</ScrollView>;
}