Rotalar ve Kabuk
Rota tablosu
| URL | Ekran | Dosya | Bileşen türü |
|---|---|---|---|
/ | — | app/page.tsx | redirect("/panel") |
/login | Oturum aç | app/login/page.tsx | Client |
/panel | Panel | app/(panel)/panel/page.tsx | Server |
/menu | Menü Yönetimi | app/(panel)/menu/page.tsx | Client |
/stock | Stok | app/(panel)/stock/page.tsx | Client |
/devices | Cihazlar | app/(panel)/devices/page.tsx | Client |
/apps | Uygulama Yönetimi | app/(panel)/apps/page.tsx | Server |
/settings | Restoran Ayarları | app/(panel)/settings/page.tsx | Client |
/staff | Personel & Roller | app/(panel)/staff/page.tsx | Client |
/sync | Senkronizasyon | app/(panel)/sync/page.tsx | Client |
/errors | Hata Kayıtları | app/(panel)/errors/page.tsx | Client |
/audit | Denetim Kaydı | app/(panel)/audit/page.tsx | Client |
/fiscal | e-Belge · GİB | app/(panel)/fiscal/page.tsx | Client |
/billing | Abonelik | app/(panel)/billing/page.tsx | Client |
Tüm rotalar build sırasında statik olarak prerender edilir.
(panel) rota grubu
Parantezli klasör URL’ye segment eklemez. Grup, kabuğu (kenar çubuğu, başlık ve
kayan içerik alanı) on iki kardeş rotaya tek bir layout.tsx ile bağlar. Böylece
/menu, /stock, /settings gibi rotalar URL’de panel/ öneki olmadan en üst
seviyede kalır. Bu, tasarımdaki düz kenar çubuğuyla örtüşür.
/login bilerek grubun dışında tutulur ve kabuk olmadan render edilir.
/ doğrudan dashboard değil, /panel’e yönlendirmedir. Dashboard
(panel)/page.tsx olarak konsaydı / rotası olur ve app/page.tsx ile
çakışırdı. Dashboard’a açık bir /panel segmenti vermek, her navigasyon hedefini
gerçek ve paylaşılabilir bir URL yapar. Kenar çubuğundaki aktif satır tespiti de
böylece basit bir pathname === href karşılaştırmasına iner.
Kabuk
app/(panel)/layout.tsx bir Server Component’tir. Yerleşim, 248px kenar
çubuğu ile minmax(0,1fr) içerik sütunundan oluşan bir ızgaradır. İçerik sütunu
64px başlık ve kayan <main> alanını barındırır. Kabuk viewport yüksekliğine
kilitlidir: yalnızca <main> kayar, kenar çubuğu ve başlık sabit kalır.
İçindeki üç parça client adasıdır:
| Bileşen | Neden client |
|---|---|
_components/sidebar.tsx | Aktif satırı usePathname ile belirler |
_components/header.tsx | Ekran başlığını usePathname ile belirler, şube seçicisini barındırır |
_components/tenant-context.tsx | Seçili şubeyi tutar. Başlık değiştirir, kenar çubuğu gösterir; iki tüketicisi olduğu için ikisinden birinde yaşayamaz |
TenantProvider yalnızca bu iki adayı ve {children}’ı sarar, <html>’i sarmaz.
Ekran kaydı: _screens.ts
Navigasyon ve başlık metinleri tek bir kayıttan gelir. Her Screen şunları taşır:
href: rotalabel: kenar çubuğunda görünen ad (ör. “Menü”)titlevekicker: başlıkta görünen ad ve alt satır (ör. “Menü Yönetimi”)badge(isteğe bağlı): kenar çubuğu satırının sağındaki sayaçtone: "tag": dikkat gerektiren durumlar için accent renkli etikettone: "muted": bilgi amaçlı sayılar için gri metin
label ile title bilerek farklıdır; tasarımdaki SCREENS haritası da böyledir.
Başlık screenFor(pathname) ile bulunur, bu yüzden hiçbir sayfa kendi başlığını
ayrıca bağlamaz. Rotayla eşleşmeyen bir yol Panel başlığına düşer.
Rozet değerleri app/_data/panel.ts içindeki BADGES nesnesinden okunur. Bkz.
Veri ve entegrasyon.
Şube seçici
Başlıktaki seçici TENANTS fixture’ından üç şubeyi listeler. Seçim yalnızca
client state’tir: sayfa yenilenince ilk şubeye döner ve hiçbir ekranın verisini
filtrelemez. Gerçek çok kiracılı (multi-tenant) çözüm, SCRUM-37 altındaki
session/JWT tenant claim’ine (SCRUM-141) ve tenant bazlı RLS’e (SCRUM-140)
bağlıdır.
Yeni ekran eklemek
app/(panel)/<segment>/page.tsxoluşturun._screens.tsiçindekiSCREENSdizisine bir kayıt ekleyin. Kenar çubuğundaki sıra dizideki sıradır.- Rozet gerekiyorsa
BadgeKeytipine anahtarı ekleyin ve değeriniapp/_data/panel.tsiçindekiBADGES’te veriden türetin. - Varsayılan olarak Server Component yazın.
"use client"’ı yalnızca state, effect veya tarayıcı API’si gerçekten gerektiğinde ekleyin.
Server ve Client sınırı
Ekran bazında karar verilir, ağaç bazında değil:
- Saf sunum yapan ekranlar (
panel,apps) Server Component’tir. En ağır ekran olan dashboard bu sayede tarayıcıya bileşen JavaScript’i göndermez. - Tasarımda filtre, form veya diyalog olan ekranlar Client Component’tir.
Dashboard’daki saat bazlı ciro grafiği bir grafik kütüphanesi değil, düz flex
div’lerdir. Grafikte on üç çubuk var; eksen, tick veya tooltip yok ve taban
çizgisini tasarımın kendi 2px çizgisi çiziyor. Kütüphane eklemek hem bağımlılık
getirir hem de CSS’in zaten yaptığı iş için client sınırı açardı. Çubuk
yükseklikleri en yüksek değere göre yüzde olarak hesaplanır ve tasarımdaki sabit
yüzdeleri birebir üretir.
Kimlik doğrulama
Uygulanmadı. (panel) grubu auth’un yerleşeceği yer (SCRUM-34), ancak
middleware, session kontrolü ya da anonim ziyaretçi için yönlendirme yok. Her
rota herkese açıktır.
- Giriş ekranı e-posta alanının boş olmadığını kontrol edip
/panel’e gider. Şifre kontrol edilmez. “Sihirli bağlantı gönder” düğmesi de aynı işlevi çağırır. - Kenar çubuğundaki “Çıkış Yap” düğmesi yalnızca
/login’e bağlantıdır. - Kenar çubuğu altındaki kullanıcı adı ve rolü
CURRENT_USERfixture’ından gelir.
Gerçek Supabase Auth çağrısı geldiğinde giriş ekranındaki submit işlevinin
yerini alacak. O zamana kadar panel kimliksiz kabul edilmelidir.