From 0836fc85392974b8692284869c7b2ff602417e75 Mon Sep 17 00:00:00 2001 From: AyrisAI Date: Thu, 20 Aug 2026 15:07:13 +0300 Subject: [PATCH] feat: redesign web menu layout, add header cover banner & dynamic header layout, refine mobile inputs and theme selector --- .gitignore | 2 + apps/mobile/src/app/(auth)/login.tsx | 52 ++-- apps/mobile/src/app/(auth)/register.tsx | 52 ++-- .../src/app/(onboarding)/restaurant.tsx | 30 +-- apps/mobile/src/app/account/index.tsx | 103 ++------ .../src/components/menu/AddCategoryModal.tsx | 6 +- .../src/components/menu/AddItemModal.tsx | 18 +- .../src/components/menu/ItemDetailSheet.tsx | 18 +- .../components/menu/ThemeSelectorSheet.tsx | 110 ++------ apps/web/src/app/demo/page.tsx | 2 +- apps/web/src/app/menu/[slug]/page.tsx | 5 +- apps/web/src/components/PublicMenuClient.tsx | 211 ++++++++------- .../src/components/TemplateGalleryClient.tsx | 242 +++++------------- apps/web/src/lib/demo-data.ts | 1 + apps/web/src/lib/theme.ts | 10 + packages/shared/src/theme.ts | 1 + .../20260819000000_initial_schema.sql | 1 + 17 files changed, 311 insertions(+), 553 deletions(-) diff --git a/.gitignore b/.gitignore index 2034e74..b0cfbfd 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ build/ supabase/.branches/ supabase/.temp/ coverage/ +*.ipa +*.apk diff --git a/apps/mobile/src/app/(auth)/login.tsx b/apps/mobile/src/app/(auth)/login.tsx index 619e151..f05ed1d 100644 --- a/apps/mobile/src/app/(auth)/login.tsx +++ b/apps/mobile/src/app/(auth)/login.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { Link, router } from "expo-router"; -import { ActivityIndicator, Pressable, Text, TextInput, View } from "react-native"; +import { ActivityIndicator, Image, Pressable, Text, TextInput, View } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import { supabase } from "@/lib/supabase"; @@ -30,28 +30,24 @@ export default function LoginScreen() { {/* Brand Icon Header */} - - - - - Menulio'ya Giriş Yap + resizeMode="contain" + /> + + MenuL.io - + AI destekli dijital restoran menü yöneticisi @@ -81,22 +77,22 @@ export default function LoginScreen() { flexDirection: "row", alignItems: "center", backgroundColor: "#FFFFFF", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, marginBottom: 12, }} > - + @@ -106,27 +102,27 @@ export default function LoginScreen() { flexDirection: "row", alignItems: "center", backgroundColor: "#FFFFFF", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, marginBottom: 20, }} > - + setShowPassword(!showPassword)} style={{ padding: 4 }}> diff --git a/apps/mobile/src/app/(auth)/register.tsx b/apps/mobile/src/app/(auth)/register.tsx index 2420de0..164ad77 100644 --- a/apps/mobile/src/app/(auth)/register.tsx +++ b/apps/mobile/src/app/(auth)/register.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { Link, router } from "expo-router"; -import { ActivityIndicator, Pressable, Text, TextInput, View } from "react-native"; +import { ActivityIndicator, Image, Pressable, Text, TextInput, View } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import { supabase } from "@/lib/supabase"; @@ -35,28 +35,24 @@ export default function RegisterScreen() { {/* Brand Icon Header */} - - - - - Hesap Oluştur + resizeMode="contain" + /> + + MenuL.io - + Dakikalar içinde restoranınızı ve QR menünüzü hazırlayın @@ -86,22 +82,22 @@ export default function RegisterScreen() { flexDirection: "row", alignItems: "center", backgroundColor: "#FFFFFF", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, marginBottom: 12, }} > - + @@ -111,27 +107,27 @@ export default function RegisterScreen() { flexDirection: "row", alignItems: "center", backgroundColor: "#FFFFFF", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, marginBottom: 20, }} > - + setShowPassword(!showPassword)} style={{ padding: 4 }}> diff --git a/apps/mobile/src/app/(onboarding)/restaurant.tsx b/apps/mobile/src/app/(onboarding)/restaurant.tsx index 0b605e1..e0833d3 100644 --- a/apps/mobile/src/app/(onboarding)/restaurant.tsx +++ b/apps/mobile/src/app/(onboarding)/restaurant.tsx @@ -96,20 +96,20 @@ export default function OnboardingRestaurantStep() { flexDirection: "row", alignItems: "center", backgroundColor: "#FFFFFF", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, marginBottom: 12, }} > - + @@ -119,21 +119,21 @@ export default function OnboardingRestaurantStep() { flexDirection: "row", alignItems: "center", backgroundColor: "#FFFFFF", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, marginBottom: 12, }} > - + @@ -143,20 +143,20 @@ export default function OnboardingRestaurantStep() { flexDirection: "row", alignItems: "center", backgroundColor: "#FFFFFF", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, marginBottom: 24, }} > - + diff --git a/apps/mobile/src/app/account/index.tsx b/apps/mobile/src/app/account/index.tsx index 42913cf..a673c73 100644 --- a/apps/mobile/src/app/account/index.tsx +++ b/apps/mobile/src/app/account/index.tsx @@ -560,8 +560,8 @@ export default function AccountScreen() { flexDirection: "row", alignItems: "center", backgroundColor: "#FAF8F5", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 12, }} @@ -570,7 +570,7 @@ export default function AccountScreen() { value={newDomainInput} onChangeText={setNewDomainInput} placeholder="Örn: menu.kebapciahmet.com" - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" autoCapitalize="none" autoCorrect={false} style={{ @@ -728,15 +728,17 @@ export default function AccountScreen() { value={name} onChangeText={setName} placeholder="Restoran Adı" + placeholderTextColor="#57534E" style={{ backgroundColor: "#FAF8F5", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 10, paddingHorizontal: 14, paddingVertical: 12, fontSize: 14, color: "#1C1917", + fontWeight: "500", }} /> @@ -750,16 +752,18 @@ export default function AccountScreen() { value={phone} onChangeText={setPhone} placeholder="05xx xxx xx xx" + placeholderTextColor="#57534E" keyboardType="phone-pad" style={{ backgroundColor: "#FAF8F5", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 10, paddingHorizontal: 14, paddingVertical: 12, fontSize: 14, color: "#1C1917", + fontWeight: "500", }} /> @@ -773,17 +777,19 @@ export default function AccountScreen() { value={address} onChangeText={setAddress} placeholder="Restoran adresi" + placeholderTextColor="#57534E" multiline numberOfLines={2} style={{ backgroundColor: "#FAF8F5", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 10, paddingHorizontal: 14, paddingVertical: 12, fontSize: 14, color: "#1C1917", + fontWeight: "500", minHeight: 64, }} /> @@ -806,85 +812,6 @@ export default function AccountScreen() { - - {/* Theme Selector */} - - - - - Menü Şablonu (Tema) - - - - Restoranınızın konseptine uygun tasarımı seçin. Seçtiğiniz tema QR menünüzde anında aktif olur. - - - - {THEME_OPTIONS.map((theme) => { - const isSelected = selectedTheme === theme.key; - return ( - handleSelectTheme(theme.key)} - style={({ pressed }) => ({ - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - padding: 14, - borderRadius: 14, - backgroundColor: isSelected ? "#FAF8F5" : "#FAFAFA", - borderWidth: 2, - borderColor: isSelected ? theme.color : "#E7E5E4", - opacity: pressed ? 0.9 : 1, - })} - > - - - - - {theme.name} - - - {theme.desc} - - - - - - {isSelected ? : null} - - - ); - })} - - ); diff --git a/apps/mobile/src/components/menu/AddCategoryModal.tsx b/apps/mobile/src/components/menu/AddCategoryModal.tsx index 4e1ea05..a2aa03c 100644 --- a/apps/mobile/src/components/menu/AddCategoryModal.tsx +++ b/apps/mobile/src/components/menu/AddCategoryModal.tsx @@ -101,12 +101,12 @@ export function AddCategoryModal({ value={name} onChangeText={setName} placeholder="Örn: Tatlılar, Başlangıçlar, Sıcak İçecekler" - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" autoFocus style={{ backgroundColor: "#FAFAFA", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, padding: 14, fontSize: 15, diff --git a/apps/mobile/src/components/menu/AddItemModal.tsx b/apps/mobile/src/components/menu/AddItemModal.tsx index a32115c..dea7dcf 100644 --- a/apps/mobile/src/components/menu/AddItemModal.tsx +++ b/apps/mobile/src/components/menu/AddItemModal.tsx @@ -218,11 +218,11 @@ export function AddItemModal({ value={name} onChangeText={setName} placeholder="Örn: Mercimek Çorbası" - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" style={{ backgroundColor: "#FAFAFA", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, padding: 14, fontSize: 15, @@ -241,8 +241,8 @@ export function AddItemModal({ flexDirection: "row", alignItems: "center", backgroundColor: "#FAFAFA", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, }} @@ -251,7 +251,7 @@ export function AddItemModal({ value={price} onChangeText={setPrice} placeholder="120" - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" keyboardType="decimal-pad" style={{ flex: 1, @@ -273,13 +273,13 @@ export function AddItemModal({ value={description} onChangeText={setDescription} placeholder="Kısa içerik veya porsiyon açıklaması..." - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" multiline numberOfLines={3} style={{ backgroundColor: "#FAFAFA", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, padding: 14, fontSize: 14, diff --git a/apps/mobile/src/components/menu/ItemDetailSheet.tsx b/apps/mobile/src/components/menu/ItemDetailSheet.tsx index 4bb9910..2a2e6c8 100644 --- a/apps/mobile/src/components/menu/ItemDetailSheet.tsx +++ b/apps/mobile/src/components/menu/ItemDetailSheet.tsx @@ -311,11 +311,11 @@ export function ItemDetailSheet({ value={name} onChangeText={setName} placeholder="Örn: Izgara Levrek" - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" style={{ backgroundColor: "#FAFAFA", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, padding: 14, fontSize: 15, @@ -335,8 +335,8 @@ export function ItemDetailSheet({ flexDirection: "row", alignItems: "center", backgroundColor: "#FAFAFA", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, paddingHorizontal: 14, }} @@ -345,7 +345,7 @@ export function ItemDetailSheet({ value={price} onChangeText={setPrice} placeholder="0.00" - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" keyboardType="decimal-pad" style={{ flex: 1, @@ -368,13 +368,13 @@ export function ItemDetailSheet({ value={description} onChangeText={setDescription} placeholder="İçindekiler, porsiyon bilgisi, pişirme tarzı..." - placeholderTextColor="#A8A29E" + placeholderTextColor="#57534E" multiline numberOfLines={3} style={{ backgroundColor: "#FAFAFA", - borderWidth: 1, - borderColor: "#E7E5E4", + borderWidth: 1.5, + borderColor: "#D6D3D1", borderRadius: 12, padding: 14, fontSize: 14, diff --git a/apps/mobile/src/components/menu/ThemeSelectorSheet.tsx b/apps/mobile/src/components/menu/ThemeSelectorSheet.tsx index 84f07f2..082714c 100644 --- a/apps/mobile/src/components/menu/ThemeSelectorSheet.tsx +++ b/apps/mobile/src/components/menu/ThemeSelectorSheet.tsx @@ -285,7 +285,7 @@ export function ThemeSelectorSheet({ Menü Şablonları & Canlı Önizleme - 5 lüks şablonu inceleyin, demolarını paylaşın veya menünüze uygulayın + Şablonları inceleyin, demolarını görün veya menünüze uygulayın @@ -323,61 +323,21 @@ export function ThemeSelectorSheet({ elevation: isSelected ? 3 : 1, }} > - {/* Top Row: Color Pip, Name, Category Badge & Active Check */} - - - - - - {theme.name} - - - - - - - {theme.category} - - - - - {/* Description */} - - {theme.desc} - - - {/* Meta details */} - - - - Renk: {theme.accent} • {theme.suitableFor} + {/* Top Row: Theme Name */} + + + {theme.name} - {/* Action Bar: Canlı Demo, Paylaş, Uygula */} - - {/* Canlı Demo Aç */} + {/* Description */} + + {theme.desc} + + + {/* Action Bar: Canlı Demo & Şablon Seç */} + + {/* Canlı Demo Önizle */} handleOpenDemo(theme.key)} style={({ pressed }) => ({ @@ -385,43 +345,25 @@ export function ThemeSelectorSheet({ flexDirection: "row", alignItems: "center", justifyContent: "center", - gap: 4, + gap: 6, backgroundColor: "#F5F5F4", - paddingVertical: 10, - borderRadius: 10, + paddingVertical: 12, + borderRadius: 12, opacity: pressed ? 0.8 : 1, })} > - - - Demo Menü + + + Demo Önizle - {/* Demo Linkini Gönder / Paylaş */} - handleShareDemo(theme)} - style={({ pressed }) => ({ - width: 40, - alignItems: "center", - justifyContent: "center", - backgroundColor: "#FAF8F5", - borderWidth: 1, - borderColor: "#E7E5E4", - paddingVertical: 10, - borderRadius: 10, - opacity: pressed ? 0.8 : 1, - })} - > - - - {/* Bu Şablonu Uygula / Aktif Rozeti */} handleApplyTheme(theme.key)} disabled={isSelected || isApplying} style={({ pressed }) => ({ - flex: 1.3, + flex: 1, flexDirection: "row", alignItems: "center", justifyContent: "center", @@ -429,8 +371,8 @@ export function ThemeSelectorSheet({ backgroundColor: isSelected ? "#ECFDF5" : theme.color, borderWidth: isSelected ? 1 : 0, borderColor: "#A7F3D0", - paddingVertical: 10, - borderRadius: 10, + paddingVertical: 12, + borderRadius: 12, opacity: pressed ? 0.85 : 1, })} > @@ -438,15 +380,15 @@ export function ThemeSelectorSheet({ ) : isSelected ? ( <> - - + + Aktif Şablon ) : ( <> - - + + Şablonu Seç diff --git a/apps/web/src/app/demo/page.tsx b/apps/web/src/app/demo/page.tsx index 7edaf58..2b09f14 100644 --- a/apps/web/src/app/demo/page.tsx +++ b/apps/web/src/app/demo/page.tsx @@ -20,7 +20,7 @@ export default async function DemoMenuPage({ searchParams }: PageProps) { restaurant={DEMO_RESTAURANT} categories={DEMO_CATEGORIES} initialThemeKey={theme} - allowThemeSwitching={true} + allowThemeSwitching={false} /> ); } diff --git a/apps/web/src/app/menu/[slug]/page.tsx b/apps/web/src/app/menu/[slug]/page.tsx index 582ae92..45fe468 100644 --- a/apps/web/src/app/menu/[slug]/page.tsx +++ b/apps/web/src/app/menu/[slug]/page.tsx @@ -74,7 +74,7 @@ export default async function PublicMenuPage({ params, searchParams }: PageProps let restaurant: any = null; const { data: bySlug } = await supabase .from("restaurants") - .select("id, name, slug, logo_url, phone, address") + .select("id, name, slug, logo_url, cover_url, phone, address") .eq("slug", slug) .maybeSingle(); @@ -84,7 +84,7 @@ export default async function PublicMenuPage({ params, searchParams }: PageProps // 2. Try finding restaurant by custom domain hostname const { data: domainRow } = await supabase .from("domains") - .select("restaurant_id, restaurants(id, name, slug, logo_url, phone, address)") + .select("restaurant_id, restaurants(id, name, slug, logo_url, cover_url, phone, address)") .eq("hostname", slug) .maybeSingle(); @@ -144,6 +144,7 @@ export default async function PublicMenuPage({ params, searchParams }: PageProps name: restaurant.name, slug: restaurant.slug, logo_url: restaurant.logo_url, + cover_url: restaurant.cover_url, phone: restaurant.phone, address: restaurant.address, }; diff --git a/apps/web/src/components/PublicMenuClient.tsx b/apps/web/src/components/PublicMenuClient.tsx index c2adae1..af2bfff 100644 --- a/apps/web/src/components/PublicMenuClient.tsx +++ b/apps/web/src/components/PublicMenuClient.tsx @@ -26,6 +26,7 @@ export interface RestaurantData { name: string; slug: string; logo_url: string | null; + cover_url?: string | null; phone?: string | null; address?: string | null; } @@ -43,7 +44,7 @@ export function PublicMenuClient({ categories, initialThemeKey = "elegant", customThemeConfig, - allowThemeSwitching = true, + allowThemeSwitching = false, }: PublicMenuClientProps) { const [selectedThemeKey, setSelectedThemeKey] = useState(initialThemeKey); const [searchQuery, setSearchQuery] = useState(""); @@ -176,26 +177,38 @@ export function PublicMenuClient({ {/* Header Hero Banner */}
+ {/* Background Cover Image if available */} + {restaurant.cover_url && ( + <> + {restaurant.name} +
+ + )} + {/* Subtle Ambient Glow */} -
+ {!restaurant.cover_url && ( +
+ )} {/* Top Bar: Table & Action Buttons */} -
+
{tableNumber ? ( -
+
Masa {tableNumber}
) : ( -
- Dijital QR Menü -
+
)}
@@ -230,54 +243,84 @@ export function PublicMenuClient({ )} - - {/* Live Theme Switcher Trigger */} - {allowThemeSwitching && ( - - )}
- {/* Restaurant Identity */} -
- {restaurant.logo_url ? ( - {restaurant.name} - ) : ( -
- {restaurant.name.charAt(0).toUpperCase()} -
- )} + {/* Restaurant Identity - Dynamic Header Layout (Centered or Left) */} + {theme.config.headerLayout === "left" ? ( + /* Left-Aligned Header Layout */ +
+ {restaurant.logo_url ? ( + {restaurant.name} + ) : ( +
+ {restaurant.name.charAt(0).toUpperCase()} +
+ )} -
-

+
+

+ {restaurant.name} +

+

+ {totalItemsCount} Özel Lezzet +

+
+

+ ) : ( + /* Centered Header Layout */ +
+ {/* Centered Logo Avatar */} +
+ {restaurant.logo_url ? ( + {restaurant.name} + ) : ( +
+ {restaurant.name.charAt(0).toUpperCase()} +
+ )} + {/* Decorative Ambient Glow Ring */} +
+
+ + {/* Centered Restaurant Title */} +

{restaurant.name}

-

+ + {/* Centered Subtitle Badge Pill */} +

+ {totalItemsCount} Özel Lezzet - - {theme.name} Şablonu -

+
-
+ )} {/* Live Search Bar */}
@@ -810,12 +853,6 @@ export function PublicMenuClient({ > ₺{item.price.toFixed(0)} - - + -
@@ -905,48 +942,19 @@ export function PublicMenuClient({

- {/* Floating Quick Action Bar (Garson Çağır / Hesap İste / Başa Dön) */} - + )}
{/* Item Detail Modal */} @@ -1003,30 +1011,17 @@ export function PublicMenuClient({ {selectedItem.description}

)} - - {/* Quality Badges */} -
- - 🌱 Taze & Günlük - - - ⭐ Şefin İmzası - -
{/* Modal Footer */}
diff --git a/apps/web/src/components/TemplateGalleryClient.tsx b/apps/web/src/components/TemplateGalleryClient.tsx index 2623422..c2e63b2 100644 --- a/apps/web/src/components/TemplateGalleryClient.tsx +++ b/apps/web/src/components/TemplateGalleryClient.tsx @@ -1,9 +1,8 @@ "use client"; -import { useState } from "react"; import Link from "next/link"; import { PublicMenuClient, type MenuCategory, type RestaurantData } from "@/components/PublicMenuClient"; -import { THEME_PRESETS, type ThemePreset } from "@/lib/theme"; +import { THEME_PRESETS } from "@/lib/theme"; interface TemplateGalleryClientProps { restaurant: RestaurantData; @@ -14,199 +13,86 @@ interface TemplateGalleryClientProps { export function TemplateGalleryClient({ restaurant, categories, - initialThemeKey = "elegant", }: TemplateGalleryClientProps) { - const [selectedThemeKey, setSelectedThemeKey] = useState(initialThemeKey); - const [viewMode, setViewMode] = useState<"phone" | "fullscreen">("phone"); - - const currentPreset: ThemePreset = THEME_PRESETS[selectedThemeKey] || THEME_PRESETS.elegant!; + const presetsList = Object.values(THEME_PRESETS); return (
{/* Top Navbar */}
-
-
-
- - MENULIO - - / - Şablon Galerisi -
- - {/* View Mode Toggle (Visible on desktop/tablet) */} -
- - -
-
- - {/* 5 Theme Pills - Smooth Horizontal Scroll */} -
- {Object.values(THEME_PRESETS).map((preset) => { - const isActive = selectedThemeKey === preset.key; - return ( - - ); - })} -
- -
- {/* View Mode Toggle (Desktop) */} -
- - -
- - - Uygulamayı İndir → +
+
+ + MENULIO + / + + Şablon Galerisi +
+ + + Ana Sayfa → +
- {/* Main Content Area */} -
- {viewMode === "fullscreen" ? ( - /* Fullscreen Fluid View */ -
- -
- ) : ( - /* Responsive Device Simulator / Side-by-Side on Desktop */ -
- {/* Left Info Panel (Visible on Desktop) */} -
-
- - ŞABLON DETAYI - -

- {currentPreset.name} -

-

- {currentPreset.key === "elegant" && "Fine dining restoranlar, şarap evleri ve lüks steakhouse mekanlar için altın & krem tonlarında yüksek prestijli tasarım."} - {currentPreset.key === "modern" && "Kafeler, burgerciler ve dinamik mekanlar için canlı mavi safir tonları ve hızlı arama odaklı ızgara düzeni."} - {currentPreset.key === "dark" && "Gece kulüpleri, kokteyl barlar ve lounge mekanlar için obsidian siyahı ve kehribar parıltılı lüks mod."} - {currentPreset.key === "minimal" && "Butik kahveciler, fırınlar ve üçüncü nesil mekanlar için ferah ve monokromatik Nordic mizanpaj."} - {currentPreset.key === "classic" && "Geleneksel brasserie'ler, meyhaneler ve trattoria'lar için Toskana bordo ve sıcak rustik doku."} -

+ {/* Main Content Area - Stacked Vertically */} +
+ {presetsList.map((preset) => ( +
+ {/* Theme Info */} +
+
+ + {preset.key} Şablonu
- {/* Theme Specs */} -
-
- Vurgu Rengi -
- - {currentPreset.config.primaryColor} -
-
+

+ {preset.name} +

-
- Tipografi Ailesi - {currentPreset.fontFamily} -
+

+ Tipografi: {preset.fontFamily} • Mizanpaj: {preset.config.productLayout} +

-
- Ürün Mizanpajı - {currentPreset.config.productLayout} -
- -
- Kategori Gezintisi - {currentPreset.config.categoryLayout} -
-
- - {/* Direct Demo Link */} - - Yeni Sekmede Canlı Menüyü Aç - -
- - {/* Right Phone Mockup Container */} -
-
- {/* Dynamic Island (Desktop only) */} -
- - {/* Simulated Screen Body */} -
- -
+
+ + Canlı Demoyu Sekmede Aç +
-
- )} + + {/* Phone Mockup Preview */} +
+ {/* Dynamic Island */} +
+ + {/* Screen Body */} +
+ +
+
+
+ ))}
); diff --git a/apps/web/src/lib/demo-data.ts b/apps/web/src/lib/demo-data.ts index 30fa80a..3209451 100644 --- a/apps/web/src/lib/demo-data.ts +++ b/apps/web/src/lib/demo-data.ts @@ -5,6 +5,7 @@ export const DEMO_RESTAURANT: RestaurantData = { name: "Gusto & Co. Brasserie", slug: "gusto-brasserie", logo_url: null, + cover_url: "https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=1200&auto=format&fit=crop&q=80", phone: "+90 (212) 555 0192", address: "Nişantaşı, Abdi İpekçi Cad. No: 42, İstanbul", }; diff --git a/apps/web/src/lib/theme.ts b/apps/web/src/lib/theme.ts index 7b6b6dc..32d8bb5 100644 --- a/apps/web/src/lib/theme.ts +++ b/apps/web/src/lib/theme.ts @@ -25,6 +25,7 @@ export const THEME_PRESETS: Record = { background: "#F7F3EC", productLayout: "card", categoryLayout: "tabs", + headerLayout: "centered", }, cardBg: "#FCFAF6", cardBorder: "#E4DBCF", @@ -44,6 +45,7 @@ export const THEME_PRESETS: Record = { background: "#0D1117", productLayout: "card", categoryLayout: "tabs", + headerLayout: "left", }, cardBg: "#FCF7EC", cardBorder: "rgba(255, 42, 133, 0.3)", @@ -63,6 +65,7 @@ export const THEME_PRESETS: Record = { background: "#EEEAE4", productLayout: "card", categoryLayout: "tabs", + headerLayout: "centered", }, cardBg: "#F7F4EF", cardBorder: "rgba(36, 70, 58, 0.2)", @@ -82,6 +85,7 @@ export const THEME_PRESETS: Record = { background: "#FFFFFF", productLayout: "card", categoryLayout: "tabs", + headerLayout: "left", }, cardBg: "#FFFFFF", cardBorder: "#000000", @@ -101,6 +105,7 @@ export const THEME_PRESETS: Record = { background: "#121316", productLayout: "card", categoryLayout: "tabs", + headerLayout: "centered", }, cardBg: "#1C1E24", cardBorder: "rgba(255, 255, 255, 0.08)", @@ -120,6 +125,7 @@ export const THEME_PRESETS: Record = { background: "#FAF8F5", productLayout: "card", categoryLayout: "accordion", + headerLayout: "centered", }, cardBg: "#FFFFFF", cardBorder: "rgba(200, 169, 107, 0.18)", @@ -139,6 +145,7 @@ export const THEME_PRESETS: Record = { background: "#F8FAFC", productLayout: "card", categoryLayout: "tabs", + headerLayout: "left", }, cardBg: "#FFFFFF", cardBorder: "rgba(226, 232, 240, 0.9)", @@ -158,6 +165,7 @@ export const THEME_PRESETS: Record = { background: "#0F0F12", productLayout: "card", categoryLayout: "accordion", + headerLayout: "centered", }, cardBg: "#18181D", cardBorder: "rgba(255, 255, 255, 0.07)", @@ -177,6 +185,7 @@ export const THEME_PRESETS: Record = { background: "#FAFAFA", productLayout: "list", categoryLayout: "flat", + headerLayout: "left", }, cardBg: "#FFFFFF", cardBorder: "#E4E4E7", @@ -196,6 +205,7 @@ export const THEME_PRESETS: Record = { background: "#FFF9F2", productLayout: "list", categoryLayout: "accordion", + headerLayout: "centered", }, cardBg: "#FFFFFF", cardBorder: "rgba(139, 30, 30, 0.15)", diff --git a/packages/shared/src/theme.ts b/packages/shared/src/theme.ts index 11a3d5c..9dc68a0 100644 --- a/packages/shared/src/theme.ts +++ b/packages/shared/src/theme.ts @@ -7,6 +7,7 @@ export const themeConfigSchema = z.object({ background: z.string(), productLayout: z.enum(["card", "list"]), categoryLayout: z.enum(["accordion", "tabs", "flat"]), + headerLayout: z.enum(["centered", "left"]).optional().default("centered"), }); export type ThemeConfig = z.infer; diff --git a/supabase/migrations/20260819000000_initial_schema.sql b/supabase/migrations/20260819000000_initial_schema.sql index c36ea4c..96e8d5b 100644 --- a/supabase/migrations/20260819000000_initial_schema.sql +++ b/supabase/migrations/20260819000000_initial_schema.sql @@ -27,6 +27,7 @@ create table restaurants ( name text not null, slug text not null unique, logo_url text, + cover_url text, phone text, address text, created_by uuid not null references users (id) on delete restrict,