Index: backend/01.init.sql
===================================================================
--- backend/01.init.sql	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/01.init.sql	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -333,11 +333,11 @@
 
 -- DML
-INSERT INTO users(id, email, password, phone_number, street, city)
-VALUES
-    (1, 'test@hotmail.com', 'password1', '070003005', 'Mladinska 3', 'Strumica'),
-    (2, 'test2@hotmail.com', 'password2', '070001002', 'Marsal Tito 10', 'Strumica'),
-    (3, 'test3@hotmail.com', 'password1', '070003003', 'Mladinska 5', 'Strumica'),
-    (4, 'test4@hotmail.com', 'password2', '070004004', 'Marsal Tito 11', 'Strumica'),
-    (5, 'test5@hotmail.com', 'password1', '070005005', 'Mladinska 12', 'Strumica');
+INSERT INTO users(id, email, password, phone_number, street, city) -- password1
+VALUES
+    (1, 'test@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070003005', 'Mladinska 3', 'Strumica'),
+    (2, 'test2@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070001002', 'Marsal Tito 10', 'Strumica'),
+    (3, 'test3@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070003003', 'Mladinska 5', 'Strumica'),
+    (4, 'test4@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070004004', 'Marsal Tito 11', 'Strumica'),
+    (5, 'test5@hotmail.com', '$2a$10$rliIgXfgZgT1ljzxf.3NjeF1hx63s30xKfUsKjeUYA8jL/GXA1Jsy', '070005005', 'Mladinska 12', 'Strumica');
 
 INSERT INTO employees(user_id, net_salary, gross_salary)
@@ -598,47 +598,43 @@
 
 -- ANALYTIC: Revenue by shift period (dynamic monthly view)
-DO
-$$
-DECLARE
-dynamic_sql text;
-    shift_columns text;
-BEGIN
-    shift_columns := (
-        SELECT string_agg(
-            format('SUM(CASE WHEN o.datetime::time BETWEEN ''%s'' AND ''%s'' THEN COALESCE(oi.quantity * oi.price, 0) ELSE 0 END) AS "%sto%s"',
-                   t.start_time, t.end_time,
-                   REPLACE(t.start_time::text, ':', ''),
-                   REPLACE(t.end_time::text, ':', '')),
-            ', '
-        )
-        FROM (
-            SELECT DISTINCT start_time, end_time
-            FROM shifts
-            ORDER BY start_time, end_time
-        ) AS t
-    );
-
-    dynamic_sql := format(
-        'DROP VIEW IF EXISTS revenue_by_shift_period;
-        CREATE VIEW revenue_by_shift_period AS
-        SELECT
-            TO_CHAR(period_date, ''YYYY-MM'') as period,
-            %s
-        FROM generate_series(
-            date_trunc(''month'', CURRENT_DATE - INTERVAL ''12 months''),
-            date_trunc(''month'', CURRENT_DATE),
-            ''1 month''::interval
-        ) period_date
-        LEFT JOIN orders o ON DATE_TRUNC(''month'', o.datetime) = period_date
-        LEFT JOIN order_items oi ON o.id = oi.order_id
-        GROUP BY period_date
-        ORDER BY period_date;',
-        shift_columns
-    );
-
-    RAISE NOTICE 'Dynamic SQL: %', dynamic_sql;
-EXECUTE dynamic_sql;
-END
-$$;
+
+
+CREATE OR REPLACE VIEW v_revenue_by_shift_period AS
+
+-- CTE to get all unique shift start and end times from your shifts table
+WITH distinct_shift_periods AS (
+    SELECT DISTINCT
+        start_time::time AS start_t,
+        end_time::time AS end_t
+    FROM
+        shifts
+)
+
+-- Main query to calculate revenue
+SELECT
+    -- 1. The month of the order, e.g., '2025-08'
+    TO_CHAR(o.datetime, 'YYYY-MM') AS period,
+
+    -- 2. The shift period string, e.g., '08:00:00-16:00:00'
+    dsp.start_t::text || '-' || dsp.end_t::text AS shift_period,
+
+    -- 3. The total revenue for that shift period within that month
+    SUM(oi.price * oi.quantity) AS total_revenue
+FROM
+    orders o
+        JOIN
+    order_items oi ON o.id = oi.order_id
+-- Join each order to a shift period if its timestamp's time falls within the start and end times
+        JOIN
+    distinct_shift_periods dsp ON o.datetime::time >= dsp.start_t AND o.datetime::time < dsp.end_t
+GROUP BY
+    period,
+    shift_period
+ORDER BY
+    period DESC,
+    shift_period ASC;
+
+SELECT * FROM v_revenue_by_shift_period;
+
 
 -- ANALYTIC: Revenue split (Online vs Tab) for a date range (by order date)
@@ -710,4 +706,15 @@
 ORDER BY period DESC, sr.shift_revenue DESC;
 
+SELECT setval('public.users_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.users;
+SELECT setval('public.staff_roles_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.staff_roles;
+SELECT setval('public.shifts_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.shifts;
+SELECT setval('public.assignments_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.assignments;
+SELECT setval('public.reservations_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.reservations;
+SELECT setval('public.frontstaff_managed_reservations_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.frontstaff_managed_reservations;
+SELECT setval('public.categories_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.categories;
+SELECT setval('public.products_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.products;
+SELECT setval('public.orders_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.orders;
+SELECT setval('public.order_items_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.order_items;
+SELECT setval('public.payments_id_seq', COALESCE(MAX(id + 1), 1), false) FROM public.payments;
 
 COMMIT;
Index: backend/src/main/java/finki/db/tasty_tabs/entity/Product.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/entity/Product.java	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/src/main/java/finki/db/tasty_tabs/entity/Product.java	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -30,6 +30,5 @@
     private String taxClass;
 
-//    @Column(length = 1024)
-    @Transient
+    @Column(length = 1024)
     private String description = "";
 
Index: backend/src/main/java/finki/db/tasty_tabs/repository/AnalyticsReadRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/AnalyticsReadRepository.java	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/src/main/java/finki/db/tasty_tabs/repository/AnalyticsReadRepository.java	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -205,5 +205,5 @@
     public List<Map<String, Object>> revenueByShiftPeriodView() {
         // dynamic columns -> return as list of maps
-        return jdbc.queryForList("SELECT * FROM revenue_by_shift_period");
+        return jdbc.queryForList("SELECT * FROM v_revenue_by_shift_period");
     }
 
Index: backend/src/main/java/finki/db/tasty_tabs/repository/AssignmentRepository.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/repository/AssignmentRepository.java	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/src/main/java/finki/db/tasty_tabs/repository/AssignmentRepository.java	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -12,3 +12,4 @@
 
     Optional<Assignment> findFirstByEmployee_IdOrderByShiftStartAsc(Long employeeId);
+    Optional<Assignment> findFirstByEmployee_IdAndClockOutTimeNullOrderByShiftStartAsc(Long employeeId);
 }
Index: backend/src/main/java/finki/db/tasty_tabs/service/impl/EmployeeServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/EmployeeServiceImpl.java	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/src/main/java/finki/db/tasty_tabs/service/impl/EmployeeServiceImpl.java	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -49,5 +49,5 @@
     @Override
     public AssignmentDto getNextShiftForEmployee(Long employeeId) {
-        Assignment assignment = assignmentRepository.findFirstByEmployee_IdOrderByShiftStartAsc(employeeId).orElse(null);
+        Assignment assignment = assignmentRepository.findFirstByEmployee_IdAndClockOutTimeNullOrderByShiftStartAsc(employeeId).orElse(null);
 
         if (assignment == null) {
Index: backend/src/main/java/finki/db/tasty_tabs/service/impl/PaymentServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/PaymentServiceImpl.java	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/src/main/java/finki/db/tasty_tabs/service/impl/PaymentServiceImpl.java	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -12,4 +12,5 @@
 import finki.db.tasty_tabs.web.dto.CreatePaymentDto;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import jakarta.transaction.Transactional;
@@ -18,4 +19,5 @@
 import java.util.List;
 
+@Slf4j
 @Service
 @RequiredArgsConstructor
@@ -30,4 +32,5 @@
     @Transactional
     public Payment createPayment(CreatePaymentDto dto) {
+        log.info("Creating payment for orderId: {}", dto.orderId());
         Order order = orderRepository.findById(dto.orderId())
                 .orElseThrow(() -> new OrderNotFoundException(dto.orderId()));
Index: backend/src/main/java/finki/db/tasty_tabs/service/impl/ProductServiceImpl.java
===================================================================
--- backend/src/main/java/finki/db/tasty_tabs/service/impl/ProductServiceImpl.java	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/src/main/java/finki/db/tasty_tabs/service/impl/ProductServiceImpl.java	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -116,4 +116,5 @@
             productTmp.setTaxClass(dto.taxClass());
         }
+
         productTmp.setCategory(categoryService.findById(dto.categoryId()));
         productTmp.setDescription(dto.description());
Index: backend/src/main/resources/application.properties
===================================================================
--- backend/src/main/resources/application.properties	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ backend/src/main/resources/application.properties	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -1,7 +1,7 @@
 spring.application.name=Tasty Tabs
-#spring.datasource.url=jdbc:postgresql://localhost:5434/db_202425z_va_prj_tasty_tabs
-#spring.datasource.username=db_202425z_va_prj_tasty_tabs_owner
-#spring.datasource.password=99e003badb51
-spring.profiles.active=test
+spring.datasource.url=jdbc:postgresql://localhost:5434/db_202425z_va_prj_tasty_tabs
+spring.datasource.username=db_202425z_va_prj_tasty_tabs_owner
+spring.datasource.password=99e003badb51
+#spring.profiles.active=dev
 springdoc.api-docs.enabled=true
 springdoc.swagger-ui.enabled=true
Index: frontend/package-lock.json
===================================================================
--- frontend/package-lock.json	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/package-lock.json	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -16,4 +16,5 @@
         "react-hook-form": "^7.62.0",
         "react-router-dom": "^7.8.2",
+        "recharts": "^3.1.2",
         "tailwindcss": "^4.1.12",
         "zod": "^4.1.1"
@@ -1072,4 +1073,30 @@
       }
     },
+    "node_modules/@reduxjs/toolkit": {
+      "version": "2.8.2",
+      "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.2.tgz",
+      "integrity": "sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A==",
+      "license": "MIT",
+      "dependencies": {
+        "@standard-schema/spec": "^1.0.0",
+        "@standard-schema/utils": "^0.3.0",
+        "immer": "^10.0.3",
+        "redux": "^5.0.1",
+        "redux-thunk": "^3.1.0",
+        "reselect": "^5.1.0"
+      },
+      "peerDependencies": {
+        "react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
+        "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
+      },
+      "peerDependenciesMeta": {
+        "react": {
+          "optional": true
+        },
+        "react-redux": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@rolldown/pluginutils": {
       "version": "1.0.0-beta.32",
@@ -1338,4 +1365,10 @@
         "win32"
       ]
+    },
+    "node_modules/@standard-schema/spec": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
+      "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
+      "license": "MIT"
     },
     "node_modules/@standard-schema/utils": {
@@ -1652,4 +1685,67 @@
       }
     },
+    "node_modules/@types/d3-array": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
+      "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-color": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
+      "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-ease": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
+      "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-interpolate": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
+      "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/d3-color": "*"
+      }
+    },
+    "node_modules/@types/d3-path": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
+      "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-scale": {
+      "version": "4.0.9",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
+      "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/d3-time": "*"
+      }
+    },
+    "node_modules/@types/d3-shape": {
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
+      "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/d3-path": "*"
+      }
+    },
+    "node_modules/@types/d3-time": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
+      "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-timer": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
+      "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
+      "license": "MIT"
+    },
     "node_modules/@types/estree": {
       "version": "1.0.8",
@@ -1669,5 +1765,5 @@
       "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.11.tgz",
       "integrity": "sha512-lr3jdBw/BGj49Eps7EvqlUaoeA0xpj3pc0RoJkHpYaCHkVK7i28dKyImLQb3JVlqs3aYSXf7qYuWOW/fgZnTXQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "MIT",
       "dependencies": {
@@ -1684,4 +1780,10 @@
         "@types/react": "^19.0.0"
       }
+    },
+    "node_modules/@types/use-sync-external-store": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
+      "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
+      "license": "MIT"
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
@@ -2191,4 +2293,13 @@
       }
     },
+    "node_modules/clsx": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+      "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/color-convert": {
       "version": "2.0.1",
@@ -2265,6 +2376,127 @@
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
       "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
-      "dev": true,
+      "devOptional": true,
       "license": "MIT"
+    },
+    "node_modules/d3-array": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+      "license": "ISC",
+      "dependencies": {
+        "internmap": "1 - 2"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-color": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+      "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-ease": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+      "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-format": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-interpolate": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-color": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-path": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-scale": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-array": "2.10.0 - 3",
+        "d3-format": "1 - 3",
+        "d3-interpolate": "1.2.0 - 3",
+        "d3-time": "2.1.1 - 3",
+        "d3-time-format": "2 - 4"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-shape": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-path": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-time": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+      "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-array": "2 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-time-format": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+      "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-time": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-timer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+      "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/debug": {
@@ -2285,4 +2517,10 @@
         }
       }
+    },
+    "node_modules/decimal.js-light": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
+      "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
+      "license": "MIT"
     },
     "node_modules/deep-is": {
@@ -2389,4 +2627,14 @@
         "node": ">= 0.4"
       }
+    },
+    "node_modules/es-toolkit": {
+      "version": "1.39.10",
+      "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.10.tgz",
+      "integrity": "sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w==",
+      "license": "MIT",
+      "workspaces": [
+        "docs",
+        "benchmarks"
+      ]
     },
     "node_modules/esbuild": {
@@ -2632,4 +2880,10 @@
       }
     },
+    "node_modules/eventemitter3": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+      "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+      "license": "MIT"
+    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
@@ -2973,4 +3227,14 @@
       }
     },
+    "node_modules/immer": {
+      "version": "10.1.3",
+      "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.3.tgz",
+      "integrity": "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==",
+      "license": "MIT",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/immer"
+      }
+    },
     "node_modules/import-fresh": {
       "version": "3.3.1",
@@ -2998,4 +3262,13 @@
       "engines": {
         "node": ">=0.8.19"
+      }
+    },
+    "node_modules/internmap": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+      "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
       }
     },
@@ -3766,4 +4039,34 @@
       }
     },
+    "node_modules/react-is": {
+      "version": "19.1.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz",
+      "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==",
+      "license": "MIT",
+      "peer": true
+    },
+    "node_modules/react-redux": {
+      "version": "9.2.0",
+      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
+      "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/use-sync-external-store": "^0.0.6",
+        "use-sync-external-store": "^1.4.0"
+      },
+      "peerDependencies": {
+        "@types/react": "^18.2.25 || ^19",
+        "react": "^18.0 || ^19",
+        "redux": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        },
+        "redux": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/react-refresh": {
       "version": "0.17.0",
@@ -3813,4 +4116,52 @@
         "react-dom": ">=18"
       }
+    },
+    "node_modules/recharts": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.1.2.tgz",
+      "integrity": "sha512-vhNbYwaxNbk/IATK0Ki29k3qvTkGqwvCgyQAQ9MavvvBwjvKnMTswdbklJpcOAoMPN/qxF3Lyqob0zO+ZXkZ4g==",
+      "license": "MIT",
+      "dependencies": {
+        "@reduxjs/toolkit": "1.x.x || 2.x.x",
+        "clsx": "^2.1.1",
+        "decimal.js-light": "^2.5.1",
+        "es-toolkit": "^1.39.3",
+        "eventemitter3": "^5.0.1",
+        "immer": "^10.1.1",
+        "react-redux": "8.x.x || 9.x.x",
+        "reselect": "5.1.1",
+        "tiny-invariant": "^1.3.3",
+        "use-sync-external-store": "^1.2.2",
+        "victory-vendor": "^37.0.2"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+        "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+        "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/redux": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
+      "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
+      "license": "MIT"
+    },
+    "node_modules/redux-thunk": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
+      "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
+      "license": "MIT",
+      "peerDependencies": {
+        "redux": "^5.0.0"
+      }
+    },
+    "node_modules/reselect": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
+      "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
+      "license": "MIT"
     },
     "node_modules/resolve-from": {
@@ -4023,4 +4374,10 @@
       }
     },
+    "node_modules/tiny-invariant": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+      "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+      "license": "MIT"
+    },
     "node_modules/tinyglobby": {
       "version": "0.2.14",
@@ -4184,4 +4541,35 @@
       "dependencies": {
         "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/use-sync-external-store": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+      "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/victory-vendor": {
+      "version": "37.3.6",
+      "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz",
+      "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==",
+      "license": "MIT AND ISC",
+      "dependencies": {
+        "@types/d3-array": "^3.0.3",
+        "@types/d3-ease": "^3.0.0",
+        "@types/d3-interpolate": "^3.0.1",
+        "@types/d3-scale": "^4.0.2",
+        "@types/d3-shape": "^3.1.0",
+        "@types/d3-time": "^3.0.0",
+        "@types/d3-timer": "^3.0.0",
+        "d3-array": "^3.1.6",
+        "d3-ease": "^3.0.1",
+        "d3-interpolate": "^3.0.1",
+        "d3-scale": "^4.0.2",
+        "d3-shape": "^3.1.0",
+        "d3-time": "^3.0.0",
+        "d3-timer": "^3.0.1"
       }
     },
Index: frontend/package.json
===================================================================
--- frontend/package.json	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/package.json	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -18,4 +18,5 @@
     "react-hook-form": "^7.62.0",
     "react-router-dom": "^7.8.2",
+    "recharts": "^3.1.2",
     "tailwindcss": "^4.1.12",
     "zod": "^4.1.1"
Index: frontend/src/App.tsx
===================================================================
--- frontend/src/App.tsx	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/App.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -28,4 +28,5 @@
 import { MyReservationsPage } from './pages/public/MyReservationsPage';
 import { MyOrdersPage } from './pages/public/MyOrdersPage';
+import { AnalyticsPage } from './pages/AnalyticsPage';
 
 // Admin Layout
@@ -68,4 +69,8 @@
                             <Route index element={<DashboardPage />} />
                         </Route>
+                        <Route path="analytics" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER]} />}>
+                            <Route index element={<AnalyticsPage />} />
+                        </Route>
+
                         <Route path="orders" element={<ProtectedRoute allowedRoles={[ROLES.MANAGER, ROLES.FRONT_STAFF, ROLES.BACK_STAFF]} />}>
                             <Route index element={<OrdersPage />} />
Index: frontend/src/api/analyticsRepository.ts
===================================================================
--- frontend/src/api/analyticsRepository.ts	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/api/analyticsRepository.ts	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,105 @@
+// src/api/analyticsRepository.ts
+import axiosClient from "./axiosClient";
+import type {
+  DailyOpsDto,
+  TopProductDto,
+  ServerPerformanceDto,
+  ManagerShiftAboveAvgDto,
+  MonthlyRevenueVsLaborDto,
+  RevenueSplitDto,
+  AnalyticsByChannelResponse,
+} from "../types/api";
+
+const getISODateString = (date: Date) => date.toISOString().split("T")[0];
+
+export const analyticsRepository = {
+  /**
+   * Fetches daily operational summary for the last X days.
+   * @param days The number of past days to include (default 30).
+   */
+  getDailyOps: async (days: number = 30): Promise<DailyOpsDto[]> => {
+    const { data } = await axiosClient.get("/analytics/daily-ops", {
+      params: { days },
+    });
+    return data;
+  },
+
+  /**
+   * Fetches the top-selling products.
+   * @param days The number of past days to analyze (default 90).
+   * @param limit The number of products to return (default 10).
+   */
+  getTopProducts: async (
+    days: number = 90,
+    limit: number = 5,
+  ): Promise<TopProductDto[]> => {
+    const { data } = await axiosClient.get("/analytics/top-products", {
+      params: { days, limit },
+    });
+    return data;
+  },
+
+  /**
+   * Fetches performance metrics for all servers.
+   */
+  getServerPerformance: async (): Promise<ServerPerformanceDto[]> => {
+    const { data } = await axiosClient.get("/analytics/servers/performance");
+    return data;
+  },
+
+  /**
+   * Fetches revenue split between different order types (e.g., ONLINE, TAB) for a date range.
+   */
+  getRevenueSplit: async (): Promise<RevenueSplitDto[]> => {
+    const to = new Date();
+    const from = new Date();
+    from.setDate(to.getDate() - 30); // Default to last 30 days
+
+    const params = { from: getISODateString(from), to: getISODateString(to) };
+    const { data } = await axiosClient.get("/analytics/revenue-split", {
+      params,
+    });
+    return data;
+  },
+
+  /**
+   * Fetches a monthly comparison of total revenue vs. total labor cost.
+   */
+  getMonthlyRevenueVsLabor: async (): Promise<MonthlyRevenueVsLaborDto[]> => {
+    const { data } = await axiosClient.get(
+      "/analytics/monthly-revenue-vs-labor",
+    );
+    return data;
+  },
+
+  /**
+   * Fetches shifts managed by managers that performed above the monthly average.
+   */
+  getManagersShiftsAboveAvg: async (): Promise<ManagerShiftAboveAvgDto[]> => {
+    const { data } = await axiosClient.get(
+      "/analytics/managers/shifts-above-avg",
+    );
+    return data;
+  },
+
+  /**
+   * Fetches revenue grouped by shift periods (e.g., Morning, Afternoon, Evening).
+   * The backend returns a generic structure that we will handle dynamically.
+   */
+  getRevenueByShiftPeriod: async (): Promise<Record<string, any>[]> => {
+    const { data } = await axiosClient.get(
+      "/analytics/revenue-by-shift-period",
+    );
+    return data;
+  },
+
+  getRevenueByChannel: async (params: {
+    from: string;
+    to: string;
+  }): Promise<AnalyticsByChannelResponse> => {
+    const { data } = await axiosClient.get("/analytics/reveunueByChannel", {
+      params,
+    });
+    return data;
+  },
+};
Index: frontend/src/api/paymentRepository.ts
===================================================================
--- frontend/src/api/paymentRepository.ts	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/api/paymentRepository.ts	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,10 @@
+// src/api/paymentRepository.ts
+import axiosClient from "./axiosClient";
+import type { CreatePaymentDto } from "../types/api";
+
+export const paymentRepository = {
+  createPayment: async (paymentData: CreatePaymentDto): Promise<any> => {
+    const { data } = await axiosClient.post("/payments", paymentData);
+    return data;
+  },
+};
Index: frontend/src/components/Navbar.tsx
===================================================================
--- frontend/src/components/Navbar.tsx	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/components/Navbar.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -12,5 +12,7 @@
     { path: '/admin/employees', label: 'Employees' },
     { path: '/admin/assignments', label: 'Assignments' },
+    { path: '/admin/analytics', label: 'Analytics' }, // New Link
 ];
+
 
 
Index: frontend/src/components/analytics/ManagerPerformanceTable.tsx
===================================================================
--- frontend/src/components/analytics/ManagerPerformanceTable.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/ManagerPerformanceTable.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,46 @@
+// src/components/analytics/ManagerPerformanceTable.tsx
+import { useEffect, useState } from 'react';
+import type { ManagerShiftAboveAvgDto } from '../../types/api';
+import { analyticsRepository } from '../../api/analyticsRepository';
+
+export const ManagerPerformanceTable = () => {
+    const [data, setData] = useState<ManagerShiftAboveAvgDto[]>([]);
+    const [loading, setLoading] = useState(true);
+
+    useEffect(() => {
+        analyticsRepository.getManagersShiftsAboveAvg()
+            .then(setData)
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, []);
+
+    if (loading) return <p>Loading manager performance...</p>;
+
+    return (
+        <div className="bg-white p-6 rounded-lg shadow-md">
+            <h3 className="text-xl font-semibold mb-4">Manager Shifts Above Average Revenue</h3>
+            <div className="overflow-x-auto">
+                <table className="min-w-full">
+                    <thead>
+                        <tr>
+                            <th className="py-2 text-left">Manager</th>
+                            <th className="py-2 text-left">Shift Date</th>
+                            <th className="py-2 text-right">Shift Revenue</th>
+                            <th className="py-2 text-right">Average Revenue</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {data.map((shift, i) => (
+                            <tr key={i} className="border-t">
+                                <td className="py-2">{shift.manager_email}</td>
+                                <td className="py-2">{new Date(shift.shift_date).toLocaleDateString()}</td>
+                                <td className="py-2 text-right font-bold text-green-600">${shift.shift_revenue.toFixed(2)}</td>
+                                <td className="py-2 text-right text-gray-600">${shift.avg_revenue_per_shift.toFixed(2)}</td>
+                            </tr>
+                        ))}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    );
+};
Index: frontend/src/components/analytics/MonthlyRevenueLaborChart.tsx
===================================================================
--- frontend/src/components/analytics/MonthlyRevenueLaborChart.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/MonthlyRevenueLaborChart.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,36 @@
+// src/components/analytics/MonthlyRevenueLaborChart.tsx
+import { useEffect, useState } from 'react';
+import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
+import type { MonthlyRevenueVsLaborDto } from '../../types/api';
+import { analyticsRepository } from '../../api/analyticsRepository';
+
+export const MonthlyRevenueLaborChart = () => {
+    const [data, setData] = useState<MonthlyRevenueVsLaborDto[]>([]);
+    const [loading, setLoading] = useState(true);
+
+    useEffect(() => {
+        analyticsRepository.getMonthlyRevenueVsLabor()
+            .then(setData)
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, []);
+
+    if (loading) return <p>Loading monthly performance...</p>;
+
+    return (
+        <div className="bg-white p-6 rounded-lg shadow-md h-[400px]">
+            <h3 className="text-xl font-semibold mb-4">Monthly Revenue vs. Labor Cost</h3>
+            <ResponsiveContainer width="100%" height="90%">
+                <BarChart data={data}>
+                    <CartesianGrid strokeDasharray="3 3" />
+                    <XAxis dataKey="period" />
+                    <YAxis />
+                    <Tooltip formatter={(value: number) => `$${value.toFixed(2)}`} />
+                    <Legend />
+                    <Bar dataKey="total_revenue" fill="#8884d8" name="Revenue" />
+                    <Bar dataKey="total_labor_cost" fill="#82ca9d" name="Labor Cost" />
+                </BarChart>
+            </ResponsiveContainer>
+        </div>
+    );
+};
Index: frontend/src/components/analytics/RevenueByChannelChart.tsx
===================================================================
--- frontend/src/components/analytics/RevenueByChannelChart.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/RevenueByChannelChart.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,118 @@
+// src/components/analytics/RevenueByChannelChart.tsx
+import { useEffect, useState, useMemo, useCallback } from 'react';
+import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
+import type { AnalyticsByChannelResponse } from '../../types/api';
+import { analyticsRepository } from '../../api/analyticsRepository';
+
+// Helper to get date strings for API params
+const getISODateString = (date: Date) => date.toISOString().split('T')[0];
+
+const COLORS = ['#8884d8', '#82ca9d', '#ffc658', '#FF8042'];
+
+export const RevenueByChannelChart = () => {
+    const [data, setData] = useState<AnalyticsByChannelResponse | null>(null);
+    const [loading, setLoading] = useState(true);
+
+    // State for the date inputs
+    const [dateRange, setDateRange] = useState(() => {
+        const to = new Date();
+        const from = new Date();
+        from.setDate(to.getDate() - 29); // Default to last 30 days
+        return {
+            from: getISODateString(from),
+            to: getISODateString(to),
+        };
+    });
+
+    const fetchData = useCallback(() => {
+        setLoading(true);
+        analyticsRepository.getRevenueByChannel(dateRange)
+            .then(setData)
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, [dateRange]);
+
+    // Fetch data on initial load and when the date range is submitted
+    useEffect(() => {
+        fetchData();
+    }, [dateRange, fetchData]);
+
+    // Transform the API data into a format that Recharts can easily use for a multi-line chart.
+    const chartData = useMemo(() => {
+        if (!data) return [];
+
+        const processedData: Record<string, any> = {};
+        const channels = data.channels.map(c => c.channel);
+
+        data.channels.forEach(channel => {
+            channel.data.forEach(dailyData => {
+                if (!processedData[dailyData.day]) {
+                    processedData[dailyData.day] = { day: dailyData.day };
+                    // Initialize other channels to 0 for this day to keep the lines continuous
+                    channels.forEach(c => { processedData[dailyData.day][c] = 0; });
+                }
+                processedData[dailyData.day][channel.channel] = dailyData.revenue;
+            });
+        });
+
+        // Sort data by date to ensure the X-axis is chronological
+        return Object.values(processedData).sort((a, b) => new Date(a.day).getTime() - new Date(b.day).getTime());
+    }, [data]);
+
+    const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+        setDateRange(prev => ({ ...prev, [e.target.name]: e.target.value }));
+    };
+
+    return (
+        <div className="bg-white p-6 rounded-lg shadow-md">
+            <div className="md:flex justify-between items-center mb-4">
+                <h3 className="text-xl font-semibold mb-2 md:mb-0">Revenue by Channel</h3>
+                <div className="flex items-center gap-2">
+                    <input type="date" name="from" value={dateRange.from} onChange={handleDateChange} className="p-1 border rounded" />
+                    <span>to</span>
+                    <input type="date" name="to" value={dateRange.to} onChange={handleDateChange} className="p-1 border rounded" />
+                </div>
+            </div>
+
+            {loading ? <p>Loading chart data...</p> : (
+                <div className="h-[400px]">
+                    <ResponsiveContainer width="100%" height="100%">
+                        <LineChart data={chartData}>
+                            <CartesianGrid strokeDasharray="3 3" />
+                            <XAxis dataKey="day" tickFormatter={(dateStr) => new Date(dateStr).toLocaleDateString([], { month: 'short', day: 'numeric' })} />
+                            <YAxis tickFormatter={(value) => `$${value}`} />
+                            <Tooltip formatter={(value: number) => `$${value.toFixed(2)}`} />
+                            <Legend />
+                            {data?.channels.map((channel, index) => (
+                                <Line
+                                    key={channel.channel}
+                                    type="monotone"
+                                    dataKey={channel.channel}
+                                    stroke={COLORS[index % COLORS.length]}
+                                    strokeWidth={2}
+                                    dot={false}
+                                />
+                            ))}
+                        </LineChart>
+                    </ResponsiveContainer>
+                </div>
+            )}
+            {data && (
+                <div className="grid grid-cols-3 gap-4 text-center mt-4 border-t pt-4">
+                    <div>
+                        <p className="text-sm text-gray-500">Grand Total Revenue</p>
+                        <p className="text-xl font-bold">${data.grand_total_revenue.toLocaleString(undefined, { minimumFractionDigits: 2 })}</p>
+                    </div>
+                    <div>
+                        <p className="text-sm text-gray-500">Total Paid Orders</p>
+                        <p className="text-xl font-bold">{data.grand_total_paid_orders.toLocaleString()}</p>
+                    </div>
+                    <div>
+                        <p className="text-sm text-gray-500">Total Tips</p>
+                        <p className="text-xl font-bold">${data.grand_total_tips.toLocaleString(undefined, { minimumFractionDigits: 2 })}</p>
+                    </div>
+                </div>
+            )}
+        </div>
+    );
+};
Index: frontend/src/components/analytics/RevenueByShiftPeriodTable.tsx
===================================================================
--- frontend/src/components/analytics/RevenueByShiftPeriodTable.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/RevenueByShiftPeriodTable.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,51 @@
+// src/components/analytics/RevenueByShiftPeriodTable.tsx
+import { useEffect, useState } from 'react';
+import { analyticsRepository } from '../../api/analyticsRepository';
+
+export const RevenueByShiftPeriodTable = () => {
+    const [data, setData] = useState<Record<string, any>[]>([]);
+    const [loading, setLoading] = useState(true);
+    const [headers, setHeaders] = useState<string[]>([]);
+
+    useEffect(() => {
+        analyticsRepository.getRevenueByShiftPeriod()
+            .then(rawData => {
+                if (rawData.length > 0) {
+                    setHeaders(Object.keys(rawData[0]));
+                }
+                setData(rawData);
+            })
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, []);
+
+    if (loading) return <p>Loading revenue by shift period...</p>;
+
+    return (
+        <div className="bg-white p-6 rounded-lg shadow-md">
+            <h3 className="text-xl font-semibold mb-4">Revenue by Shift Period</h3>
+            <div className="overflow-x-auto">
+                <table className="min-w-full">
+                    <thead>
+                        <tr>
+                            {headers.map(header => (
+                                <th key={header} className="py-2 text-left capitalize">{header.replace(/_/g, ' ')}</th>
+                            ))}
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {data.map((row, i) => (
+                            <tr key={i} className="border-t">
+                                {headers.map(header => (
+                                    <td key={header} className="py-2">
+                                        {typeof row[header] === 'number' ? `$${row[header].toFixed(2)}` : row[header]}
+                                    </td>
+                                ))}
+                            </tr>
+                        ))}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    )
+};
Index: frontend/src/components/analytics/RevenueSplitChart.tsx
===================================================================
--- frontend/src/components/analytics/RevenueSplitChart.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/RevenueSplitChart.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,47 @@
+// src/components/analytics/RevenueSplitChart.tsx
+import { useEffect, useState } from 'react';
+import { PieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer } from 'recharts';
+import type { RevenueSplitDto } from '../../types/api';
+import { analyticsRepository } from '../../api/analyticsRepository';
+
+const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
+
+export const RevenueSplitChart = () => {
+    const [data, setData] = useState<RevenueSplitDto[]>([]);
+    const [loading, setLoading] = useState(true);
+
+    useEffect(() => {
+        analyticsRepository.getRevenueSplit()
+            .then(setData)
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, []);
+
+    if (loading) return <p>Loading revenue split...</p>;
+
+    return (
+        <div className="bg-white p-6 rounded-lg shadow-md h-[400px]">
+            <h3 className="text-xl font-semibold mb-4">Revenue by Order Type (Last 30 Days)</h3>
+            <ResponsiveContainer width="100%" height="100%">
+                <PieChart>
+                    <Pie
+                        data={data}
+                        dataKey="total_revenue"
+                        nameKey="order_type"
+                        cx="50%"
+                        cy="50%"
+                        outerRadius={120}
+                        fill="#8884d8"
+                        label={({ name, percent }) => `${name} ${(percent * 100).toFixed(0)}%`}
+                    >
+                        {data.map((entry, index) => (
+                            <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
+                        ))}
+                    </Pie>
+                    <Tooltip formatter={(value: number) => `$${value.toFixed(2)}`} />
+                    <Legend />
+                </PieChart>
+            </ResponsiveContainer>
+        </div>
+    );
+};
Index: frontend/src/components/analytics/ServerPerformanceTable.tsx
===================================================================
--- frontend/src/components/analytics/ServerPerformanceTable.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/ServerPerformanceTable.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,46 @@
+// src/components/analytics/ServerPerformanceTable.tsx
+import { useEffect, useState } from 'react';
+import type { ServerPerformanceDto } from '../../types/api';
+import { analyticsRepository } from '../../api/analyticsRepository';
+
+export const ServerPerformanceTable = () => {
+    const [servers, setServers] = useState<ServerPerformanceDto[]>([]);
+    const [loading, setLoading] = useState(true);
+
+    useEffect(() => {
+        analyticsRepository.getServerPerformance()
+            .then(setServers)
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, []);
+
+    if (loading) return <p>Loading server performance...</p>;
+
+    return (
+        <div className="bg-white p-6 rounded-lg shadow-md">
+            <h3 className="text-xl font-semibold mb-4">Server Performance</h3>
+            <div className="overflow-x-auto">
+                <table className="min-w-full leading-normal">
+                    <thead>
+                        <tr>
+                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Server</th>
+                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Orders Processed</th>
+                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Avg. Order Value</th>
+                            <th className="px-5 py-3 border-b-2 text-left text-xs font-semibold uppercase">Total Revenue</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {servers.map(server => (
+                            <tr key={server.server_email}>
+                                <td className="px-5 py-4 border-b text-sm">{server.server_email}</td>
+                                <td className="px-5 py-4 border-b text-sm">{server.orders_processed}</td>
+                                <td className="px-5 py-4 border-b text-sm">${server.avg_order_value.toFixed(2)}</td>
+                                <td className="px-5 py-4 border-b text-sm font-bold">${server.total_revenue_generated.toFixed(2)}</td>
+                            </tr>
+                        ))}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    );
+};
Index: frontend/src/components/analytics/StatCard.tsx
===================================================================
--- frontend/src/components/analytics/StatCard.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/StatCard.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,20 @@
+// src/components/analytics/StatCard.tsx
+import type { ReactNode } from 'react';
+
+interface StatCardProps {
+    title: string;
+    value: string | number;
+    icon: ReactNode;
+}
+
+export const StatCard = ({ title, value, icon }: StatCardProps) => (
+    <div className="bg-white p-4 rounded-lg shadow-md flex items-center">
+        <div className="bg-blue-100 text-blue-600 rounded-full p-3 mr-4">
+            {icon}
+        </div>
+        <div>
+            <p className="text-sm text-gray-500">{title}</p>
+            <p className="text-2xl font-bold">{value}</p>
+        </div>
+    </div>
+);
Index: frontend/src/components/analytics/TopProductsList.tsx
===================================================================
--- frontend/src/components/analytics/TopProductsList.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/analytics/TopProductsList.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,38 @@
+// src/components/analytics/TopProductsList.tsx
+import { useEffect, useState } from 'react';
+import type { TopProductDto } from '../../types/api';
+import { analyticsRepository } from '../../api/analyticsRepository';
+
+export const TopProductsList = () => {
+    const [products, setProducts] = useState<TopProductDto[]>([]);
+    const [loading, setLoading] = useState(true);
+
+    useEffect(() => {
+        analyticsRepository.getTopProducts(90, 5)
+            .then(setProducts)
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, []);
+
+    if (loading) return <p>Loading top products...</p>;
+
+    return (
+        <div className="bg-white p-6 rounded-lg shadow-md">
+            <h3 className="text-xl font-semibold mb-4">Top Selling Products (Last 90 Days)</h3>
+            <ul className="space-y-3">
+                {products.map(product => (
+                    <li key={product.product_name} className="flex justify-between items-center border-b pb-2">
+                        <div>
+                            <p className="font-semibold">{product.product_name}</p>
+                            <p className="text-sm text-gray-500">{product.category_name}</p>
+                        </div>
+                        <div className="text-right">
+                            <p className="font-bold">${product.total_revenue.toFixed(2)}</p>
+                            <p className="text-sm text-gray-500">{product.total_quantity_sold} sold</p>
+                        </div>
+                    </li>
+                ))}
+            </ul>
+        </div>
+    );
+};
Index: frontend/src/components/forms/CreateProductForm.tsx
===================================================================
--- frontend/src/components/forms/CreateProductForm.tsx	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/components/forms/CreateProductForm.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -21,4 +21,5 @@
     tax_class: z.string().default('A'),
     manage_inventory: z.boolean().default(false),
+    description: z.string().default(''),
 });
 
@@ -84,4 +85,10 @@
 
             <div>
+                <label>Product Description</label>
+                <textarea {...register('description')} className="w-full p-2 border rounded" />
+                {errors.description && <p className="text-red-500 text-xs">{errors.description.message}</p>}
+            </div>
+
+            <div>
                 <input type="checkbox" {...register('manage_inventory')} className="mr-2" />
                 <label>Manage Inventory</label>
Index: frontend/src/components/modals/PaymentModal.tsx
===================================================================
--- frontend/src/components/modals/PaymentModal.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/components/modals/PaymentModal.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,109 @@
+// src/components/modals/PaymentModal.tsx
+import { useState, useMemo } from 'react';
+import type { OrderDto, CreatePaymentDto } from '../../types/api';
+import { paymentRepository } from '../../api/paymentRepository';
+import { Modal } from '../Modal';
+
+interface PaymentModalProps {
+    isOpen: boolean;
+    onClose: () => void;
+    order: OrderDto;
+    onSuccess: () => void;
+}
+
+const TIP_OPTIONS = [5, 10, 15];
+
+export const PaymentModal = ({ isOpen, onClose, order, onSuccess }: PaymentModalProps) => {
+    const [paymentType, setPaymentType] = useState<'CASH' | 'CARD' | null>(null);
+    const [tipOption, setTipOption] = useState<number | 'custom' | null>(null);
+    const [customTip, setCustomTip] = useState('');
+    const [isSubmitting, setIsSubmitting] = useState(false);
+    const [error, setError] = useState('');
+
+    const subtotal = useMemo(() =>
+        order.order_items.reduce((sum, item) => sum + (item.price * item.quantity), 0),
+        [order.order_items]
+    );
+
+    const tipAmount = useMemo(() => {
+        if (tipOption === 'custom') {
+            return parseFloat(customTip) || 0;
+        }
+        if (tipOption) {
+            return subtotal * (tipOption / 100);
+        }
+        return 0;
+    }, [tipOption, customTip, subtotal]);
+
+    const total = subtotal + tipAmount;
+
+    const handleSubmit = async () => {
+        setError('');
+        if (!paymentType) {
+            setError('Please select a payment method.');
+            return;
+        }
+
+        setIsSubmitting(true);
+        const paymentData: CreatePaymentDto = {
+            order_id: order.id,
+            amount: total,
+            payment_type: paymentType,
+            tip_amount: tipAmount,
+        };
+
+        try {
+            await paymentRepository.createPayment(paymentData);
+            alert('Payment successful!');
+            onSuccess();
+        } catch (err) {
+            console.error("Payment failed:", err);
+            setError('An error occurred during payment. Please try again.');
+        } finally {
+            setIsSubmitting(false);
+        }
+    };
+
+    return (
+        <Modal isOpen={isOpen} onClose={onClose} title={`Payment for Order #${order.id}`}>
+            <div className="space-y-4">
+                {/* Payment Method */}
+                <div>
+                    <h4 className="font-semibold mb-2">Payment Method</h4>
+                    <div className="flex gap-4">
+                        <button onClick={() => setPaymentType('CASH')} className={`w-full p-3 rounded-lg border-2 ${paymentType === 'CASH' ? 'border-blue-500 bg-blue-50' : 'border-gray-300'}`}>Cash</button>
+                        <button onClick={() => setPaymentType('CARD')} className={`w-full p-3 rounded-lg border-2 ${paymentType === 'CARD' ? 'border-blue-500 bg-blue-50' : 'border-gray-300'}`}>Card</button>
+                    </div>
+                </div>
+
+                {/* Tip Selection */}
+                <div>
+                    <h4 className="font-semibold mb-2">Add a Tip</h4>
+                    <div className="flex gap-2">
+                        {TIP_OPTIONS.map(opt => (
+                            <button key={opt} onClick={() => setTipOption(opt)} className={`flex-1 p-2 rounded border ${tipOption === opt ? 'bg-blue-500 text-white' : ''}`}>{opt}%</button>
+                        ))}
+                        <button onClick={() => setTipOption('custom')} className={`flex-1 p-2 rounded border ${tipOption === 'custom' ? 'bg-blue-500 text-white' : ''}`}>Custom</button>
+                    </div>
+                    {tipOption === 'custom' && (
+                        <input type="number" placeholder="Enter tip amount" value={customTip} onChange={e => setCustomTip(e.target.value)} className="w-full mt-2 p-2 border rounded" />
+                    )}
+                </div>
+
+                {/* Summary */}
+                <div className="border-t pt-4 space-y-2">
+                    <div className="flex justify-between"><span className="text-gray-600">Subtotal</span><span>${subtotal.toFixed(2)}</span></div>
+                    <div className="flex justify-between"><span className="text-gray-600">Tip</span><span>${tipAmount.toFixed(2)}</span></div>
+                    <div className="flex justify-between font-bold text-lg"><span >Grand Total</span><span>${total.toFixed(2)}</span></div>
+                </div>
+
+                {error && <p className="text-red-500 text-sm">{error}</p>}
+
+                {/* Action Button */}
+                <button onClick={handleSubmit} disabled={isSubmitting} className="w-full bg-green-500 hover:bg-green-600 text-white font-bold py-3 rounded-lg disabled:bg-gray-400">
+                    {isSubmitting ? 'Processing...' : 'Confirm Payment'}
+                </button>
+            </div>
+        </Modal>
+    );
+};
Index: frontend/src/index.css
===================================================================
--- frontend/src/index.css	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/index.css	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -30,2 +30,26 @@
     }
 }
+
+.border-b {
+    border-color: rgba(0, 0, 0, 0.12);
+}
+
+.border-l {
+    border-color: rgba(0, 0, 0, 0.12);
+}
+
+.border-r {
+    border-color: rgba(0, 0, 0, 0.12);
+}
+
+.border {
+    border-color: rgba(0, 0, 0, 0.12);
+}
+
+.border-t {
+    border-color: rgba(0, 0, 0, 0.12);
+}
+
+.border-b-2 {
+    border-color: rgba(0, 0, 0, 0.12);
+}
Index: frontend/src/pages/AnalyticsPage.tsx
===================================================================
--- frontend/src/pages/AnalyticsPage.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
+++ frontend/src/pages/AnalyticsPage.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -0,0 +1,73 @@
+// src/pages/AnalyticsPage.tsx
+import { useEffect, useState } from 'react';
+import type { DailyOpsDto } from '../types/api';
+import { analyticsRepository } from '../api/analyticsRepository';
+import { StatCard } from '../components/analytics/StatCard';
+import { TopProductsList } from '../components/analytics/TopProductsList';
+import { ServerPerformanceTable } from '../components/analytics/ServerPerformanceTable';
+import { RevenueByShiftPeriodTable } from '../components/analytics/RevenueByShiftPeriodTable';
+import { ManagerPerformanceTable } from '../components/analytics/ManagerPerformanceTable';
+import { RevenueSplitChart } from '../components/analytics/RevenueSplitChart';
+import { MonthlyRevenueLaborChart } from '../components/analytics/MonthlyRevenueLaborChart';
+import { RevenueByChannelChart } from '../components/analytics/RevenueByChannelChart';
+
+// Simple icons for StatCards
+const RevenueIcon = () => <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v.01" /></svg>;
+const OrdersIcon = () => <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" /></svg>;
+const CustomersIcon = () => <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M15 21a6 6 0 00-9-5.197m0 0A5.975 5.975 0 0112 13a5.975 5.975 0 014.5 2.803" /></svg>;
+
+
+export const AnalyticsPage = () => {
+    const [dailyOps, setDailyOps] = useState<DailyOpsDto[]>([]);
+    const [loading, setLoading] = useState(true);
+
+    useEffect(() => {
+        analyticsRepository.getDailyOps(30)
+            .then(setDailyOps)
+            .catch(console.error)
+            .finally(() => setLoading(false));
+    }, []);
+
+    const totals = dailyOps.reduce((acc, day) => {
+        acc.revenue += day.daily_revenue;
+        acc.orders += day.total_orders;
+        acc.customers += day.unique_customers;
+        return acc;
+    }, { revenue: 0, orders: 0, customers: 0 });
+
+    if (loading) return <div className="p-6">Loading analytics...</div>;
+
+    return (
+        <div className="p-6 bg-gray-50">
+            <h1 className="text-3xl font-bold mb-6">Analytics Dashboard</h1>
+
+            {/* Stat Cards Section */}
+            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
+                <StatCard title="Total Revenue (Last 30 Days)" value={`$${totals.revenue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`} icon={<RevenueIcon />} />
+                <StatCard title="Total Orders (Last 30 Days)" value={totals.orders.toLocaleString()} icon={<OrdersIcon />} />
+                <StatCard title="Unique Customers (Last 30 Days)" value={totals.customers.toLocaleString()} icon={<CustomersIcon />} />
+            </div>
+            <div className="mb-8">
+                <RevenueByChannelChart />
+            </div>
+
+            {/* Charts Section */}
+            <div className="grid grid-cols-1 lg:grid-cols-5 gap-6 mb-8">
+                <div className="lg:col-span-3">
+                    <MonthlyRevenueLaborChart />
+                </div>
+                <div className="lg:col-span-2">
+                    <RevenueSplitChart />
+                </div>
+            </div>
+
+            {/* Tables Section */}
+            <div className="space-y-8">
+                <TopProductsList />
+                <ServerPerformanceTable />
+                <ManagerPerformanceTable />
+                <RevenueByShiftPeriodTable />
+            </div>
+        </div>
+    );
+};
Index: frontend/src/pages/OrderDetailsPage.tsx
===================================================================
--- frontend/src/pages/OrderDetailsPage.tsx	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/pages/OrderDetailsPage.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -6,4 +6,5 @@
 import { AddItemModal } from '../components/AddItemModal';
 import { UpdateOrderStatusActions } from '../components/order/UpdateOrderStatusActions';
+import { PaymentModal } from '../components/modals/PaymentModal';
 
 export const OrderDetailsPage = () => {
@@ -11,5 +12,6 @@
     const [order, setOrder] = useState<OrderDto | null>(null);
     const [loading, setLoading] = useState(true);
-    const [isModalOpen, setIsModalOpen] = useState(false);
+    const [isAddItemModalOpen, setIsAddItemModalOpen] = useState(false);
+    const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // New state for payment modal
 
     const fetchOrderDetails = useCallback(() => {
@@ -27,11 +29,7 @@
     }, [orderId, fetchOrderDetails]);
 
-    const handleModalSuccess = () => {
-        setIsModalOpen(false);
-        fetchOrderDetails(); // Refresh details after adding items
-    };
-
     const handleSuccess = () => {
-        setIsModalOpen(false);
+        setIsAddItemModalOpen(false);
+        setIsPaymentModalOpen(false); // Close payment modal on success too
         fetchOrderDetails(); // Generic success handler for all updates
     };
@@ -41,4 +39,5 @@
 
     const totalPrice = order.order_items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
+    const isPayable = order.status !== 'COMPLETED' && order.status !== 'CANCELED' && totalPrice > 0 && order.status !== 'PAID';
 
     const getStatusColor = (status: string) => {
@@ -47,4 +46,5 @@
             case 'CANCELED': return 'bg-red-100 text-red-800';
             case 'CONFIRMED': return 'bg-yellow-100 text-yellow-800';
+            case 'PAID': return 'bg-purple-100 text-purple-800';
             default: return 'bg-blue-100 text-blue-800';
         }
@@ -55,5 +55,7 @@
             <Link to="/admin/orders" className="text-blue-600 hover:underline mb-4 block">&larr; Back to All Orders</Link>
 
-            {orderId && <AddItemModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} orderId={parseInt(orderId, 10)} onSuccess={handleModalSuccess} />}
+            {/* Modals */}
+            {orderId && <AddItemModal isOpen={isAddItemModalOpen} onClose={() => setIsAddItemModalOpen(false)} orderId={parseInt(orderId, 10)} onSuccess={handleSuccess} />}
+            {order && <PaymentModal isOpen={isPaymentModalOpen} onClose={() => setIsPaymentModalOpen(false)} order={order} onSuccess={handleSuccess} />}
 
             <div className="flex justify-between items-start mb-6">
@@ -62,7 +64,14 @@
                     <p className="text-gray-500">Placed on: {new Date(order.timestamp).toLocaleString()}</p>
                 </div>
-                <button onClick={() => setIsModalOpen(true)} className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
-                    + Add Items
-                </button>
+                <div className="flex gap-4">
+                    <button onClick={() => setIsAddItemModalOpen(true)} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
+                        + Add Items
+                    </button>
+                    {isPayable && (
+                        <button onClick={() => setIsPaymentModalOpen(true)} className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
+                            Pay
+                        </button>
+                    )}
+                </div>
             </div>
 
Index: frontend/src/pages/OrdersPage.tsx
===================================================================
--- frontend/src/pages/OrdersPage.tsx	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/pages/OrdersPage.tsx	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -6,4 +6,5 @@
 import { CreateTabOrderForm } from '../components/forms/CreateTabOrderForm';
 import { Link } from 'react-router-dom';
+import { useAuth } from '../hooks/useAuth';
 
 export const OrdersPage = () => {
@@ -12,4 +13,5 @@
     const [error, setError] = useState('');
     const [isModalOpen, setIsModalOpen] = useState(false);
+    const { user } = useAuth();
 
     const fetchOrders = async () => {
@@ -37,4 +39,5 @@
     if (loading) return <div>Loading orders...</div>;
     if (error) return <div className="text-red-500">{error}</div>;
+    if (!user) return <div className="text-red-500">User not authenticated.</div>;
 
     return (
@@ -42,10 +45,10 @@
             <div className="flex justify-between items-center mb-4">
                 <h1 className="text-3xl font-bold">Open Orders</h1>
-                <button
+                {user.user_type === "FRONT_STAFF" && <button
                     onClick={() => setIsModalOpen(true)}
                     className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
                 >
                     + Create Tab
-                </button>
+                </button>}
             </div>
 
Index: frontend/src/types/api.ts
===================================================================
--- frontend/src/types/api.ts	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/types/api.ts	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -190,2 +190,78 @@
   last_name?: string;
 }
+
+export interface DailyOpsDto {
+  operation_date: string;
+  total_reservations: number;
+  total_orders: number;
+  unique_customers: number;
+  active_employees: number;
+  daily_revenue: number;
+}
+
+export interface TopProductDto {
+  product_name: string;
+  category_name: string;
+  total_quantity_sold: number;
+  total_revenue: number;
+}
+
+export interface ServerPerformanceDto {
+  server_email: string;
+  total_assignments: number;
+  orders_processed: number;
+  total_revenue_generated: number;
+  avg_order_value: number;
+}
+
+// src/types/api.ts (add these interfaces)
+
+export interface RevenueSplitDto {
+  order_type: string;
+  total_revenue: number;
+}
+
+export interface MonthlyRevenueVsLaborDto {
+  period: string; // e.g., "2025-08"
+  total_revenue: number;
+  total_labor_cost: number;
+}
+
+export interface ManagerShiftAboveAvgDto {
+  manager_email: string;
+  shift_date: string;
+  shift_revenue: number;
+  avg_revenue_per_shift: number;
+}
+
+export interface CreatePaymentDto {
+  tip_amount: number;
+  payment_type: string; // "CASH" or "CARD"
+  amount: number;
+  order_id: number;
+}
+
+export interface PaymentsDailyChannelDto {
+  day: string; // LocalDate
+  channel: string;
+  paid_orders_cnt: number;
+  revenue: number;
+  tip_total: number;
+}
+
+export interface ChannelTableDto {
+  channel: string;
+  data: PaymentsDailyChannelDto[];
+  total_paid_orders: number;
+  total_revenue: number;
+  total_tips: number;
+}
+
+export interface AnalyticsByChannelResponse {
+  from: string; // LocalDate
+  to: string; // LocalDate
+  channels: ChannelTableDto[];
+  grand_total_paid_orders: number;
+  grand_total_revenue: number;
+  grand_total_tips: number;
+}
Index: frontend/src/utils/roles.ts
===================================================================
--- frontend/src/utils/roles.ts	(revision de7a44e8bbc4f0a5bf45334d2c960128c0ba76e0)
+++ frontend/src/utils/roles.ts	(revision 88a1dbd462f13f64d5f6f31b9d02323eb4fcfff1)
@@ -21,4 +21,5 @@
     "/admin/employees",
     "/admin/assignments",
+    "/admin/analytics",
   ],
   [UserType.FRONT_STAFF]: ["/admin/orders", "/admin/reservations"],
