Files
kozmos-qr-menu/docs/superpowers/specs/2026-06-03-kozmos-qr-menu-design.md
2026-06-03 01:36:14 +03:00

201 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kozmos Beach & More — QR Menü Sitesi Tasarım Dokümanı
**Tarih:** 2026-06-03
**Proje:** kozmosqr
**Stack:** Next.js 16.2.7 · React 19.2 · Tailwind CSS v4 · TypeScript
---
## Amaç
Masa başında QR okutulunca açılan, uygulama gerektirmeyen, sadece görüntüleme amaçlı dijital menü. TR/EN dil desteği, mobil-first, PWA-ready.
---
## Tasarım Kararları (Brainstorming Özeti)
| Karar | Seçim | Gerekçe |
|---|---|---|
| Ürün kartı stili | Minimal liste (emoji + isim + açıklama + fiyat) | Hızlı taranır, fotoğraf zorunluluğu yok |
| Kategori navigasyon | Sticky alt tab bar | Başparmakla kolay erişim, native his |
| i18n yaklaşımı | URL tabanlı (`/tr`, `/en`) | Next.js native `[lang]` dynamic segment |
| Günün Önerisi / Rakı Gecesi | Sonraki sprint'e bırakıldı | Şimdilik kapsam dışı |
---
## Tasarım Dili
- **Renkler:** krem `#F5F0E8` · bej `#E8DCC8` · turkuaz `#4AAFA8` · yeşil `#5C8A5C` · koyu kahve `#3D2B1F`
- **Font:** Playfair Display (başlıklar, italic vurgu) + Inter (gövde, fiyat, etiketler)
- **His:** Bohem, Ege, hasır doku — Magic UI animasyon kalitesi ile desteklenmiş
- **Animasyon:** Minimal — scroll geçişleri, tab değiştirme fade
---
## Sayfa Yapısı
```
┌─────────────────────┐
│ KOZMOS Beach&More │ sticky header — bg: #3D2B1F
│ TR EN│ dil seçici sağ üst
├─────────────────────┤
│ │
│ [Aktif kategori │ scroll area — bg: #F5F0E8
│ içeriği] │
│ │
│ 🥗 Akdeniz Salatası│ minimal liste satırı
│ Taze sebzeler ₺120 │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ │
│ [WA btn] │ fixed, sağ alt, bg: #25D366
├─────────────────────┤
│ 🥗 🍽️ 🍕 🍹 🍮│ sticky bottom tab bar — bg: #3D2B1F
└─────────────────────┘
```
---
## Dosya Yapısı
```
app/
[lang]/
layout.tsx — font yükleme, html lang attr, meta tags
page.tsx — menü sayfası (Server Component)
manifest.ts — PWA web app manifest
proxy.ts — / → /tr yönlendirmesi (Next.js 16 proxy)
data/
menu.ts — tüm menü verisi (TR+EN, tip tanımlı)
dictionaries/
tr.json — UI string'leri Türkçe
en.json — UI string'leri İngilizce
public/
icons/ — PWA icon'ları (192x192, 512x512)
```
---
## Veri Modeli
```ts
// data/menu.ts
type LocalizedString = { tr: string; en: string }
type MenuItem = {
id: string
emoji: string
name: LocalizedString
description: LocalizedString
price: number // TL
highlight?: boolean // Günün Önerisi — sonraya hazır alan
}
type Category = {
id: string
emoji: string
label: LocalizedString
items: MenuItem[]
}
export const categories: Category[] = [ ... ]
```
**Kategoriler (6):** Başlangıçlar · Ana Yemekler · Pizzalar · Mezeler · İçecekler · Tatlılar
**Her kategoride:** 45 ürün, TR+EN isim ve açıklama
---
## i18n Mimarisi
**Routing:** `app/[lang]/page.tsx``/tr` ve `/en` URL'leri
**proxy.ts:**
- `/``/tr` yönlendirir (varsayılan locale)
- Desteklenmeyen locale → 404
**dictionaries/tr.json + en.json:**
```json
{
"nav": { "starters": "Başlangıçlar", "mains": "Ana Yemekler", ... },
"whatsapp": "Rezervasyon için yazın",
"currency": "₺"
}
```
**getDictionary (server-only):** `app/[lang]/dictionaries.ts`
- `import 'server-only'` ile client bundle'dan korunur
- `hasLocale()` ile geçersiz locale → `notFound()`
**Params:** Next.js 16 gereği `await params` — senkron erişim yok.
---
## Bileşen Mimarisi
Bileşenler varsayılan olarak Server Component'tir. `'use client'` yalnızca aktif tab detection için gereklidir.
```
app/[lang]/page.tsx
└─ <MenuPage lang dict categories /> — Server Component
├─ <Header lang /> — Server Component, dil linkleri
├─ <CategorySection id="starters" ...> — Server Component, her kategori için
│ └─ <MenuItemRow> — Server Component
├─ <WhatsAppButton phone /> — Server Component (statik link)
└─ <BottomTabBar categories /> — CLIENT Component ⚠️
```
**BottomTabBar neden client?**
Sayfa tek scroll alanı, tüm kategoriler alt alta sıralı. Tab'lar `href="#category-id"` anchor linkleri. Aktif tab'ı belirlemek için Intersection Observer kullanılır — bu `useEffect` + `useState` gerektirir.
**Sayfada sadece bu bir bileşen `'use client'` alır.**
---
## PWA
`app/manifest.ts`:
```ts
{ name: 'Kozmos Beach & More', short_name: 'Kozmos',
start_url: '/tr', display: 'standalone',
background_color: '#F5F0E8', theme_color: '#3D2B1F' }
```
`app/[lang]/layout.tsx` meta tags:
- `viewport` + `theme-color`
- `apple-mobile-web-app-capable`
---
## Tailwind v4 Yapılandırması
`app/globals.css` içinde `@theme inline` ile özel renkler:
```css
@import "tailwindcss";
@theme inline {
--color-cream: #F5F0E8;
--color-beige: #E8DCC8;
--color-teal: #4AAFA8;
--color-green: #5C8A5C;
--color-coffee: #3D2B1F;
--font-display: 'Playfair Display', serif;
--font-body: 'Inter', sans-serif;
}
```
---
## WhatsApp Butonu
Fixed, sağ alt köşe. `href="https://wa.me/90XXXXXXXXXX"` — telefon numarası `data/menu.ts`'ten gelir, hardcode edilmez.
---
## Kapsam Dışı (Sonraki Sprint)
- Günün Önerisi özel kartı
- Perşembe Rakı Gecesi banner'ı
- Gerçek ürün fotoğrafları (Next.js Image optimizasyonu)
- Admin paneli / menü düzenleme arayüzü