Replace entire repo content with kottgard-production-v1.1.zip (for shahikitchen-prod repo)

This commit is contained in:
root
2026-06-29 15:04:08 +00:00
parent 6cd5aaa048
commit 57cc67d2d3
850 changed files with 26149 additions and 15588 deletions
-349
View File
@@ -1,349 +0,0 @@
export const arTranslations = {
// Navbar
nav: {
home: 'الرئيسية',
menu: 'القائمة',
catering: 'تموين الحفلات',
locations: 'الفروع',
login: 'تسجيل الدخول',
experience: 'التجربة',
contact: 'تواصل معنا',
},
reserve: 'احجز طاولة',
cart: 'السلة',
wishlist: 'المفضلة',
// Table Booking / Reserve Page
booking: {
title: 'احجز طاولتك',
subtitle: 'احجز طاولة في أسكيم أو باكابلان. اطلب مسبقاً أطباقك المفضلة من القائمة الكاملة لتجربة سلسة.',
formTitle: 'تفاصيل الحجز',
locationLabel: 'الفرع',
locationPlaceholder: 'اختر الفرع',
dateLabel: 'التاريخ',
timeLabel: 'الوقت',
guestsLabel: 'عدد الضيوف',
nameLabel: 'الاسم الكامل',
namePlaceholder: 'اسمك الكامل',
phoneLabel: 'رقم الهاتف',
phonePlaceholder: '+46 70 123 4567',
emailLabel: 'البريد الإلكتروني (اختياري)',
emailPlaceholder: 'your@email.com',
notesLabel: 'طلبات خاصة (اختياري)',
notesPlaceholder: 'مثال: مقعد بجانب النافذة، عيد ميلاد، حساسية',
continueBtn: 'المتابعة إلى الطلب المسبق',
menuTitle: 'طلب الطعام مسبقاً (اختياري)',
menuSubtitle: 'اختر الأطباق لتحضيرها مسبقاً قبل وصولك.',
searchPlaceholder: 'ابحث عن الأطباق...',
addToPreOrder: 'أضف إلى الطلب المسبق',
yourPreOrder: 'طلبك المسبق',
emptyPreOrder: 'لم تُختَر أي أطباق بعد. أضف الأطباق أعلاه للطلب المسبق.',
total: 'إجمالي الطلب المسبق',
sendInquiry: 'إرسال الحجز والطلب المسبق عبر واتساب',
inquiryNote: 'يفتح واتساب مع استفسار مُعبأ مسبقاً. سنؤكد التوفر وطلبك المسبق.',
successTitle: 'تم إرسال الاستفسار!',
successMessage: 'شكراً لك! سنؤكد حجز طاولتك وطلبك المسبق قريباً عبر واتساب أو الهاتف.',
editBooking: 'تعديل تفاصيل الحجز',
backHome: 'العودة إلى الرئيسية',
askim: 'أسكيم (سيسيون)',
backaplan: 'باكابلان',
},
// Hero
hero: {
badge: 'مطبخ شاهي الهندي والباكستاني منذ 2016',
welcome: 'أهلاً بكم في',
title: 'ShahiKitchen Online',
subtitle: 'استمتعوا بدفء ضيافة شاهي وغنى النكهات الهندية والباكستانية الأصيلة — الآن بأناقة، من قلب غوتنبرغ.',
exploreMenu: 'استكشف القائمة',
viewExperience: 'تجربة شاهي',
},
// Signature Menu
signatureMenu: {
title: 'قائمة التوقيع',
subtitle: 'مجموعة منتقاة من أحب أطباقنا لدى ضيوفنا.',
filterAll: 'الكل',
filterCurry: 'كاري',
filterRice: 'أرز',
filterGrill: 'مشويات',
filterSweets: 'حلويات',
filterMeat: 'لحوم',
filterStreet: 'شارع',
filterRoll: 'رول',
addToTable: 'أضف إلى الطاولة',
viewFullMenu: 'اعرض القائمة الكاملة — أكثر من 40 طبقاً',
},
signatureMenuItems: {
'chicken-biryani': 'بسمتي معتق عطري مع دجاج متبل وطبقات من الزعفران والبصل المكرمل',
'bong-nihari': 'عظم بقر مطهو ببطء في مرق غني عطري مع الزنجبيل والليمون ونان طازج',
panipuri: 'بوري مقرمش مجوف محشو بالحمص المتبل والبطاطس وماء التمر الهندي الحامض',
'lamm-palak': 'لحم غنم طري مطهو مع السبانخ الطازجة في مرق خفيف ولذيذ',
'chicken-karahi': 'دجاج مقلي في الووك بمرق قوي من الطماطم والفلفل والزنجبيل',
'chicken-haleem': 'دجاج مفتت مطهو ببطء مع العدس والقمح والبهارات العطرية',
'tikka-boti-roll': 'تيكا دجاج عصير ملفوف في نان طري مع صلصة النعناع والبصل',
jalebi: 'حلقات ذهبية مقرمشة بالزعفران منقوعة في شراب سكر عطري',
kulfi: 'حلوى حليب مجمدة تقليدية بالهيل والفستق والزعفران',
},
menuDescriptions: {
'samosa-aloo': 'معجنات مثلثة مقلية ومقرمشة محشوة بالبطاطس والبازلاء المتبلة.',
'samosa-keema': 'معجنات مقرمشة محشوة بحشوة لحم مفروم متبل.',
'samosa-chat': 'سموسا مقرمشة مغطاة بالحمص الحار واللبن والصلصات والأعشاب الطازجة.',
'chana-chat': 'حمص متبل حامض ممزوج بالبطاطس والبصل والطماطم والصلصات.',
panipuri: 'بوري مجوف مقرمش محشو بالحمص والبطاطس المتبلين، يُقدَّم مع ماء التمر الهندي الحامض.',
'keema-naan-starter': 'خبز نان طري محشو بلحم مفروم متبل، مخبوز حتى يصبح ذهبياً.',
'palak-paneer': 'جبن قريش مطهو في مرق سبانخ كريمي ببهارات خفيفة وأعشاب عطرية.',
'shahi-paneer': 'جبن قريش طري في مرق غني وكريمي من الكاجو والطماطم مع بهارات هندية.',
'malai-kofta': 'كرات خضار طرية مطهوة في مرق بصل وطماطم غني وكريمي ببهارات خفيفة.',
'daal-makhani': 'عدس أسود مطهو ببطء في مرق طماطم زبدي وكريمي ببهارات عطرية.',
'lahore-chana': 'حمص متبل مطهو في مرق بصل وطماطم حامض ببهارات البنجاب التقليدية.',
'lamm-palak': 'لحم غنم طري مطهو مع السبانخ الطازجة في مرق خفيف ولذيذ.',
'lamm-vindaloo': 'كاري لحم غنم حار وحامض بصلصة الخل والفلفل.',
'lamm-rogan-josh': 'كاري لحم غنم عطري مطهو ببطء في مرق زبادي وبهارات كشميرية غنية.',
'lamm-karahi': 'قطع لحم غنم مقلية في الووك مع الطماطم والزنجبيل والثوم والبهارات.',
'bong-nihari': 'عظم بقر مطهو ببطء في مرق غني وعطري، يُقدَّم تقليدياً مع النان.',
paye: 'أقدام غنم مطهوة ببطء في مرق كثيف حار ولذيذ.',
'shahi-burger': 'قرص لحم متبل عصير في خبز طري مع صلصات خاصة وخس وطماطم.',
'shami-sandwich': 'أقراص شامي كباب من لحم مفروم متبل تُقدَّم في خبز مع صلصة وبصل.',
'chicken-biryani': 'أرز بسمتي معتق عطري مع دجاج متبل طري وطبقات من الزعفران والبصل المكرمل.',
'chicken-tikka': 'قطع دجاج بدون عظم متبلة بالزبادي والبهارات، مشوية في التندور.',
'tikka-boti': 'قطع دجاج طرية متبلة بالبهارات ومشوية على أسياخ.',
'chicken-karahi': 'دجاج مقلي في الووك بمرق قوي من الطماطم والفلفل والزنجبيل.',
'lahore-sizzler': 'طبق ساخن من دجاج متبل مع خضروات وصلصات حارة.',
'butter-chicken': 'دجاج طري في مرق كريمي من الطماطم والزبدة ببهارات خفيفة.',
'chicken-haleem': 'دجاج مفتت مطهو ببطء مع العدس والقمح والبهارات العطرية.',
'lahore-pizza': 'بيتزا مغطاة بدجاج متبل وبصل وصلصات لاهورية خاصة على قاعدة مقرمشة.',
'kebab-pizza': 'بيتزا مع كباب لحم مفروم وجبن وبصل وبهارات عطرية.',
'tikka-boti-pizza': 'بيتزا مع تيكا دجاج مشوي وجبن وطماطم وأعشاب طازجة.',
'peshawari-pizza': 'بيتزا على طريقة النان بلحم طري ومكسرات وزبيب وبهارات بشاورية.',
'veg-pizza': 'بيتزا نباتية محشوة بخضروات طازجة وجبن وصلصة طماطم.',
'tikka-boti-roll': 'تيكا دجاج مشوي ملفوف في نان طري مع صلصة النعناع والبصل.',
'kebab-roll': 'كباب لحم مفروم متبل ملفوف في نان مع صلصة وسلطة وصلصات.',
'falafel-roll': 'فلافل مقرمش ملفوف في نان مع خضروات وحمص وصلصات حامضة.',
'paneer-roll': 'مكعبات بانير مشوية ملفوفة في نان مع بهارات وصلصة وخضروات طازجة.',
namakpare: 'مقرمشات دقيق مقلية مالحة متبلة ببذور الكراويا والملح.',
jalebi: 'حلقات ذهبية مقرمشة بالزعفران منقوعة في شراب سكر عطري.',
'gajar-halwa': 'حلوى جزر حلوة مطهوة ببطء مع الحليب والسكر والسمن والمكسرات.',
rasmalai: 'كرات جبن طرية منقوعة في حليب حلو بارد بالهيل والزعفران.',
kulfi: 'حلوى حليب مجمدة كريمية تقليدية بالهيل والفستق والزعفران.',
'masala-chai': 'شاي متبل تقليدي مُحضَّر بالحليب والهيل والزنجبيل والبهارات العطرية.',
'mango-lassi': 'مشروب زبادي حلو منعش ممزوج بمانجو ناضج وهيل.',
'coca-cola': 'مشروب كولا بارد كلاسيكي.',
'pepsi-fanta': 'مشروب غازي منعش بنكهة الكولا أو البرتقال.',
'sprite-ramlosa': 'صودا ليمون-لايم منعشة أو مياه معدنية فوارة.',
'energy-drink': 'مشروب منشط بالكافيين لدفعة طاقة فورية.',
juice: 'عصير فواكه طازج، عادة مانجو أو نكهات موسمية أخرى.',
coffee: 'قهوة ساخنة طازجة.',
latte: 'إسبريسو مع حليب مبخر وطبقة خفيفة من الرغوة.',
cappuccino: 'إسبريسو مغطى بحليب مبخر ورغوة كثيفة.',
tea: 'شاي أسود ساخن تقليدي، يُقدَّم سادة أو مع الحليب.',
},
// Experience
experience: {
badge: 'أسلوب شاهي',
title: 'دفء كالوليمة.\nهدوء كالقصر.',
heritage: {
title: 'إرث شاهي',
text: 'وصفات توارثتها الأجيال. كل طبق يحكي قصة البنجاب ومطابخ شاهي في شبه القارة.',
},
generous: {
title: 'سخاء وصدق',
text: 'حصص وفيرة. بلا اختصارات. نعامل كل ضيف كأنه من العائلة — كما ينبغي أن تكون الضيافة.',
},
grace: {
title: 'أناقة عصرية',
text: 'أماكن جميلة في أسكيم وباكابلان. خدمة سريعة ومدروسة. تغليف يستحق أن يُهدى.',
},
},
// Locations
locations: {
badge: 'بيتان في غوتنبرغ',
title: 'تأتوا ضيوفاً.\nوتغادروا عائلة.',
},
// Footer
footer: {
tagline: 'مأكولات هندية وباكستانية أصيلة في غوتنبرغ منذ 2016.',
locations: 'فروعنا',
explore: 'استكشف',
follow: 'تابعنا',
},
catering: {
badge: 'المناسبات والاحتفالات',
title: 'تموين شاهي',
subtitle:
'باقات فاخرة لكل ضيف للأعراس والفعاليات الشركات والتجمعات العائلية — نكهات شاهي أصيلة بتقديم راقٍ.',
perHead: 'لكل ضيف',
includedDishes: 'الأطباق المشمولة',
mostPopular: 'الأكثر شعبية',
guestNote: 'قوائم مخصصة متاحة — تواصل معنا لتخصيص مناسبتك.',
catalogBadge: 'قائمة التموين الكاملة',
catalogTitle: 'أطباق التموين المتاحة',
catalogSubtitle:
'جميع الباقات مبنية على قائمة التموين الرئيسية. امزج واختر لمناسبات خاصة.',
sendInquiry: 'إرسال استفسار',
inquiryMessage:
'مرحباً Shahi Kitchen 👋\n\nأود الاستفسار عن تموين لمناسبة.\n\nيرجى التواصل معي بخصوص التوفر وخيارات الباقات.\n\nشكراً لك!',
categories: {
lamb: 'أطباق لحم الضأن',
chicken: 'أطباق الدجاج',
beef: 'أطباق اللحم البقري',
vegetarian: 'أطباق نباتية',
sides: 'الأطباق الجانبية',
},
packages: {
silver: 'باقة الفضة',
gold: 'باقة الذهب',
royal: 'باقة شاهي الملكية',
},
packageDescriptions: {
silver:
'مقدمة راقية لتموين شاهي — كاري مميز واحد، دال، أرز، نان وسلطة طازجة. مثالي للغداء المكتبي والتجمعات الصغيرة.',
gold:
'قائمة الاحتفال الأكثر شعبية — برياني، كاريان، كلاسيكي نباتي، أرز، نان، رايتا وسلطة. مثالي للأعراس.',
royal:
'تجربة شاهي الكاملة — برياني، تيكا ماسالا، لحم ضأن فاخر، سيخ كباب، بانير، دال وجميع الأطباق الجانبية.',
},
},
// Common
add: 'أضف',
viewCart: 'عرض السلة',
// Cart Drawer (fully language-aware)
cartDrawer: {
title: 'سلتك',
item: 'صنف',
items: 'أصناف',
clear: 'مسح',
empty: 'سلتك فارغة',
browseMenu: 'تصفح القائمة ←',
clearBasket: 'إفراغ السلة',
total: 'الإجمالي',
pickupNote: 'وقت استلام الطلب المقدر 30 دقيقة، وقد يختلف حسب ضغط العمل والتوفر.',
sendViaWhatsApp: 'إرسال الطلب عبر واتساب',
call: 'اتصل 031-28 89 10',
continueBrowsing: 'متابعة التصفح',
whatsappHint: 'يفتح واتساب مع طلبك مُعبأ مسبقاً. سنؤكد التوفر.',
remove: 'إزالة',
// WhatsApp message fragments (used to build the draft in the correct language)
messageHello: 'مرحباً Shahi Kitchen 👋',
messageIntro: 'أود تقديم طلب:',
messageConfirm: 'يرجى تأكيد وقت الاستلام (مثلاً {time} أو لاحقاً)',
messageTotal: 'الإجمالي',
messageThanks: 'شكراً لك!',
},
wishlistDrawer: {
title: 'قائمة المفضلة',
item: 'طبق',
items: 'أطباق',
clear: 'مسح',
empty: 'قائمة المفضلة فارغة',
browseMenu: 'تصفح القائمة ←',
addToCart: 'أضف إلى السلة',
remove: 'إزالة',
hint: 'احفظ أطباقك المفضلة وأضفها إلى طلبك في أي وقت.',
continueBrowsing: 'متابعة التصفح',
},
// Authentication / Staff Login Page (fully translated, placeholder only)
auth: {
title: 'دخول الموظفين',
subtitle: 'وصول آمن لأعضاء فريق مطبخ شاهي في فروعنا',
usernameLabel: 'اسم المستخدم',
usernamePlaceholder: 'أدخل اسم المستخدم',
passwordLabel: 'كلمة المرور',
passwordPlaceholder: 'أدخل كلمة المرور',
siteLabel: 'اختر الفرع',
sitePlaceholder: 'اختر فرعك',
askim: 'أسكيم (سيسيون)',
backaplan: 'باكابلان',
submit: 'تسجيل الدخول',
submitting: 'جارٍ تسجيل الدخول...',
construction: {
title: 'نظام المصادقة قيد الإنشاء',
message: 'نظام دخول الموظفين قيد التطوير حالياً. خدمة المصادقة الخلفية غير متاحة بعد. يرجى المحاولة لاحقاً. للمساعدة الفورية في الطلبات أو الحجوزات، تواصل مع المطعم مباشرة عبر الهاتف أو واتساب.',
contact: 'تواصل مع المطعم',
tryAgain: 'إغلاق والمحاولة لاحقاً',
},
footerNote: 'هذا البوابة مخصصة لموظفي مطبخ شاهي المصرح لهم فقط.',
},
// Full Menu Page
menu: {
title: 'قائمتنا',
subtitle: 'وصفات تقليدية. حصص سخية. مُعدَّة من القلب.',
searchPlaceholder: 'ابحث عن الأطباق...',
showVegetarian: 'عرض النباتي',
vegetarianOnly: 'نباتي فقط',
clearFilters: 'مسح الفلاتر',
noResults: 'لم يُعثَر على أطباق تطابق الفلاتر.',
dishes: 'أطباق',
allDishes: 'جميع الأطباق',
perHalfKg: 'kr / ½ kg',
perKg: 'kr / kg',
},
// In-Restaurant Display Screens (screen1/screen2) — desktop fullscreen only, mesmerizing menu + animations
screen: {
brand: 'Shahi Kitchen',
display1: 'شاشة 1',
display2: 'شاشة 2',
menuTitle: 'القائمة',
kitchenTitle: 'في المطبخ',
kitchenSubtitle: 'شاهد أطباقك المفضلة وهي تُحضَّر',
featuredTag: 'توقيع',
prepared: 'مُحضَّر طازجاً في مطبخنا',
viewFull: 'القائمة الكاملة على shahikitchen.se',
// screen3 - Live Order Display (for customers & delivery riders)
display3: 'شاشة 3',
orderBoard: 'لوحة الطلبات المباشرة',
orderSubtitle: 'طاولات داخل المطعم والتوصيل عبر الإنترنت — لحظي للعملاء والسائقين',
inHouse: 'داخل المطعم',
online: 'توصيل عبر الإنترنت',
statuses: {
received: 'تم استلام الطلب',
review: 'قيد المراجعة',
preparing: 'قيد التحضير',
packing: 'التعبئة / التقديم',
ready: 'جاهز',
},
readyForPickup: 'جاهز للاستلام',
serving: 'يُقدَّم الآن',
elapsed: 'منقضٍ',
eta: 'الوقت المتوقع',
mins: 'د',
table: 'طاولة',
riderNote: 'السائقون: ابحثوا عن رقم طلبكم على المنصة',
liveUpdates: 'تحديثات مباشرة • الخادم الخلفي قريباً',
},
// Table ordering via QR (orderfromtable page)
tableOrder: {
title: 'اطلب من طاولتك',
branchAskim: 'مطبخ شاهي أسكيم',
branchBackaplan: 'مطبخ شاهي باكابلان',
tableLabel: 'طاولة',
invalidTitle: 'رمز QR للطاولة غير صالح',
invalidMessage: 'يرجى طلب المساعدة من موظفي المطعم.',
selectTitle: 'اختر أطباقك',
selectSubtitle: 'اضغط على أي طبق لإضافته إلى طلبك.',
searchPlaceholder: 'ابحث عن الأطباق...',
showVegetarian: 'نباتي فقط',
yourOrder: 'طلبك',
emptyOrder: 'لا توجد أصناف بعد. اضغط على الأطباق أعلاه لبناء طلبك.',
notesLabel: 'ملاحظات للمطبخ (اختياري)',
notesPlaceholder: 'مثال: بدون بصل، حار جداً، حساسية...',
sendOrder: 'إرسال الطلب',
total: 'الإجمالي',
confirmationTitle: 'تم إرسال الطلب!',
confirmationMessage: 'تم إرسال طلبك. سيأتي أحد من المطعم إلى طاولتك قريباً لتأكيد طلبك.',
orderAnother: 'اطلب المزيد',
},
} as const;
-349
View File
@@ -1,349 +0,0 @@
export const trTranslations = {
// Navbar
nav: {
home: 'Ana Sayfa',
menu: 'Menü',
catering: 'Catering',
locations: 'Şubeler',
login: 'Giriş',
experience: 'Deneyim',
contact: 'İletişim',
},
reserve: 'Masa Rezervasyonu',
cart: 'Sepet',
wishlist: 'Favoriler',
// Table Booking / Reserve Page
booking: {
title: 'Masanızı Rezerve Edin',
subtitle: 'Askim veya Backaplan\'da masa ayırtın. Sorunsuz bir deneyim için tam menüden favorilerinizi önceden sipariş edin.',
formTitle: 'Rezervasyon Bilgileriniz',
locationLabel: 'Şube',
locationPlaceholder: 'Şube seçin',
dateLabel: 'Tarih',
timeLabel: 'Saat',
guestsLabel: 'Misafir Sayısı',
nameLabel: 'Ad Soyad',
namePlaceholder: 'Adınız ve soyadınız',
phoneLabel: 'Telefon Numarası',
phonePlaceholder: '+46 70 123 4567',
emailLabel: 'E-posta (isteğe bağlı)',
emailPlaceholder: 'your@email.com',
notesLabel: 'Özel İstekler (isteğe bağlı)',
notesPlaceholder: 'ör. pencere kenarı, doğum günü, alerjiler',
continueBtn: 'Ön Sipariş Menüsüne Devam Et',
menuTitle: 'Önceden Yemek Siparişi (İsteğe Bağlı)',
menuSubtitle: 'Gelişiniz için önceden hazırlanacak yemekleri seçin.',
searchPlaceholder: 'Yemek ara...',
addToPreOrder: 'Ön Siparişe Ekle',
yourPreOrder: 'Ön Siparişiniz',
emptyPreOrder: 'Henüz ürün seçilmedi. Ön sipariş için yukarıdan yemek ekleyin.',
total: 'Ön Sipariş Toplamı',
sendInquiry: 'Rezervasyon ve Ön Siparişi WhatsApp ile Gönder',
inquiryNote: 'Bu, önceden doldurulmuş bir sorguyla WhatsApp\'ı açar. Müsaitliği ve ön siparişinizi onaylayacağız.',
successTitle: 'Sorgu Gönderildi!',
successMessage: 'Teşekkürler! Masanızı ve ön siparişinizi kısa süre içinde WhatsApp veya telefonla onaylayacağız.',
editBooking: 'Rezervasyon Bilgilerini Düzenle',
backHome: 'Ana Sayfaya Dön',
askim: 'Askim (Sisjön)',
backaplan: 'Backaplan',
},
// Hero
hero: {
badge: '2016\'dan Beri Shahi Hint ve Pakistan Mutfağı',
welcome: 'Hoş geldiniz',
title: 'ShahiKitchen Online',
subtitle: 'Shahi misafirperverliğinin sıcaklığını ve otantik Hint-Pakistan lezzetlerinin zenginliğini yaşayın — şimdi Gothenburg\'un kalbinden, zarafetle.',
exploreMenu: 'Menüyü Keşfedin',
viewExperience: 'Shahi Deneyimi',
},
// Signature Menu
signatureMenu: {
title: 'İmza Menü',
subtitle: 'En sevilen yemeklerimizden özenle seçilmiş bir koleksiyon.',
filterAll: 'Tümü',
filterCurry: 'Köri',
filterRice: 'Pilav',
filterGrill: 'Izgara',
filterSweets: 'Tatlılar',
filterMeat: 'Et',
filterStreet: 'Sokak',
filterRoll: 'Dürüm',
addToTable: 'Masaya Ekle',
viewFullMenu: 'TAM MENÜYÜ GÖRÜN — 40+ YEMEK',
},
signatureMenuItems: {
'chicken-biryani': 'Baharatlı tavuk, safran ve karamelize soğan katmanlarıyla aromatik yaşlandırılmış basmati pilav',
'bong-nihari': 'Zencefil, limon ve taze naan ile zengin aromatik sos içinde yavaş pişirilmiş dana incik',
panipuri: 'Baharatlı nohut, patates ve ekşi hint eriği suyuyla doldurulmuş çıtır içi boş puriler',
'lamm-palak': 'Taze ıspanakla pişirilmiş yumuşak kuzu eti, hafif ve lezzetli bir sos içinde',
'chicken-karahi': 'Wokta kavrulmuş tavuk, domates, biber ve zencefil sosunda',
'chicken-haleem': 'Mercimek, buğday ve aromatik baharatlarla yavaş pişirilmiş didiklenmiş tavuk',
'tikka-boti-roll': 'Nane chutney ve soğanla yumuşak naan içine sarılmış sulu tavuk tikka',
jalebi: 'Kokulu şeker şurabına batırılmış çıtır altın safran spiralleri',
kulfi: 'Kakule, antep fıstığı ve safranlı geleneksel dondurulmuş sütlü tatlı',
},
menuDescriptions: {
'samosa-aloo': 'Baharatlı patates ve bezelye ile doldurulmuş çıtır kızarmış üçgen börekler.',
'samosa-keema': 'Baharatlı kıyma dolgulu yapraklı börekler.',
'samosa-chat': 'Baharatlı nohut, yoğurt, soslar ve taze otlarla süslenmiş çıtır samosalar.',
'chana-chat': 'Patates, soğan, domates ve soslarla karıştırılmış ekşi baharatlı nohut.',
panipuri: 'Baharatlı nohut ve patatesle doldurulmuş çıtır içi boş puriler, ekşi hint eriği suyuyla servis edilir.',
'keema-naan-starter': 'Baharatlı kıyma ile doldurulmuş yumuşak naan ekmeği, altın rengi olana kadar pişirilir.',
'palak-paneer': 'Hafif baharatlar ve aromatik otlarla kremalı ıspanak sosunda pişirilmiş lor peyniri.',
'shahi-paneer': 'Hint baharatlarıyla zengin, kremalı kaju ve domates sosunda yumuşak lor peyniri.',
'malai-kofta': 'Hafif baharatlı zengin ve kremalı soğan-domates sosunda pişirilmiş yumuşak sebze köfteleri.',
'daal-makhani': 'Aromatik baharatlarla tereyağlı, kremalı domates sosunda yavaş pişirilmiş siyah mercimek.',
'lahore-chana': 'Geleneksel Pencap baharatlarıyla ekşi soğan-domates sosunda pişirilmiş baharatlı nohut.',
'lamm-palak': 'Taze ıspanakla pişirilmiş yumuşak kuzu eti, hafif ve lezzetli bir sos içinde.',
'lamm-vindaloo': 'Sirke ve biber bazlı sos içinde baharatlı ve ekşi kuzu körisi.',
'lamm-rogan-josh': 'Zengin yoğurt ve Keşmir baharat sosunda yavaş pişirilmiş aromatik kuzu körisi.',
'lamm-karahi': 'Domates, zencefil, sarımsak ve baharatlarla wokta kavrulmuş kuzu parçaları.',
'bong-nihari': 'Zengin aromatik sos içinde yavaş pişirilmiş dana incik, geleneksel olarak naan ile servis edilir.',
paye: 'Koyu, baharatlı ve lezzetli bir sos içinde yavaş kaynatılmış kuzu paçaları.',
'shahi-burger': 'Özel soslar, marul ve domatesle yumuşak ekmek arasında sulu baharatlı et köftesi.',
'shami-sandwich': 'Sos ve soğanla ekmek arasında servis edilen baharatlı kıymalı şami kebab köfteleri.',
'chicken-biryani': 'Yumuşak baharatlı tavuk, safran ve karamelize soğan katmanlarıyla aromatik yaşlandırılmış basmati pilav.',
'chicken-tikka': 'Yoğurt ve baharatlarda marine edilmiş kemiksiz tavuk parçaları, tandırda ızgara yapılır.',
'tikka-boti': 'Baharatlarda marine edilmiş yumuşak tavuk parçaları, şişte ızgara yapılır.',
'chicken-karahi': 'Wokta kavrulmuş tavuk, domates, biber ve zencefil sosunda.',
'lahore-sizzler': 'Sebzeler ve baharatlı soslarla marine edilmiş tavuk, ıslık çalan tabakta servis edilir.',
'butter-chicken': 'Hafif baharatlı kremalı domates ve tereyağı sosunda yumuşak tavuk.',
'chicken-haleem': 'Mercimek, buğday ve aromatik baharatlarla yavaş pişirilmiş didiklenmiş tavuk.',
'lahore-pizza': 'Çıtır taban üzerinde baharatlı tavuk, soğan ve özel Lahor soslarıyla pizza.',
'kebab-pizza': 'Kıyma kebab, peynir, soğan ve aromatik baharatlarla pizza.',
'tikka-boti-pizza': 'Izgara tavuk tikka, peynir, domates ve taze otlarla pizza.',
'peshawari-pizza': 'Yumuşak et, kuruyemiş, kuru üzüm ve Peşaveri baharatlarıyla naan tarzı pizza.',
'veg-pizza': 'Taze sebzeler, peynir ve domates sosuyla dolu vejetaryen pizza.',
'tikka-boti-roll': 'Nane chutney ve soğanla yumuşak naan içine sarılmış ızgara tavuk tikka.',
'kebab-roll': 'Sos, salata ve çeşitli soslarla naan içine sarılmış baharatlı kıyma kebab.',
'falafel-roll': 'Sebzeler, humus ve ekşi soslarla naan içine sarılmış çıtır falafel.',
'paneer-roll': 'Baharatlar, sos ve taze sebzelerle naan içine sarılmış ızgara paneer küpleri.',
namakpare: 'Çörek otu ve tuzla tatlandırılmış çıtır, tuzlu kızarmış un atıştırmalıkları.',
jalebi: 'Kokulu şeker şurabına batırılmış çıtır altın safran spiralleri.',
'gajar-halwa': 'Süt, şeker, ghee ve kuruyemişlerle yavaş pişirilmiş tatlı havuç pudingi.',
rasmalai: 'Kakule ve safranla soğutulmuş tatlandırılmış sütte bekletilmiş yumuşak peynir topları.',
kulfi: 'Kakule, antep fıstığı ve safranlı kremalı geleneksel dondurulmuş sütlü tatlı.',
'masala-chai': 'Süt, kakule, zencefil ve aromatik baharatlarla demlenmiş geleneksel baharatlı çay.',
'mango-lassi': 'Olgun mango ve kakule ile karıştırılmış ferahlatıcı tatlı yoğurt içeceği.',
'coca-cola': 'Klasik soğuk kola.',
'pepsi-fanta': 'Ferahlatıcı kola veya portakallı gazlı içecek.',
'sprite-ramlosa': 'Çıtır limon-lime soda veya maden suyu.',
'energy-drink': 'Anlık enerji için kafeinli içecek.',
juice: 'Taze meyve suyu, genellikle mango veya diğer mevsimlik lezzetler.',
coffee: 'Taze demlenmiş sıcak kahve.',
latte: 'Buharla ısıtılmış sütlü espresso, hafif köpük tabakasıyla.',
cappuccino: 'Buharla ısıtılmış sütlü ve kalın köpüklü espresso.',
tea: 'Geleneksel sıcak siyah çay, sade veya sütlü servis edilir.',
},
// Experience
experience: {
badge: 'SHAHI YOLU',
title: 'Ziyafet gibi sıcaklık.\nSaray gibi huzur.',
heritage: {
title: 'Shahi Mirası',
text: 'Nesiller boyu aktarılan tarifler. Her yemek, Pencap ve alt kıtanın şahi mutfaklarının hikayesini anlatır.',
},
generous: {
title: 'Cömert ve Dürüst',
text: 'Büyük porsiyonlar. Kısayol yok. Her misafiri aile gibi karşılıyoruz — misafirperverlik böyle olmalı.',
},
grace: {
title: 'Modern Zarafet',
text: 'Askim ve Backaplan\'da güzel mekanlar. Hızlı, düşünceli servis. Hediye değerinde paketleme.',
},
},
// Locations
locations: {
badge: 'GOTHENBURG\'DA İKİ EV',
title: 'Misafir olarak gelin.\nAile olarak ayrılın.',
},
// Footer
footer: {
tagline: '2016\'dan beri Gothenburg\'da otantik Hint ve Pakistan mutfağı.',
locations: 'ŞUBELERİMİZ',
explore: 'KEŞFET',
follow: 'BİZİ TAKİP EDİN',
},
catering: {
badge: 'Etkinlikler & Kutlamalar',
title: 'Shahi Catering',
subtitle:
'Düğünler, kurumsal etkinlikler ve aile toplantıları için kişi başı premium paketler — otantik Shahi lezzetleri.',
perHead: 'kişi başı',
includedDishes: 'Dahil yemekler',
mostPopular: 'En Popüler',
guestNote: 'Özel menüler mevcut — etkinliğiniz için bizimle iletişime geçin.',
catalogBadge: 'Tam catering menüsü',
catalogTitle: 'Mevcut catering yemekleri',
catalogSubtitle:
'Tüm paketler ana catering menümüzden oluşur. Özel etkinlikler için karıştırın.',
sendInquiry: 'Sorgu Gönder',
inquiryMessage:
'Merhaba Shahi Kitchen 👋\n\nBir etkinlik için catering hakkında bilgi almak istiyorum.\n\nLütfen müsaitlik ve paket seçenekleri için benimle iletişime geçin.\n\nTeşekkürler!',
categories: {
lamb: 'Kuzu yemekleri',
chicken: 'Tavuk yemekleri',
beef: 'Dana yemekleri',
vegetarian: 'Vejetaryen yemekler',
sides: 'Yan ürünler',
},
packages: {
silver: 'Gümüş Paket',
gold: 'Altın Paket',
royal: 'Kraliyet Shahi Paketi',
},
packageDescriptions: {
silver:
'Shahi catering\'e zarif bir giriş — bir imza köri, dal, pilav, naan ve taze salata. Küçük toplantılar için ideal.',
gold:
'En popüler kutlama menümüz — biryani, iki köri, vejetaryen klasik, pilav, naan, raita ve salata.',
royal:
'Tam Shahi deneyimi — biryani, tikka masala, premium kuzu, şiş kebab, paneer, dal ve tüm yan ürünler.',
},
},
// Common
add: 'Ekle',
viewCart: 'Sepeti Görüntüle',
// Cart Drawer (fully language-aware)
cartDrawer: {
title: 'Sepetiniz',
item: 'ürün',
items: 'ürün',
clear: 'Temizle',
empty: 'Sepetiniz boş',
browseMenu: 'Menüye göz atın →',
clearBasket: 'Sepeti temizle',
total: 'Toplam',
pickupNote: 'Tahmini sipariş teslim alma süresi 30 dakikadır; iş yoğunluğu ve müsaitliğe göre değişebilir.',
sendViaWhatsApp: 'Siparişi WhatsApp ile gönder',
call: 'Ara 031-28 89 10',
continueBrowsing: 'Göz atmaya devam et',
whatsappHint: 'WhatsApp siparişiniz önceden doldurulmuş olarak açılır. Müsaitliği onaylayacağız.',
remove: 'Kaldır',
// WhatsApp message fragments (used to build the draft in the correct language)
messageHello: 'Merhaba Shahi Kitchen 👋',
messageIntro: 'Sipariş vermek istiyorum:',
messageConfirm: 'Lütfen teslim alma saatini onaylayın (ör. {time} veya sonrası)',
messageTotal: 'Toplam',
messageThanks: 'Teşekkürler!',
},
wishlistDrawer: {
title: 'Favorileriniz',
item: 'yemek',
items: 'yemek',
clear: 'Temizle',
empty: 'Favori listeniz boş',
browseMenu: 'Menüye göz atın →',
addToCart: 'Sepete Ekle',
remove: 'Kaldır',
hint: 'Favori yemeklerinizi kaydedin ve istediğiniz zaman siparişe ekleyin.',
continueBrowsing: 'Göz atmaya devam et',
},
// Authentication / Staff Login Page (fully translated, placeholder only)
auth: {
title: 'Personel Girişi',
subtitle: 'Shahi Kitchen ekip üyeleri için güvenli erişim',
usernameLabel: 'Kullanıcı Adı',
usernamePlaceholder: 'Kullanıcı adınızı girin',
passwordLabel: 'Şifre',
passwordPlaceholder: 'Şifrenizi girin',
siteLabel: 'Şube Seçin',
sitePlaceholder: 'Şubenizi seçin',
askim: 'Askim (Sisjön)',
backaplan: 'Backaplan',
submit: 'Giriş Yap',
submitting: 'Giriş yapılıyor...',
construction: {
title: 'Kimlik Doğrulama Yapım Aşamasında',
message: 'Personel giriş sistemimiz şu anda geliştirilme aşamasındadır. Arka uç kimlik doğrulama hizmeti henüz kullanılamıyor. Lütfen daha sonra tekrar deneyin. Sipariş veya rezervasyon için acil yardım için lütfen restoranla doğrudan telefon veya WhatsApp üzerinden iletişime geçin.',
contact: 'Restoranla İletişime Geç',
tryAgain: 'Kapat ve Sonra Dene',
},
footerNote: 'Bu portal yalnızca yetkili Shahi Kitchen personeli içindir.',
},
// Full Menu Page
menu: {
title: 'Menümüz',
subtitle: 'Geleneksel tarifler. Cömert porsiyonlar. Kalpten yapılmış.',
searchPlaceholder: 'Yemek ara...',
showVegetarian: 'Vejetaryen Göster',
vegetarianOnly: 'Yalnızca Vejetaryen',
clearFilters: 'Filtreleri temizle',
noResults: 'Filtrelerinize uyan yemek bulunamadı.',
dishes: 'yemek',
allDishes: 'Tüm Yemekler',
perHalfKg: 'kr / ½ kg',
perKg: 'kr / kg',
},
// In-Restaurant Display Screens (screen1/screen2) — desktop fullscreen only, mesmerizing menu + animations
screen: {
brand: 'Shahi Kitchen',
display1: 'EKRAN 1',
display2: 'EKRAN 2',
menuTitle: 'Menü',
kitchenTitle: 'Mutfakta',
kitchenSubtitle: 'Favorilerinizin hazırlanışını izleyin',
featuredTag: 'İmza',
prepared: 'Mutfağımızda taze hazırlanır',
viewFull: 'Tam menü shahikitchen.se adresinde',
// screen3 - Live Order Display (for customers & delivery riders)
display3: 'EKRAN 3',
orderBoard: 'Canlı Sipariş Panosu',
orderSubtitle: 'Restoran içi masalar ve online teslimat — müşteriler ve kuryeler için gerçek zamanlı',
inHouse: 'Restoran İçi',
online: 'Online Teslimat',
statuses: {
received: 'Sipariş Alındı',
review: 'İnceleniyor',
preparing: 'Hazırlanıyor',
packing: 'Paketleme / Sunum',
ready: 'Hazır',
},
readyForPickup: 'TESLİM ALMAYA HAZIR',
serving: 'ŞİMDİ SERVİS EDİLİYOR',
elapsed: 'geçen',
eta: 'Tahmini',
mins: 'dk',
table: 'Masa',
riderNote: 'Kuryeler: platform sipariş numaranızı arayın',
liveUpdates: 'Canlı güncellemeler • Arka uç yakında',
},
// Table ordering via QR (orderfromtable page)
tableOrder: {
title: 'Masadan sipariş verin',
branchAskim: 'Shahi Kitchen Askim',
branchBackaplan: 'Shahi Kitchen Backaplan',
tableLabel: 'Masa',
invalidTitle: 'Geçersiz masa QR kodu',
invalidMessage: 'Lütfen restoran personelinden yardım isteyin.',
selectTitle: 'Yemeklerinizi seçin',
selectSubtitle: 'Siparişinize eklemek için herhangi bir yemeğe dokunun.',
searchPlaceholder: 'Yemek ara...',
showVegetarian: 'Yalnızca vejetaryen',
yourOrder: 'Siparişiniz',
emptyOrder: 'Henüz ürün yok. Siparişinizi oluşturmak için yukarıdaki yemeklere dokunun.',
notesLabel: 'Mutfak için notlar (isteğe bağlı)',
notesPlaceholder: 'ör. soğansız, ekstra acılı, alerjiler...',
sendOrder: 'Siparişi gönder',
total: 'Toplam',
confirmationTitle: 'Sipariş gönderildi!',
confirmationMessage: 'Siparişiniz gönderildi. Restorandan biri kısa süre içinde siparişinizi onaylamak için masanıza gelecek.',
orderAnother: 'Daha fazla sipariş ver',
},
} as const;
-30
View File
@@ -1,30 +0,0 @@
/** Shallow-deep merge for translation fallbacks */
export function mergeTranslations<T extends Record<string, unknown>>(
base: T,
override: Partial<T>
): T {
const result = { ...base };
for (const key of Object.keys(override) as (keyof T)[]) {
const baseVal = base[key];
const overrideVal = override[key];
if (
overrideVal &&
typeof overrideVal === 'object' &&
!Array.isArray(overrideVal) &&
baseVal &&
typeof baseVal === 'object' &&
!Array.isArray(baseVal)
) {
result[key] = mergeTranslations(
baseVal as Record<string, unknown>,
overrideVal as Record<string, unknown>
) as T[keyof T];
} else if (overrideVal !== undefined) {
result[key] = overrideVal as T[keyof T];
}
}
return result;
}
File diff suppressed because it is too large Load Diff
-115
View File
@@ -1,115 +0,0 @@
'use client';
import React, { createContext, useContext, useReducer, useEffect, ReactNode } from 'react';
import { toast } from 'sonner';
import { cartReducer, getCartTotals } from '@/domain/cart/cart-domain';
import type { CartItem, NewCartItem } from '@/domain/cart/entities';
import { container } from '@/infrastructure/di/container';
import { playAddSound } from '@/infrastructure/audio/web-audio-sound-adapter';
export type { CartItem };
interface CartContextType {
items: CartItem[];
isOpen: boolean;
totalItems: number;
totalPrice: number;
addToCart: (item: NewCartItem) => void;
removeFromCart: (id: string) => void;
updateQuantity: (id: string, quantity: number) => void;
clearCart: () => void;
toggleCart: () => void;
openCart: () => void;
closeCart: () => void;
}
const CartContext = createContext<CartContextType | undefined>(undefined);
export function CartProvider({ children }: { children: ReactNode }) {
const [state, dispatch] = useReducer(cartReducer, {
items: [],
isOpen: false,
});
useEffect(() => {
const savedItems = container.cartRepository.load();
if (savedItems.length > 0) {
dispatch({ type: 'RESTORE_ITEMS', payload: savedItems });
}
}, []);
useEffect(() => {
container.cartRepository.save(state.items);
}, [state.items]);
const { totalItems, totalPrice } = getCartTotals(state.items);
const addToCart = (item: NewCartItem) => {
dispatch({ type: 'ADD_ITEM', payload: item });
playAddSound();
const priceLabel =
item.pricingMode === 'weight'
? `${item.pricePerHalfKg ?? item.price} kr / ½ kg`
: `${item.price} kr`;
toast.success(`Added ${item.name} to cart`, {
description: priceLabel,
action: {
label: 'View Cart',
onClick: () => dispatch({ type: 'OPEN_CART' }),
},
});
};
const removeFromCart = (id: string) => {
dispatch({ type: 'REMOVE_ITEM', payload: id });
};
const updateQuantity = (id: string, quantity: number) => {
dispatch({ type: 'UPDATE_QUANTITY', payload: { id, quantity } });
};
const clearCart = () => {
dispatch({ type: 'CLEAR_CART' });
};
const toggleCart = () => {
dispatch({ type: 'TOGGLE_CART' });
};
const openCart = () => {
dispatch({ type: 'OPEN_CART' });
};
const closeCart = () => {
dispatch({ type: 'CLOSE_CART' });
};
return (
<CartContext.Provider
value={{
items: state.items,
isOpen: state.isOpen,
totalItems,
totalPrice,
addToCart,
removeFromCart,
updateQuantity,
clearCart,
toggleCart,
openCart,
closeCart,
}}
>
{children}
</CartContext.Provider>
);
}
export function useCart() {
const context = useContext(CartContext);
if (context === undefined) {
throw new Error('useCart must be used within a CartProvider');
}
return context;
}
@@ -1,53 +0,0 @@
'use client';
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { isRtlLanguage, type Language } from '@/domain/language/entities';
import {
persistLanguage,
resolveInitialLanguage,
} from '@/application/language/language-use-cases';
import { container } from '@/infrastructure/di/container';
interface LanguageContextType {
language: Language;
setLanguage: (lang: Language) => void;
isRtl: boolean;
}
const LanguageContext = createContext<LanguageContextType | undefined>(undefined);
export function LanguageProvider({ children }: { children: ReactNode }) {
const [language, setLanguageState] = useState<Language>('sv');
useEffect(() => {
setLanguageState(resolveInitialLanguage(container.languageRepository));
}, []);
useEffect(() => {
const root = document.documentElement;
root.lang = language;
root.dir = isRtlLanguage(language) ? 'rtl' : 'ltr';
root.dataset.locale = language;
}, [language]);
const setLanguage = (lang: Language) => {
setLanguageState(lang);
persistLanguage(container.languageRepository, lang);
};
return (
<LanguageContext.Provider
value={{ language, setLanguage, isRtl: isRtlLanguage(language) }}
>
{children}
</LanguageContext.Provider>
);
}
export function useLanguage() {
const context = useContext(LanguageContext);
if (context === undefined) {
throw new Error('useLanguage must be used within a LanguageProvider');
}
return context;
}
@@ -1,113 +0,0 @@
'use client';
import React, { createContext, useContext, useReducer, useEffect, ReactNode } from 'react';
import { toast } from 'sonner';
import {
wishlistReducer,
isInWishlist,
getWishlistCount,
} from '@/domain/wishlist/wishlist-domain';
import type { WishlistItem, NewWishlistItem } from '@/domain/wishlist/entities';
import { container } from '@/infrastructure/di/container';
export type { WishlistItem };
interface WishlistContextType {
items: WishlistItem[];
isOpen: boolean;
totalItems: number;
toggleWishlist: (item: NewWishlistItem) => void;
removeFromWishlist: (id: string) => void;
clearWishlist: () => void;
isWishlisted: (id: string) => boolean;
toggleDrawer: () => void;
openWishlist: () => void;
closeWishlist: () => void;
}
const WishlistContext = createContext<WishlistContextType | undefined>(undefined);
export function WishlistProvider({ children }: { children: ReactNode }) {
const [state, dispatch] = useReducer(wishlistReducer, {
items: [],
isOpen: false,
});
useEffect(() => {
const savedItems = container.wishlistRepository.load();
if (savedItems.length > 0) {
dispatch({ type: 'RESTORE_ITEMS', payload: savedItems });
}
}, []);
useEffect(() => {
container.wishlistRepository.save(state.items);
}, [state.items]);
const totalItems = getWishlistCount(state.items);
const toggleWishlist = (item: NewWishlistItem) => {
const wasInList = isInWishlist(state.items, item.id);
dispatch({ type: 'TOGGLE_ITEM', payload: item });
if (wasInList) {
toast.info(`Removed ${item.name} from wishlist`);
} else {
toast.success(`Saved ${item.name} to wishlist`, {
action: {
label: 'View',
onClick: () => dispatch({ type: 'OPEN_DRAWER' }),
},
});
}
};
const removeFromWishlist = (id: string) => {
dispatch({ type: 'REMOVE_ITEM', payload: id });
};
const clearWishlist = () => {
dispatch({ type: 'CLEAR_WISHLIST' });
};
const isWishlisted = (id: string) => isInWishlist(state.items, id);
const toggleDrawer = () => {
dispatch({ type: 'TOGGLE_DRAWER' });
};
const openWishlist = () => {
dispatch({ type: 'OPEN_DRAWER' });
};
const closeWishlist = () => {
dispatch({ type: 'CLOSE_DRAWER' });
};
return (
<WishlistContext.Provider
value={{
items: state.items,
isOpen: state.isOpen,
totalItems,
toggleWishlist,
removeFromWishlist,
clearWishlist,
isWishlisted,
toggleDrawer,
openWishlist,
closeWishlist,
}}
>
{children}
</WishlistContext.Provider>
);
}
export function useWishlist() {
const context = useContext(WishlistContext);
if (context === undefined) {
throw new Error('useWishlist must be used within a WishlistProvider');
}
return context;
}