Add QR menu design spec and update gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
0beefdee7f
commit
f879d65cfc
@@ -39,3 +39,6 @@ yarn-error.log*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
# brainstorming sessions
|
||||||
|
.superpowers/
|
||||||
|
|||||||
@@ -0,0 +1,200 @@
|
|||||||
|
# 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:** 4–5 ü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ü
|
||||||
Reference in New Issue
Block a user