From 33e539e5623414d28dbdebf74712c0247224d0cf Mon Sep 17 00:00:00 2001 From: AliReza Date: Sun, 27 Sep 2026 01:26:22 +0330 Subject: [PATCH] parents screen: tell the child and the parent apart A linked child (demo user Ali) was told "you are linked to Ali" and the screen asked for the parent-only weekly report, which 404s. GET /family/link does not say which side the caller is on, so the role now comes from the weekly report: it answers only for the parent. The child sees a line saying their parent follows their progress and no invite/accept forms. Found on the live site with the demo accounts. deploy.sh now prints the full API URL. Co-Authored-By: Claude Opus 5.5 --- deploy.sh | 2 +- src/screens/FamilyScreen.tsx | 49 ++++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/deploy.sh b/deploy.sh index 5b29959..3cc9235 100755 --- a/deploy.sh +++ b/deploy.sh @@ -45,6 +45,6 @@ step "جابه‌جایی" rm -rf dist.prev [ -d dist ] && mv dist dist.prev mv dist.next dist -API="$(grep -o 'https\?://[a-zA-Z0-9.-]*/api' dist/assets/*.js | head -1 | cut -d: -f2-)" +API="$(grep -oh 'https\?://[a-zA-Z0-9.-]*/api' dist/assets/*.js | head -1)" printf ' منتشر شد. آدرسِ API در build: %s\n' "${API:-(هم‌دامنه /api یا config.js)}" printf ' کشِ آروان را برای index.html و config.js پاک کنید اگر تغییری دیده نشد.\n' diff --git a/src/screens/FamilyScreen.tsx b/src/screens/FamilyScreen.tsx index 77ebadb..4ca31ad 100644 --- a/src/screens/FamilyScreen.tsx +++ b/src/screens/FamilyScreen.tsx @@ -1,9 +1,9 @@ import { useState } from 'react'; import { BookOpen, Flame, Link2, Star, Trophy, UserPlus } from 'lucide-react'; -import { api, ApiError, type FamilyLink } from '@/api'; +import { api, ApiError, type FamilyLink, type FamilyWeeklyReport } from '@/api'; import { useAsync } from '@/lib/useAsync'; import { useToast } from '@/components/Toast'; -import { InlineError, LoadingState, PrimaryButton, Screen, ScreenBody, ScreenHeader } from '@/components/ui'; +import { ErrorState, InlineError, LoadingState, PrimaryButton, Screen, ScreenBody, ScreenHeader } from '@/components/ui'; import { friendlyError } from '@/lib/errors'; import { digitsOnly, formatJalaliDate, toFa } from '@/lib/format'; @@ -13,26 +13,37 @@ import { digitsOnly, formatJalaliDate, toFa } from '@/lib/format'; * گزارشِ هفتگی را می‌بیند. */ export function FamilyScreen() { - const link = useAsync( - () => api.family.link().catch((err) => { + // GET /family/link نمی‌گوید کاربر در این اتصال والد است یا فرزند؛ گزارشِ + // هفتگی فقط برای والد جواب می‌دهد و برای فرزند ۴۰۴ است، پس نقش از همان درمی‌آید. + const state = useAsync(async () => { + const link = await api.family.link().catch((err) => { if (err instanceof ApiError && err.status === 404) return null; throw err; - }), - [], - ); + }); + if (!link || link.status !== 'accepted') return { link, role: null, report: null }; + try { + return { link, role: 'parent' as const, report: await api.family.weeklyReport() }; + } catch (err) { + if (err instanceof ApiError && (err.status === 404 || err.status === 403)) return { link, role: 'child' as const, report: null }; + throw err; + } + }, []); + const data = state.data; return ( - {link.loading ? ( + {state.loading ? ( + ) : state.error ? ( + ) : ( <> - {link.data && } - {link.data?.status === 'accepted' && } - - + {data?.link && } + {data?.report && } + {data?.role !== 'child' && } + {!data?.role && } )} @@ -40,23 +51,23 @@ export function FamilyScreen() { ); } -function LinkStatus({ link }: { link: FamilyLink }) { +function LinkStatus({ link, role }: { link: FamilyLink; role: 'parent' | 'child' | null }) { const accepted = link.status === 'accepted'; return (

- {accepted ? <>به {link.childName || 'فرزندت'} وصلی. : 'دعوت فرستاده شده و منتظرِ تأییدِ فرزندته.'} + {!accepted + ? 'دعوت فرستاده شده و منتظرِ تأییدِ فرزندته.' + : role === 'child' + ? 'حسابت به پدر یا مادرت وصله؛ اون‌ها هر هفته پیشرفتت رو می‌بینن.' + : <>به {link.childName || 'فرزندت'} وصلی.}

); } -function WeeklyReport() { - const report = useAsync(() => api.family.weeklyReport(), []); - if (report.loading) return
; - if (!report.data) return null; - const r = report.data; +function WeeklyReport({ report: r }: { report: FamilyWeeklyReport }) { return (

گزارشِ این هفته (از {formatJalaliDate(r.weekStart)})