feat(arayüz): sayfa yönlendirme, korumalı sayfalar ve uygulama iskeleti
- react-router: Türkçe adresler (/defter, /plan, /birikim, ...), 404 sayfası - Korumalı sayfalar: oturum yoksa /giris?donus=..., girişten sonra geri dönüş - Açık yönlendirme koruması (safeReturnPath, 10 test) - İskelet: mobilde 5 öğeli alt menü, masaüstünde sol kenar çubuğu - Diğer sayfası (değerlendirme, raporlar, ayarlar, tema, çıkış) - Arayüz metinleri lib/strings.ts'de toplanmaya başlandı - Tasarım önizlemesi /dev/tasarim (yalnızca geliştirmede) - Düzeltme: çıkışta önbellek temizliği ekranı güncellemiyordu Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { Navigate, Outlet, useLocation, useSearchParams } from 'react-router'
|
||||
import { Logo } from '@/components/logo'
|
||||
import { useMe } from '@/lib/auth'
|
||||
import { safeReturnPath } from '@/lib/return-path'
|
||||
import { t } from '@/lib/strings'
|
||||
import { paths } from './nav-items'
|
||||
|
||||
/** Oturum kontrol edilirken gösterilen tam ekran açılış. */
|
||||
export function Splash() {
|
||||
return (
|
||||
<div className="grid min-h-dvh place-items-center" role="status" aria-label={t.common.loading}>
|
||||
<Logo size={56} className="animate-pulse" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/** Oturum gerektiren sayfalar. Oturum yoksa → /giris?donus=<şimdiki adres> */
|
||||
export function RequireAuth() {
|
||||
const me = useMe()
|
||||
const location = useLocation()
|
||||
|
||||
if (me.isPending) return <Splash />
|
||||
if (!me.data) {
|
||||
const back = location.pathname + location.search
|
||||
const to = back === '/' ? paths.login : `${paths.login}?donus=${encodeURIComponent(back)}`
|
||||
return <Navigate to={to} replace />
|
||||
}
|
||||
return <Outlet />
|
||||
}
|
||||
|
||||
/**
|
||||
* Yalnızca oturumsuzken: giriş/kayıt.
|
||||
* Oturum açılınca (giriş/kayıt başarılı olduğunda da) `?donus=` adresine, yoksa panele gönderir.
|
||||
* Yönlendirme yalnızca burada yapılır — formlar ayrıca `navigate` çağırmaz (yarış durumu olmasın).
|
||||
*/
|
||||
export function RequireGuest() {
|
||||
const me = useMe()
|
||||
const [params] = useSearchParams()
|
||||
if (me.isPending) return <Splash />
|
||||
if (me.data) return <Navigate to={safeReturnPath(params.get('donus'), paths.dashboard)} replace />
|
||||
return <Outlet />
|
||||
}
|
||||
Reference in New Issue
Block a user