-
-
+
+
+
+
+
+
+
+
= __('active_orders') ?>
+
= $stats['active_orders'] ?>
+
-
-
-
-
-
-
+
-
-
Existing FAQs
-
-
-
- | Keywords |
- Answer |
- Actions |
-
-
-
-
-
- | = htmlspecialchars($faq['keywords']) ?> |
- = htmlspecialchars($faq['answer']) ?> |
-
-
- |
-
-
-
-
-
-
Recent Chat History (Last 50)
-
-
-
-
- | Time |
- User Message |
- AI Response |
-
-
-
-
-
- | No messages yet. |
-
-
-
-
- | = htmlspecialchars($msg['created_at']) ?> |
- = htmlspecialchars($msg['user_message']) ?> |
- = htmlspecialchars($msg['ai_response']) ?> |
-
-
-
-
-
+
+
+
+
+
+
+
+
= __('ready_orders') ?? 'Ready Orders' ?>
+
= $stats['ready_orders'] ?>
+
+
+
+
+
+
+
+
+
+
+
+
= __('new_customers') ?? 'New Customers' ?>
+
= $stats['new_customers'] ?>
+
+
+
-
-
+
+
+
+
= __('recent_orders') ?? 'Recent Orders' ?>
+
+
+
+
+ | # |
+ = __('customer_name') ?> |
+ = __('total') ?> |
+ = __('status') ?> |
+ = __('payment_status') ?> |
+ = __('actions') ?> |
+
+
+
+
+
+ | = $order['id'] ?> |
+ = $lang === 'ar' ? ($order['customer_name_ar'] ?: $order['customer_name_en']) : $order['customer_name_en'] ?> |
+ = number_format($order['total_price'], 2) ?> |
+ = __($order['status']) ?> |
+ = __($order['payment_status']) ?> |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+ 'secondary',
+ 'processing' => 'primary',
+ 'ready' => 'success',
+ 'delivered' => 'dark',
+ 'cancelled' => 'danger',
+ ][$status] ?? 'info';
+}
+function getPaymentStatusColor($status) {
+ return [
+ 'unpaid' => 'danger',
+ 'partially_paid' => 'warning',
+ 'paid' => 'success',
+ ][$status] ?? 'info';
+}
+require_once __DIR__ . '/includes/footer.php';
+?>
\ No newline at end of file
diff --git a/api/add_customer.php b/api/add_customer.php
new file mode 100644
index 0000000..2aac4e4
--- /dev/null
+++ b/api/add_customer.php
@@ -0,0 +1,37 @@
+ false, 'error' => 'Unauthorized']);
+ exit;
+}
+
+$phone = $_POST['phone'] ?? '';
+$name_en = $_POST['name_en'] ?? '';
+$name_ar = $_POST['name_ar'] ?? '';
+$branch_id = $_SESSION['branch_id'];
+
+if (!$phone || !$name_en) {
+ echo json_encode(['success' => false, 'error' => 'Phone and English Name are required']);
+ exit;
+}
+
+try {
+ $stmt = db()->prepare("INSERT INTO customers (branch_id, phone, name_en, name_ar) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$branch_id, $phone, $name_en, $name_ar]);
+ $customer_id = db()->lastInsertId();
+
+ echo json_encode([
+ 'success' => true,
+ 'customer' => [
+ 'id' => $customer_id,
+ 'phone' => $phone,
+ 'name_en' => $name_en,
+ 'name_ar' => $name_ar
+ ]
+ ]);
+} catch (Exception $e) {
+ echo json_encode(['success' => false, 'error' => $e->getMessage()]);
+}
diff --git a/api/add_customer_redirect.php b/api/add_customer_redirect.php
new file mode 100644
index 0000000..d31a94f
--- /dev/null
+++ b/api/add_customer_redirect.php
@@ -0,0 +1,24 @@
+prepare("INSERT INTO customers (branch_id, phone, name_en, name_ar, email) VALUES (?, ?, ?, ?, ?)");
+ $stmt->execute([$branch_id, $phone, $name_en, $name_ar, $email]);
+ }
+}
+
+header('Location: ../customers.php');
+exit;
diff --git a/api/checkout.php b/api/checkout.php
new file mode 100644
index 0000000..541565a
--- /dev/null
+++ b/api/checkout.php
@@ -0,0 +1,59 @@
+ false, 'error' => 'Unauthorized']);
+ exit;
+}
+
+$input = json_decode(file_get_contents('php://input'), true);
+$customer_id = $input['customer_id'] ?: null;
+$items = $input['items'] ?? [];
+$vat_total = (float)($input['vat_total'] ?? 0);
+$total_price = (float)($input['total_price'] ?? 0);
+$branch_id = $_SESSION['branch_id'];
+$user_id = $_SESSION['user_id'];
+
+if (empty($items)) {
+ echo json_encode(['success' => false, 'error' => 'Cart is empty']);
+ exit;
+}
+
+try {
+ $pdo = db();
+ $pdo->beginTransaction();
+
+ // Recalculate total if not provided correctly, but for now we trust the client-side breakdown
+ // If we wanted to be more secure, we'd fetch prices from DB here.
+
+ $order_number = 'ORD-' . time() . '-' . rand(100, 999);
+
+ $stmt = $pdo->prepare("INSERT INTO orders (branch_id, customer_id, user_id, order_number, total_price, vat_total, status, payment_status)
+ VALUES (?, ?, ?, ?, ?, ?, 'received', 'unpaid')");
+ $stmt->execute([$branch_id, $customer_id, $user_id, $order_number, $total_price, $vat_total]);
+ $order_id = $pdo->lastInsertId();
+
+ $stmt_item = $pdo->prepare("INSERT INTO order_items (order_id, item_id, variant_id, service_id, quantity, unit_price, vat_amount, subtotal)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+ foreach ($items as $item) {
+ $subtotal = ($item['price'] * $item['quantity']);
+ $stmt_item->execute([
+ $order_id,
+ $item['itemId'],
+ $item['variantId'] ?: null,
+ $item['serviceId'],
+ $item['quantity'],
+ $item['price'],
+ $item['vatAmount'] ?: 0,
+ $subtotal
+ ]);
+ }
+
+ $pdo->commit();
+ echo json_encode(['success' => true, 'order_id' => $order_id]);
+} catch (Exception $e) {
+ if (isset($pdo)) $pdo->rollBack();
+ echo json_encode(['success' => false, 'error' => $e->getMessage()]);
+}
\ No newline at end of file
diff --git a/assets/css/custom.css b/assets/css/custom.css
index 50e0502..e08c6ed 100644
--- a/assets/css/custom.css
+++ b/assets/css/custom.css
@@ -1,302 +1,84 @@
+:root {
+ --bs-primary: #3b82f6;
+ --bs-primary-rgb: 59, 130, 246;
+ --bs-success: #10b981;
+ --bs-warning: #f59e0b;
+ --bs-danger: #ef4444;
+}
+
body {
- background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
- background-size: 400% 400%;
- animation: gradient 15s ease infinite;
- color: #212529;
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
- font-size: 14px;
- margin: 0;
- min-height: 100vh;
+ background-color: #f3f4f6;
}
-.main-wrapper {
- display: flex;
- align-items: center;
- justify-content: center;
- min-height: 100vh;
- width: 100%;
- padding: 20px;
- box-sizing: border-box;
- position: relative;
- z-index: 1;
-}
-
-@keyframes gradient {
- 0% {
- background-position: 0% 50%;
- }
- 50% {
- background-position: 100% 50%;
- }
- 100% {
- background-position: 0% 50%;
- }
-}
-
-.chat-container {
- width: 100%;
- max-width: 600px;
- background: rgba(255, 255, 255, 0.85);
- border: 1px solid rgba(255, 255, 255, 0.3);
- border-radius: 20px;
- display: flex;
- flex-direction: column;
- height: 85vh;
- box-shadow: 0 20px 40px rgba(0,0,0,0.2);
- backdrop-filter: blur(15px);
- -webkit-backdrop-filter: blur(15px);
- overflow: hidden;
-}
-
-.chat-header {
- padding: 1.5rem;
- border-bottom: 1px solid rgba(0, 0, 0, 0.05);
- background: rgba(255, 255, 255, 0.5);
- font-weight: 700;
- font-size: 1.1rem;
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.chat-messages {
- flex: 1;
- overflow-y: auto;
- padding: 1.5rem;
- display: flex;
- flex-direction: column;
- gap: 1.25rem;
-}
-
-/* Custom Scrollbar */
-::-webkit-scrollbar {
- width: 6px;
-}
-
-::-webkit-scrollbar-track {
- background: transparent;
-}
-
-::-webkit-scrollbar-thumb {
- background: rgba(255, 255, 255, 0.3);
- border-radius: 10px;
-}
-
-::-webkit-scrollbar-thumb:hover {
- background: rgba(255, 255, 255, 0.5);
-}
-
-.message {
- max-width: 85%;
- padding: 0.85rem 1.1rem;
- border-radius: 16px;
- line-height: 1.5;
- font-size: 0.95rem;
- box-shadow: 0 4px 15px rgba(0,0,0,0.05);
- animation: fadeIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
-}
-
-@keyframes fadeIn {
- from { opacity: 0; transform: translateY(20px) scale(0.95); }
- to { opacity: 1; transform: translateY(0) scale(1); }
-}
-
-.message.visitor {
- align-self: flex-end;
- background: linear-gradient(135deg, #212529 0%, #343a40 100%);
- color: #fff;
- border-bottom-right-radius: 4px;
-}
-
-.message.bot {
- align-self: flex-start;
- background: #ffffff;
- color: #212529;
- border-bottom-left-radius: 4px;
-}
-
-.chat-input-area {
- padding: 1.25rem;
- background: rgba(255, 255, 255, 0.5);
- border-top: 1px solid rgba(0, 0, 0, 0.05);
-}
-
-.chat-input-area form {
- display: flex;
- gap: 0.75rem;
-}
-
-.chat-input-area input {
- flex: 1;
- border: 1px solid rgba(0, 0, 0, 0.1);
- border-radius: 12px;
- padding: 0.75rem 1rem;
- outline: none;
- background: rgba(255, 255, 255, 0.9);
- transition: all 0.3s ease;
-}
-
-.chat-input-area input:focus {
- border-color: #23a6d5;
- box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.2);
-}
-
-.chat-input-area button {
- background: #212529;
- color: #fff;
+.card {
+ border-radius: 1.25rem;
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -2px rgba(0, 0, 0, 0.025);
border: none;
- padding: 0.75rem 1.5rem;
- border-radius: 12px;
- cursor: pointer;
+}
+
+.btn-primary {
+ background-color: var(--bs-primary);
+ border-color: var(--bs-primary);
+ border-radius: 0.75rem;
+}
+
+.btn-primary:hover {
+ background-color: #2563eb;
+ border-color: #2563eb;
+}
+
+.sidebar {
+ background: #111827 !important;
+}
+
+.sidebar .nav-link {
+ font-weight: 500;
+ transition: all 0.2s;
+}
+
+.sidebar .nav-link:hover {
+ background: rgba(255, 255, 255, 0.05);
+}
+
+.sidebar .nav-link.active {
+ background: var(--bs-primary) !important;
+}
+
+.badge {
font-weight: 600;
- transition: all 0.3s ease;
+ padding: 0.5em 1em;
}
-.chat-input-area button:hover {
- background: #000;
- transform: translateY(-2px);
- box-shadow: 0 5px 15px rgba(0,0,0,0.2);
-}
-
-/* Background Animations */
-.bg-animations {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 0;
- overflow: hidden;
- pointer-events: none;
-}
-
-.blob {
- position: absolute;
- width: 500px;
- height: 500px;
- background: rgba(255, 255, 255, 0.2);
- border-radius: 50%;
- filter: blur(80px);
- animation: move 20s infinite alternate cubic-bezier(0.45, 0, 0.55, 1);
-}
-
-.blob-1 {
- top: -10%;
- left: -10%;
- background: rgba(238, 119, 82, 0.4);
-}
-
-.blob-2 {
- bottom: -10%;
- right: -10%;
- background: rgba(35, 166, 213, 0.4);
- animation-delay: -7s;
- width: 600px;
- height: 600px;
-}
-
-.blob-3 {
- top: 40%;
- left: 30%;
- background: rgba(231, 60, 126, 0.3);
- animation-delay: -14s;
- width: 450px;
- height: 450px;
-}
-
-@keyframes move {
- 0% { transform: translate(0, 0) rotate(0deg) scale(1); }
- 33% { transform: translate(150px, 100px) rotate(120deg) scale(1.1); }
- 66% { transform: translate(-50px, 200px) rotate(240deg) scale(0.9); }
- 100% { transform: translate(0, 0) rotate(360deg) scale(1); }
-}
-
-.admin-link {
- font-size: 14px;
- color: #fff;
- text-decoration: none;
- background: rgba(0, 0, 0, 0.2);
- padding: 0.5rem 1rem;
- border-radius: 8px;
- transition: all 0.3s ease;
-}
-
-.admin-link:hover {
- background: rgba(0, 0, 0, 0.4);
- text-decoration: none;
-}
-
-/* Admin Styles */
-.admin-container {
- max-width: 900px;
- margin: 3rem auto;
- padding: 2.5rem;
- background: rgba(255, 255, 255, 0.85);
- backdrop-filter: blur(20px);
- -webkit-backdrop-filter: blur(20px);
- border-radius: 24px;
- box-shadow: 0 20px 50px rgba(0,0,0,0.15);
- border: 1px solid rgba(255, 255, 255, 0.4);
- position: relative;
- z-index: 1;
-}
-
-.admin-container h1 {
- margin-top: 0;
- color: #212529;
- font-weight: 800;
-}
-
-.table {
- width: 100%;
- border-collapse: separate;
- border-spacing: 0 8px;
- margin-top: 1.5rem;
-}
-
-.table th {
- background: transparent;
- border: none;
- padding: 1rem;
- color: #6c757d;
- font-weight: 600;
+.table thead th {
+ background-color: #f9fafb;
text-transform: uppercase;
font-size: 0.75rem;
- letter-spacing: 1px;
+ letter-spacing: 0.05em;
+ color: #6b7280;
+ border-bottom-width: 1px;
}
-.table td {
- background: #fff;
- padding: 1rem;
- border: none;
+.form-control, .form-select {
+ border-radius: 0.75rem;
+ padding: 0.625rem 1rem;
+ border: 1px solid #d1d5db;
+ background-color: #fff;
}
-.table tr td:first-child { border-radius: 12px 0 0 12px; }
-.table tr td:last-child { border-radius: 0 12px 12px 0; }
-
-.form-group {
- margin-bottom: 1.25rem;
+.form-control:focus, .form-select:focus {
+ border-color: var(--bs-primary);
+ box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
}
-.form-group label {
- display: block;
- margin-bottom: 0.5rem;
- font-weight: 600;
- font-size: 0.9rem;
+/* RTL Support for Cairo Font */
+[dir="rtl"] {
+ font-family: 'Cairo', sans-serif !important;
}
-.form-control {
- width: 100%;
- padding: 0.75rem 1rem;
- border: 1px solid rgba(0, 0, 0, 0.1);
- border-radius: 12px;
- background: #fff;
- transition: all 0.3s ease;
- box-sizing: border-box;
+.cursor-pointer {
+ cursor: pointer;
}
-.form-control:focus {
- outline: none;
- border-color: #23a6d5;
- box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.1);
-}
\ No newline at end of file
+.item-card:hover {
+ transform: scale(1.02);
+}
diff --git a/branches.php b/branches.php
new file mode 100644
index 0000000..a3c63b9
--- /dev/null
+++ b/branches.php
@@ -0,0 +1,96 @@
+prepare("INSERT INTO branches (name_en, name_ar, company_id, phone) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$name_en, $name_ar, $company_id, $phone]);
+ header('Location: branches.php');
+ exit;
+ }
+}
+
+// NOW Include header
+$title = 'branches';
+require_once __DIR__ . '/includes/header.php';
+
+$branches = db()->query("SELECT b.*, c.name_en as company_name_en FROM branches b JOIN companies c ON b.company_id = c.id")->fetchAll();
+$companies = db()->query("SELECT * FROM companies")->fetchAll();
+?>
+
+
+
+
+
= __('add_new_branch') ?? 'Add New Branch' ?>
+
+
+
+
+
+
+
+
+
+ | # |
+ = __('name') ?> |
+ = __('company') ?> |
+ = __('phone') ?> |
+
+
+
+
+
+ | = $b['id'] ?> |
+ = $lang === 'ar' ? ($b['name_ar'] ?: $b['name_en']) : $b['name_en'] ?> |
+ = $b['company_name_en'] ?> |
+ = $b['phone'] ?> |
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/customers.php b/customers.php
new file mode 100644
index 0000000..4a0994e
--- /dev/null
+++ b/customers.php
@@ -0,0 +1,110 @@
+prepare($sql);
+$stmt->execute($params);
+$customers = $stmt->fetchAll();
+
+?>
+
+
+
+
= __('customers_list') ?? 'Customers List' ?>
+
+
+
+
+
+
+
+
+
+
+ | # |
+ = __('name') ?> |
+ = __('phone') ?> |
+ = __('email') ?> |
+ = __('date') ?> |
+ = __('actions') ?> |
+
+
+
+
+
+ | = $c['id'] ?> |
+
+ = $lang === 'ar' ? ($c['name_ar'] ?: $c['name_en']) : $c['name_en'] ?>
+ |
+ = $c['phone'] ?> |
+ = $c['email'] ?: '-' ?> |
+ = date('d/m/Y', strtotime($c['created_at'])) ?> |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/db/migrations/01_initial_schema.sql b/db/migrations/01_initial_schema.sql
new file mode 100644
index 0000000..dd95da1
--- /dev/null
+++ b/db/migrations/01_initial_schema.sql
@@ -0,0 +1,129 @@
+CREATE TABLE IF NOT EXISTS companies (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name_en VARCHAR(255) NOT NULL,
+ name_ar VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS branches (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ company_id INT NOT NULL,
+ name_en VARCHAR(255) NOT NULL,
+ name_ar VARCHAR(255) NOT NULL,
+ address_en TEXT,
+ address_ar TEXT,
+ phone VARCHAR(20),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS users (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ branch_id INT,
+ company_id INT,
+ username VARCHAR(50) NOT NULL UNIQUE,
+ password_hash VARCHAR(255) NOT NULL,
+ full_name_en VARCHAR(255),
+ full_name_ar VARCHAR(255),
+ role ENUM('super_admin', 'branch_manager', 'cashier') DEFAULT 'cashier',
+ email VARCHAR(100),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE SET NULL,
+ FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE SET NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS customers (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ branch_id INT,
+ name_en VARCHAR(255),
+ name_ar VARCHAR(255),
+ phone VARCHAR(20) NOT NULL,
+ email VARCHAR(100),
+ address_en TEXT,
+ address_ar TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE SET NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS items (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name_en VARCHAR(255) NOT NULL,
+ name_ar VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS services (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name_en VARCHAR(255) NOT NULL,
+ name_ar VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS prices (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ branch_id INT NOT NULL,
+ item_id INT NOT NULL,
+ service_id INT NOT NULL,
+ price DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ UNIQUE KEY (branch_id, item_id, service_id),
+ FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE CASCADE,
+ FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE,
+ FOREIGN KEY (service_id) REFERENCES services(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS orders (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ branch_id INT NOT NULL,
+ customer_id INT,
+ user_id INT,
+ order_number VARCHAR(50) UNIQUE,
+ status ENUM('received', 'processing', 'ready', 'delivered', 'cancelled') DEFAULT 'received',
+ total_price DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
+ payment_status ENUM('unpaid', 'partially_paid', 'paid') DEFAULT 'unpaid',
+ notes TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (branch_id) REFERENCES branches(id),
+ FOREIGN KEY (customer_id) REFERENCES customers(id),
+ FOREIGN KEY (user_id) REFERENCES users(id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS order_items (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ order_id INT NOT NULL,
+ item_id INT NOT NULL,
+ service_id INT NOT NULL,
+ quantity INT DEFAULT 1,
+ unit_price DECIMAL(10, 2) NOT NULL,
+ subtotal DECIMAL(10, 2) NOT NULL,
+ FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,
+ FOREIGN KEY (item_id) REFERENCES items(id),
+ FOREIGN KEY (service_id) REFERENCES services(id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS payments (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ order_id INT NOT NULL,
+ amount DECIMAL(10, 2) NOT NULL,
+ payment_method ENUM('cash', 'card', 'transfer') DEFAULT 'cash',
+ transaction_id VARCHAR(100),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- Initial data seed
+INSERT INTO companies (name_en, name_ar) VALUES ('Laundry Brand', 'علامة غسيل');
+INSERT INTO branches (company_id, name_en, name_ar) VALUES (1, 'Main Branch', 'الفرع الرئيسي');
+INSERT INTO users (branch_id, company_id, username, password_hash, full_name_en, full_name_ar, role)
+VALUES (1, 1, 'admin', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'Admin', 'مدير', 'super_admin');
+-- password is 'password'
+
+INSERT INTO items (name_en, name_ar) VALUES ('Shirt', 'قميص'), ('Suit', 'بدلة'), ('T-Shirt', 'تيشيرت'), ('Pants', 'بنطال'), ('Dress', 'فستان');
+INSERT INTO services (name_en, name_ar) VALUES ('Wash Only', 'غسيل فقط'), ('Iron Only', 'كوي فقط'), ('Wash & Iron', 'غسيل وكوي'), ('Dry Clean', 'تنظيف جاف');
+
+-- Default prices for Main Branch
+INSERT INTO prices (branch_id, item_id, service_id, price) VALUES
+(1, 1, 1, 5.00), (1, 1, 2, 3.00), (1, 1, 3, 7.00),
+(1, 2, 4, 30.00),
+(1, 3, 3, 5.00),
+(1, 4, 3, 6.00);
diff --git a/db/migrations/02_update_items.sql b/db/migrations/02_update_items.sql
new file mode 100644
index 0000000..27c9118
--- /dev/null
+++ b/db/migrations/02_update_items.sql
@@ -0,0 +1,37 @@
+-- Create categories table
+CREATE TABLE IF NOT EXISTS categories (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name_en VARCHAR(255) NOT NULL,
+ name_ar VARCHAR(255) NOT NULL,
+ image_url VARCHAR(255),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- Add new columns to items table
+ALTER TABLE items ADD COLUMN category_id INT AFTER id;
+ALTER TABLE items ADD COLUMN image_url VARCHAR(255) AFTER name_ar;
+ALTER TABLE items ADD COLUMN vat_percent DECIMAL(5, 2) DEFAULT 0.00 AFTER image_url;
+
+-- Add foreign key for category
+ALTER TABLE items ADD CONSTRAINT fk_item_category FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL;
+
+-- Create item_variants table (interpreting "aspire table" as "a separate table for variants")
+CREATE TABLE IF NOT EXISTS item_variants (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ item_id INT NOT NULL,
+ name_en VARCHAR(255) NOT NULL,
+ name_ar VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- Update prices table to include variant_id (optional, making it more flexible)
+ALTER TABLE prices ADD COLUMN variant_id INT AFTER item_id;
+ALTER TABLE prices ADD CONSTRAINT fk_price_variant FOREIGN KEY (variant_id) REFERENCES item_variants(id) ON DELETE CASCADE;
+
+-- Insert default categories
+INSERT INTO categories (name_en, name_ar) VALUES
+('Men', 'رجال'),
+('Women', 'نساء'),
+('Kids', 'أطفال'),
+('Bed Sheets', 'ملاءات السرير');
diff --git a/db/migrations/03_update_orders.sql b/db/migrations/03_update_orders.sql
new file mode 100644
index 0000000..8a64221
--- /dev/null
+++ b/db/migrations/03_update_orders.sql
@@ -0,0 +1,7 @@
+-- Update orders table for VAT
+ALTER TABLE orders ADD COLUMN vat_total DECIMAL(10, 2) DEFAULT 0.00 AFTER total_price;
+
+-- Update order_items table for variants and VAT
+ALTER TABLE order_items ADD COLUMN variant_id INT AFTER item_id;
+ALTER TABLE order_items ADD COLUMN vat_amount DECIMAL(10, 2) DEFAULT 0.00 AFTER unit_price;
+ALTER TABLE order_items ADD CONSTRAINT fk_order_item_variant FOREIGN KEY (variant_id) REFERENCES item_variants(id) ON DELETE SET NULL;
diff --git a/db/migrations/04_fix_prices_key.sql b/db/migrations/04_fix_prices_key.sql
new file mode 100644
index 0000000..f28d248
--- /dev/null
+++ b/db/migrations/04_fix_prices_key.sql
@@ -0,0 +1,3 @@
+-- Fix prices table unique key to include variant_id
+ALTER TABLE prices DROP INDEX branch_id;
+ALTER TABLE prices ADD UNIQUE KEY unique_price (branch_id, item_id, variant_id, service_id);
diff --git a/includes/footer.php b/includes/footer.php
new file mode 100644
index 0000000..1469170
--- /dev/null
+++ b/includes/footer.php
@@ -0,0 +1,8 @@
+
+
+