diff --git a/local_backend/routers/connect_orders.py b/local_backend/routers/connect_orders.py index 5445da6..39d87e7 100644 --- a/local_backend/routers/connect_orders.py +++ b/local_backend/routers/connect_orders.py @@ -63,6 +63,38 @@ async def _mirror_status_to_cloud(cloud_order_id: int, new_status: str, rejectio # ── Endpoints ───────────────────────────────────────────────────────────────── +@router.get("/orders", response_model=list[OrderOut]) +def get_orders_by_status( + status: str, + db: Session = Depends(get_db), + user: User = Depends(get_current_user), +): + """ + ?status=active → accepted | preparing | ready | out_for_delivery, newest first + ?status=history → delivered | rejected, newest first, limit 50 + """ + if status == "active": + statuses = ["accepted", "preparing", "ready", "out_for_delivery"] + orders = ( + db.query(Order) + .filter(Order.source == "online", Order.online_status.in_(statuses)) + .order_by(Order.opened_at.desc()) + .all() + ) + elif status == "history": + statuses = ["delivered", "rejected"] + orders = ( + db.query(Order) + .filter(Order.source == "online", Order.online_status.in_(statuses)) + .order_by(Order.opened_at.desc()) + .limit(50) + .all() + ) + else: + raise HTTPException(status_code=400, detail=f"Unknown status filter '{status}'. Use 'active' or 'history'.") + return orders + + @router.get("/orders/incoming", response_model=list[OrderOut]) def get_incoming_orders( db: Session = Depends(get_db), diff --git a/manager_dashboard/src/App.jsx b/manager_dashboard/src/App.jsx index 3474d29..7b4379e 100644 --- a/manager_dashboard/src/App.jsx +++ b/manager_dashboard/src/App.jsx @@ -10,6 +10,7 @@ import OrderDetailPage from './pages/OrderDetailPage' import ManagementPage from './pages/ManagementPage' import ReportsPage from './pages/reports/ReportsPage' import SettingsPage from './pages/Settings/SettingsPage' +import OnlineOrdersPage from './pages/OnlineOrdersPage' import client from './api/client' function Spinner() { @@ -80,6 +81,7 @@ export default function App() { } /> } /> } /> + } /> } /> } /> diff --git a/manager_dashboard/src/api/client.js b/manager_dashboard/src/api/client.js index 6e5c8f7..cbfe7b8 100644 --- a/manager_dashboard/src/api/client.js +++ b/manager_dashboard/src/api/client.js @@ -23,3 +23,18 @@ client.interceptors.response.use( ) export default client + +// ── Online Orders (Xenia Connect) ───────────────────────────────────────────── + +export const getIncomingOrders = () => client.get('/api/connect/orders/incoming') +export const getActiveOrders = () => client.get('/api/connect/orders?status=active') +export const getOrderHistory = () => client.get('/api/connect/orders?status=history') + +export const acceptOnlineOrder = (id) => + client.post(`/api/connect/orders/${id}/accept`) + +export const rejectOnlineOrder = (id, reason) => + client.post(`/api/connect/orders/${id}/reject`, { reason }) + +export const updateOnlineOrderStatus = (id, status) => + client.post(`/api/connect/orders/${id}/status`, { status }) diff --git a/manager_dashboard/src/components/Sidebar.jsx b/manager_dashboard/src/components/Sidebar.jsx index e47ad5b..3e98bdd 100644 --- a/manager_dashboard/src/components/Sidebar.jsx +++ b/manager_dashboard/src/components/Sidebar.jsx @@ -1,17 +1,33 @@ import { NavLink } from 'react-router-dom' -import { useState } from 'react' -import { BarChart2, LayoutGrid, ClipboardList, Package, Settings, ChevronRight, ChevronLeft } from 'lucide-react' - -const NAV = [ - { to: '/dashboard', icon: BarChart2, label: 'Dashboard' }, - { to: '/tables', icon: LayoutGrid, label: 'Τραπέζια' }, - { to: '/reports', icon: ClipboardList, label: 'Αναφορές' }, - { to: '/management', icon: Package, label: 'Διαχείριση' }, - { to: '/settings', icon: Settings, label: 'Ρυθμίσεις' }, -] +import { useState, useEffect, useRef } from 'react' +import { BarChart2, LayoutGrid, ClipboardList, Package, Settings, ChevronRight, ChevronLeft, ShoppingBag } from 'lucide-react' +import { getIncomingOrders } from '../api/client' export default function Sidebar() { const [collapsed, setCollapsed] = useState(false) + const [pendingCount, setPendingCount] = useState(0) + const pollRef = useRef(null) + + useEffect(() => { + async function fetchPending() { + try { + const { data } = await getIncomingOrders() + setPendingCount(data.length) + } catch { /* silently ignore — sidebar badge is non-critical */ } + } + fetchPending() + pollRef.current = setInterval(fetchPending, 20_000) + return () => clearInterval(pollRef.current) + }, []) + + const NAV = [ + { to: '/dashboard', icon: BarChart2, label: 'Dashboard' }, + { to: '/tables', icon: LayoutGrid, label: 'Τραπέζια' }, + { to: '/online-orders', icon: ShoppingBag, label: 'Online Orders', badge: pendingCount }, + { to: '/reports', icon: ClipboardList, label: 'Αναφορές' }, + { to: '/management', icon: Package, label: 'Διαχείριση' }, + { to: '/settings', icon: Settings, label: 'Ρυθμίσεις' }, + ] return (