forked from Tadrisino/MathApp_frontend
Remove every guest remnant: profile badge, register flow, delete-by-word
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState, type ReactNode } from 'react';
|
||||
import {
|
||||
BarChart3, Bell, CalendarDays, Check, ChevronLeft, Coins, Flame, Gift, GraduationCap, LifeBuoy, LogOut,
|
||||
FileText, Pencil, Repeat, Smartphone, Sparkles, Star, Trash2, Trophy, Volume2, VolumeX,
|
||||
FileText, Pencil, Repeat, Sparkles, Star, Trash2, Trophy, Volume2, VolumeX,
|
||||
} from 'lucide-react';
|
||||
import { api } from '@/api';
|
||||
import { useAppData } from '@/state/AppData';
|
||||
@@ -48,11 +48,7 @@ export function ProfileScreen({ onSignedOut }: { onSignedOut: () => void }) {
|
||||
<div className="mt-1 flex flex-wrap items-center gap-1.5 text-xs text-white/80">
|
||||
{gradeTitle && <span className="rounded-full bg-white/15 px-2.5 py-0.5">{gradeTitle}</span>}
|
||||
{age && <span className="rounded-full bg-white/15 px-2.5 py-0.5">{toFa(age)} ساله</span>}
|
||||
{profile.isGuest ? (
|
||||
<span className="rounded-full bg-[#FFD23F] px-2.5 py-0.5 font-bold text-ink">مهمان</span>
|
||||
) : (
|
||||
profile.phone && <span dir="ltr" className="rounded-full bg-white/15 px-2.5 py-0.5">{toFa(profile.phone)}</span>
|
||||
)}
|
||||
{profile.phone && <span dir="ltr" className="rounded-full bg-white/15 px-2.5 py-0.5">{toFa(profile.phone)}</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -72,21 +68,6 @@ export function ProfileScreen({ onSignedOut }: { onSignedOut: () => void }) {
|
||||
</header>
|
||||
|
||||
<div className="flex flex-col gap-4 px-4 py-5">
|
||||
{profile.isGuest && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={go({ name: 'register' })}
|
||||
className="flex items-center gap-3 rounded-3xl bg-[#FFF8E1] p-4 text-right ring-2 ring-[#FFD23F]"
|
||||
>
|
||||
<Smartphone size={22} className="flex-shrink-0 text-gold" />
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-black text-ink">شمارهت رو ثبت کن</div>
|
||||
<div className="mt-0.5 text-xs leading-6 text-body">تا اگه گوشیت عوض شد، امتیازها و پیشرفتت گم نشه.</div>
|
||||
</div>
|
||||
<ChevronLeft size={18} className="text-muted" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
<Menu>
|
||||
<Row icon={GraduationCap} label="پایهی تحصیلی" value={gradeTitle} onClick={() => setEditing('grade')} />
|
||||
<Row
|
||||
@@ -106,7 +87,7 @@ export function ProfileScreen({ onSignedOut }: { onSignedOut: () => void }) {
|
||||
</Menu>
|
||||
|
||||
<Menu>
|
||||
{!profile.isGuest && <Row icon={Gift} label="معرفی به دوستان" onClick={go({ name: 'invite' })} />}
|
||||
<Row icon={Gift} label="معرفی به دوستان" onClick={go({ name: 'invite' })} />
|
||||
<Row icon={FileText} label="پرداختها و فاکتورها" onClick={go({ name: 'invoices' })} />
|
||||
<Row icon={LifeBuoy} label="پشتیبانی و گزارشِ مشکل" onClick={go({ name: 'support' })} />
|
||||
<Row
|
||||
@@ -273,7 +254,6 @@ function BirthDateSheet({ open, onClose }: { open: boolean; onClose: () => void
|
||||
* دیگری میشد، و چند refresh tokenِ ماندگار در مرورگر خطرِ دزدیده شدن را چند برابر میکرد.
|
||||
*/
|
||||
function LogoutSheet({ open, switching = false, onClose, onSignedOut }: { open: boolean; switching?: boolean; onClose: () => void; onSignedOut: () => void }) {
|
||||
const { profile } = useAppData();
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
||||
async function logout() {
|
||||
@@ -291,9 +271,7 @@ function LogoutSheet({ open, switching = false, onClose, onSignedOut }: { open:
|
||||
<Sheet open={open} onClose={onClose} title={switching ? 'ورود با حسابِ دیگر' : 'از حسابت خارج بشی؟'}>
|
||||
<p className="mb-5 text-sm leading-7 text-muted">
|
||||
{switching && 'اول از این حساب خارج میشی، بعد با شمارهی دیگه وارد شو. '}
|
||||
{profile.isGuest
|
||||
? 'تو مهمانی: با همین گوشی و مرورگر، «فعلاً مهمان باشم» دوباره تو رو به همین پیشرفت برمیگردونه، ولی از گوشیِ دیگه نه. برای امنتر شدن، اول شمارهت رو ثبت کن.'
|
||||
: 'هر وقت خواستی با همین شماره دوباره وارد شو؛ پیشرفتت سرِ جاشه.'}
|
||||
هر وقت خواستی با همین شماره دوباره وارد شو؛ پیشرفتت سرِ جاشه.
|
||||
</p>
|
||||
<div className="flex flex-col gap-2.5">
|
||||
<SecondaryButton onClick={onClose}>نه، میمونم</SecondaryButton>
|
||||
@@ -307,7 +285,7 @@ function LogoutSheet({ open, switching = false, onClose, onSignedOut }: { open:
|
||||
|
||||
/**
|
||||
* حذفِ همیشگیِ حساب (POST /user/delete). شمارهدار با کدِ تازهی پیامکی تأیید میکند تا گوشیِ
|
||||
* بازمانده یا توکنِ دزدیده نتواند حساب را پاک کند؛ مهمان با تایپِ «حذف».
|
||||
* بازمانده یا توکنِ دزدیده نتواند حساب را پاک کند.
|
||||
*/
|
||||
function DeleteAccountSheet({ open, onClose, onSignedOut }: { open: boolean; onClose: () => void; onSignedOut: () => void }) {
|
||||
const { profile } = useAppData();
|
||||
@@ -315,7 +293,6 @@ function DeleteAccountSheet({ open, onClose, onSignedOut }: { open: boolean; onC
|
||||
const [value, setValue] = useState('');
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const needsCode = Boolean(profile.phone);
|
||||
|
||||
async function sendCode() {
|
||||
if (!profile.phone) return;
|
||||
@@ -335,7 +312,7 @@ function DeleteAccountSheet({ open, onClose, onSignedOut }: { open: boolean; onC
|
||||
setBusy(true);
|
||||
setError('');
|
||||
try {
|
||||
await api.auth.deleteAccount(needsCode ? { otp: digitsOnly(value, 6) } : { confirm: value.trim() });
|
||||
await api.auth.deleteAccount({ otp: digitsOnly(value, 6) });
|
||||
askStore.clear();
|
||||
onSignedOut();
|
||||
} catch (err) {
|
||||
@@ -351,37 +328,28 @@ function DeleteAccountSheet({ open, onClose, onSignedOut }: { open: boolean; onC
|
||||
امتیاز، زنجیره، پیشرفتِ جزیرهها، گفتگوها با دستیار، سوالهای خریدهشده و قلبِ نامحدودت پاک میشن و برنمیگردن.
|
||||
سوابقِ پرداخت فقط برای حسابداری میمونه.
|
||||
</p>
|
||||
{needsCode ? (
|
||||
sent ? (
|
||||
<input
|
||||
value={value}
|
||||
onChange={(e) => setValue(digitsOnly(e.target.value, 6))}
|
||||
placeholder="کدِ پیامکشده"
|
||||
inputMode="numeric"
|
||||
dir="ltr"
|
||||
className="mb-3 w-full rounded-2xl border-2 border-line px-4 py-3 text-center font-bold tracking-widest outline-none focus:border-red-400"
|
||||
/>
|
||||
) : (
|
||||
<p className="mb-3 text-xs leading-6 text-muted">برای اطمینان، یک کد به شمارهی خودت پیامک میشه.</p>
|
||||
)
|
||||
) : (
|
||||
{sent ? (
|
||||
<input
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value.slice(0, 10))}
|
||||
placeholder="برای تأیید بنویس: حذف"
|
||||
className="mb-3 w-full rounded-2xl border-2 border-line px-4 py-3 text-center font-bold outline-none focus:border-red-400"
|
||||
onChange={(e) => setValue(digitsOnly(e.target.value, 6))}
|
||||
placeholder="کدِ پیامکشده"
|
||||
inputMode="numeric"
|
||||
dir="ltr"
|
||||
className="mb-3 w-full rounded-2xl border-2 border-line px-4 py-3 text-center font-bold tracking-widest outline-none focus:border-red-400"
|
||||
/>
|
||||
) : (
|
||||
<p className="mb-3 text-xs leading-6 text-muted">برای اطمینان، یک کد به شمارهی خودت پیامک میشه.</p>
|
||||
)}
|
||||
{error && <div className="mb-3"><InlineError>{error}</InlineError></div>}
|
||||
<div className="flex flex-col gap-2.5">
|
||||
<SecondaryButton onClick={onClose}>نه، پشیمون شدم</SecondaryButton>
|
||||
{needsCode && !sent ? (
|
||||
{!sent ? (
|
||||
<PrimaryButton color="#ef4444" loading={busy} onClick={() => void sendCode()}>فرستادنِ کد</PrimaryButton>
|
||||
) : (
|
||||
<PrimaryButton
|
||||
color="#ef4444"
|
||||
loading={busy}
|
||||
disabled={needsCode ? value.length < 6 : value.trim() !== 'حذف'}
|
||||
disabled={value.length < 6}
|
||||
onClick={() => void remove()}
|
||||
>
|
||||
حذفِ همیشگی
|
||||
|
||||
Reference in New Issue
Block a user