Replace entire repo content with correct code from /root/shahikitchen-website/

This commit is contained in:
root
2026-06-29 16:22:09 +00:00
parent 57cc67d2d3
commit 50e3a34895
723 changed files with 20055 additions and 26101 deletions
+17
View File
@@ -0,0 +1,17 @@
/** Restaurant contact & persistence keys — domain constants (no framework deps). */
export const RESTAURANT_CONTACT = {
whatsappNumber: '46739381089',
phonePrimary: '031288910',
phoneMobile: '0739381089',
email: 'hello@shahikitchen.se',
website: 'https://shahikitchen.se',
} as const;
export const STORAGE_KEYS = {
cart: 'shahi-kitchen-cart',
wishlist: 'shahi-kitchen-wishlist',
language: 'shahi-kitchen-language',
} as const;
export const PICKUP_LEAD_TIME_MINUTES = 30;
+95
View File
@@ -0,0 +1,95 @@
import {
calculateSweetsWeightTotal,
formatSweetWeightLabel,
} from '../sweets/pricing';
/** Shared order-line model used by cart, pre-order, and table orders. */
export type OrderPricingMode = 'standard' | 'weight';
export interface OrderLine {
id: string;
name: string;
price: number;
quantity: number;
image?: string;
pricingMode?: OrderPricingMode;
pricePerKg?: number;
pricePerHalfKg?: number;
}
export type NewOrderLine = Omit<OrderLine, 'quantity'>;
export function addOrderLine(lines: OrderLine[], item: NewOrderLine): OrderLine[] {
const existing = lines.find((line) => line.id === item.id);
if (existing) {
return lines.map((line) =>
line.id === item.id ? { ...line, quantity: line.quantity + 1 } : line
);
}
return [...lines, { ...item, quantity: 1 }];
}
export function updateOrderLineQuantity(
lines: OrderLine[],
id: string,
quantity: number
): OrderLine[] {
if (quantity <= 0) {
return lines.filter((line) => line.id !== id);
}
return lines.map((line) => (line.id === id ? { ...line, quantity } : line));
}
export function removeOrderLine(lines: OrderLine[], id: string): OrderLine[] {
return lines.filter((line) => line.id !== id);
}
export function calculateLineTotal(line: OrderLine): number {
if (line.pricingMode === 'weight') {
return calculateSweetsWeightTotal(line.quantity);
}
return line.price * line.quantity;
}
export function calculateOrderTotal(lines: OrderLine[]): number {
return lines.reduce((sum, line) => sum + calculateLineTotal(line), 0);
}
export function calculateOrderItemCount(lines: OrderLine[]): number {
return lines.reduce((sum, line) => sum + line.quantity, 0);
}
export function formatOrderLinesForMessage(lines: OrderLine[]): string {
return lines
.map((line) => {
const total = calculateLineTotal(line);
if (line.pricingMode === 'weight') {
const weight = formatSweetWeightLabel(line.quantity);
return `${line.name} (${weight}) — ${total} kr`;
}
return `${line.quantity} × ${line.name}${total} kr`;
})
.join('\n');
}
/** Inquiry format: "Dish Name x Qty - Price kr" */
export function formatOrderLinesForInquiry(lines: OrderLine[]): string {
return lines
.map((line) => {
const total = calculateLineTotal(line);
const qty =
line.pricingMode === 'weight'
? formatSweetWeightLabel(line.quantity)
: String(line.quantity);
return `${line.name} x ${qty} - ${total} kr`;
})
.join('\n');
}
export function formatLineQuantityLabel(line: OrderLine): string {
if (line.pricingMode === 'weight') {
return formatSweetWeightLabel(line.quantity);
}
return String(line.quantity);
}