/** * بررسیِ اتصال به بک‌اند — ابزارِ توسعه، نه بخشی از محصول. * * برای امتحان کردن، یک خط در App.tsx (یا هر جای دیگر) کافی‌ست: * * import { ConnectionCheck } from '@/api/ConnectionCheck'; * * * هیچ فایلِ دیگری را عوض نمی‌کند و اگر بک‌اند بالا نباشد هم اپ را نمی‌خواباند. */ import { useEffect, useState } from 'react'; import type { CSSProperties } from 'react'; import { api, ApiError } from '@/api'; import type { Grade } from '@/api'; type State = | { kind: 'loading' } | { kind: 'ok'; grades: Grade[] } | { kind: 'error'; message: string; hint: string }; function hintFor(error: unknown): string { if (!(error instanceof ApiError)) return 'خطای پیش‌بینی‌نشده — کنسول را ببینید.'; if (error.isNetwork) { return 'سرور جواب نداد. VITE_API_BASE_URL درست است؟ بک‌اند بالاست؟'; } if (error.status === 502) { return 'nginx بالاست ولی جنگو نه — سرویسِ بک‌اند روی سرور اجرا نشده.'; } if (error.status === 0) return 'ارتباط برقرار نشد.'; if (error.isRateLimited) return 'سقفِ نرخ خورد؛ کلاینت خودش دوباره تلاش می‌کند.'; if (error.isUnauthorized) return 'نیاز به ورود دارد (این اندپوینت نباید داشته باشد).'; return `سرور ${error.status} داد.`; } export function ConnectionCheck() { const [state, setState] = useState({ kind: 'loading' }); useEffect(() => { const controller = new AbortController(); api .grades({ signal: controller.signal }) .then((grades) => setState({ kind: 'ok', grades })) .catch((error: unknown) => { if (controller.signal.aborted) return; setState({ kind: 'error', message: error instanceof Error ? error.message : String(error), hint: hintFor(error), }); }); return () => controller.abort(); }, []); const box: CSSProperties = { position: 'fixed', bottom: 12, right: 12, zIndex: 9999, maxWidth: 320, padding: '10px 12px', borderRadius: 10, font: '12px/1.6 system-ui, sans-serif', direction: 'rtl', background: '#fff', border: '1px solid #e5e7eb', boxShadow: '0 4px 16px rgba(0,0,0,.08)', }; if (state.kind === 'loading') { return
در حالِ بررسیِ اتصال به بک‌اند…
; } if (state.kind === 'error') { return (
اتصال برقرار نشد
{state.message}
{state.hint}
{api.http.baseUrl}
); } return (
اتصال برقرار است
{state.grades.length} پایه از سرور آمد {state.grades.length > 0 && `: ${state.grades.map((g) => g.title).join('، ')}`}
{api.http.baseUrl}
); }