{"id":2939,"date":"2026-01-31T08:54:44","date_gmt":"2026-01-31T08:54:44","guid":{"rendered":"https:\/\/malikskitchen.in\/?page_id=2939"},"modified":"2026-03-09T06:25:25","modified_gmt":"2026-03-09T00:55:25","slug":"branch","status":"publish","type":"page","link":"https:\/\/malikskitchen.in\/index.php\/branch\/","title":{"rendered":"Manage Branch"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2939\" class=\"elementor elementor-2939\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-884c589 e-flex e-con-boxed e-con e-parent\" data-id=\"884c589\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-bf55791 elementor-widget elementor-widget-shortcode\" data-id=\"bf55791\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">    <div id=\"qs-manager-app\" style=\"font-family: 'Inter', sans-serif; max-width: 1000px; margin: 0 auto; background: #f8f9fa; min-height: 80vh; border-radius: 30px; overflow: hidden; box-shadow: 0 20px 50px rgba(0,0,0,0.1); display: flex;\">\n        <div id=\"qs-mgr-login\" style=\"width:100%; padding:50px; background:white; display:flex; flex-direction:column; justify-content:center; align-items:center;\">\n            <div style=\"width:60px; height:60px; background:#60269E; border-radius:15px; display:flex; align-items:center; justify-content:center; margin-bottom:20px;\">\n                <span style=\"color:white; font-size:30px; font-weight:bold;\">Q<\/span>\n            <\/div>\n            <h2 style=\"font-weight:900; color:#60269E; margin-bottom:10px;\">Manager Login<\/h2>\n            <p style=\"color:#888; margin-bottom:30px;\">Enter your Branch ID to access dashboard.<\/p>\n            <div style=\"width:100%; max-width:350px;\">\n                <input type=\"text\" id=\"mgr-branch-id\" placeholder=\"Branch ID\" style=\"width:100%; padding:15px; border-radius:15px; border:2px solid #eee; margin-bottom:15px; font-size:16px;\">\n                <input type=\"password\" id=\"mgr-password\" placeholder=\"Password\" style=\"width:100%; padding:15px; border-radius:15px; border:2px solid #eee; margin-bottom:15px; font-size:16px;\">\n                <button onclick=\"loginManager()\" style=\"background:#60269E; color:white; border:none; padding:15px; border-radius:15px; font-weight:800; cursor:pointer; width:100%; font-size:16px; box-shadow: 0 10px 20px rgba(96, 38, 158, 0.2);\">Login Dashboard<\/button>\n            <\/div>\n        <\/div>\n        \n        <div id=\"qs-mgr-sidebar\" style=\"width:250px; background:white; border-right:1px solid #eee; display:none; flex-direction:column; padding:30px 20px;\">\n            <h2 style=\"font-weight:900; color:#60269E; margin:0 0 40px 0; font-size:20px;\">QuickServe<\/h2>\n            <div style=\"flex:1;\">\n                <div onclick=\"showMgrView('live')\" class=\"mgr-nav-item active\" id=\"nav-live\">Live Orders<\/div>\n                <div onclick=\"showMgrView('menu')\" class=\"mgr-nav-item\" id=\"nav-menu\">Menu Control<\/div>\n                \n                <div style=\"margin-top:40px; padding:20px; background:#f8f9fa; border-radius:20px;\">\n                    <p style=\"margin:0 0 10px 0; font-size:11px; font-weight:800; color:#aaa; text-transform:uppercase;\">Branch Status<\/p>\n                    <div style=\"display:flex; align-items:center; justify-content:space-between;\">\n                        <span id=\"branch-status-text\" style=\"font-weight:800; font-size:13px;\">Open<\/span>\n                        <div onclick=\"toggleBranchStatus()\" id=\"status-toggle\" style=\"width:40px; height:20px; background:#4caf50; border-radius:20px; position:relative; cursor:pointer; transition:0.3s;\">\n                            <div id=\"status-knob\" style=\"width:16px; height:16px; background:white; border-radius:50%; position:absolute; top:2px; left:22px; transition:0.3s;\"><\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n            <button onclick=\"location.reload()\" style=\"background:#fff0f0; color:#f44336; border:none; padding:12px; border-radius:12px; font-weight:800; cursor:pointer;\">Logout<\/button>\n        <\/div>\n\n        <div id=\"qs-mgr-live\" style=\"flex:1; padding:40px; display:none; overflow-y:auto;\">\n            <div style=\"display:flex; justify-content:space-between; align-items:center; margin-bottom:30px;\">\n                <div>\n                    <h2 style=\"margin:0; font-weight:900; font-size:28px;\">Live Orders<\/h2>\n                    <p id=\"mgr-branch-name\" style=\"margin:5px 0 0; color:#888; font-weight:600;\"><\/p>\n                <\/div>\n                <div style=\"background:#e8f5e9; color:#2e7d32; padding:8px 18px; border-radius:50px; font-size:12px; font-weight:800; display:flex; align-items:center; gap:8px;\">\n                    <span style=\"width:8px; height:8px; background:#2e7d32; border-radius:50%; display:inline-block; animation: pulse 1.5s infinite;\"><\/span> LIVE\n                <\/div>\n            <\/div>\n            <div id=\"orders-container\" style=\"display:grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap:20px;\"><\/div>\n        <\/div>\n\n        <div id=\"qs-mgr-menu\" style=\"flex:1; padding:40px; display:none; overflow-y:auto;\">\n            <h2 style=\"margin:0 0 30px 0; font-weight:900; font-size:28px;\">Menu Control<\/h2>\n            <div id=\"mgr-menu-container\" style=\"display:grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap:20px;\"><\/div>\n        <\/div>\n    <\/div>\n    <style>\n        @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.3; } 100% { opacity: 1; } }\n        .mgr-nav-item { padding:12px 20px; border-radius:12px; font-weight:800; margin-bottom:10px; cursor:pointer; color:#aaa; transition:0.2s; }\n        .mgr-nav-item.active { background:#f3e5f5; color:#60269E; }\n        .mgr-order-card { background:white; border:2px solid #f0f0f0; padding:25px; border-radius:25px; transition: all 0.3s; box-shadow: 0 4px 6px rgba(0,0,0,0.02); }\n        .mgr-order-card.pending { border-color: #FFD700; background: #fffdf0; box-shadow: 0 10px 30px rgba(255, 215, 0, 0.1); }\n        @keyframes slideIn { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }\n    <\/style>\n    <script>\n        const QS_API_M = 'https:\/\/malikskitchen.in\/index.php\/wp-json\/qs\/v1';\n        let lastOrderCount = 0;\n        let isRinging = false;\n        let currentBranchId = null;\n        let currentBranchStatus = 1;\n        const bell = new Audio('https:\/\/assets.mixkit.co\/active_storage\/sfx\/2869\/2869-preview.mp3');\n        bell.loop = true;\n\n        window.loginManager = async () => {\n            const id = document.getElementById('mgr-branch-id').value;\n            const pass = document.getElementById('mgr-password').value;\n            if (!id || !pass) return alert(\"Enter ID and Password\");\n            \n            const res = await fetch(QS_API_M + '\/manager\/login', {\n                method: 'POST',\n                headers: {'Content-Type': 'application\/json'},\n                body: JSON.stringify({ branch_id: id, password: pass })\n            }).then(r => r.json());\n\n            if (!res.success) return alert(res.message);\n\n            currentBranchId = id;\n            currentBranchStatus = res.branch.is_open;\n            updateStatusUI();\n\n            document.getElementById('mgr-branch-name').innerText = `Branch: ${res.branch.name}`;\n            document.getElementById('qs-mgr-login').style.display = 'none';\n            document.getElementById('qs-mgr-sidebar').style.display = 'flex';\n            document.getElementById('qs-mgr-live').style.display = 'block';\n            \n            startPolling(id);\n        };\n\n        function updateStatusUI() {\n            const text = document.getElementById('branch-status-text');\n            const toggle = document.getElementById('status-toggle');\n            const knob = document.getElementById('status-knob');\n            \n            if (currentBranchStatus == 1) {\n                text.innerText = 'Open';\n                text.style.color = '#4caf50';\n                toggle.style.background = '#4caf50';\n                knob.style.left = '22px';\n            } else {\n                text.innerText = 'Closed';\n                text.style.color = '#f44336';\n                toggle.style.background = '#ccc';\n                knob.style.left = '2px';\n            }\n        }\n\n        window.toggleBranchStatus = async () => {\n            const newStatus = currentBranchStatus == 1 ? 0 : 1;\n            const res = await fetch(QS_API_M + '\/manager\/branch\/status', {\n                method: 'POST',\n                headers: {'Content-Type': 'application\/json'},\n                body: JSON.stringify({ branch_id: currentBranchId, is_open: newStatus })\n            }).then(r => r.json());\n\n            if (res.success) {\n                currentBranchStatus = newStatus;\n                updateStatusUI();\n            }\n        };\n\n        window.showMgrView = (view) => {\n            document.getElementById('qs-mgr-live').style.display = view === 'live' ? 'block' : 'none';\n            document.getElementById('qs-mgr-menu').style.display = view === 'menu' ? 'block' : 'none';\n            document.querySelectorAll('.mgr-nav-item').forEach(n => n.classList.remove('active'));\n            document.getElementById('nav-' + view).classList.add('active');\n            if (view === 'menu') renderMgrMenu();\n        };\n\n        async function renderMgrMenu() {\n            const data = await fetch(QS_API_M + '\/menu').then(r => r.json());\n            \n            \/\/ Fetch current branch visibility status\n            const res = await fetch(QS_API + '\/menu?branch_id=' + currentBranchId).then(r => r.json());\n            const visibleCategories = res.categories.map(c => parseInt(c.term_id));\n            const visibleProducts = res.products.map(p => parseInt(p.id));\n\n            const container = document.getElementById('qs-mgr-menu');\n            container.innerHTML = `\n                <div style=\"display:flex; justify-content:space-between; align-items:center; margin-bottom:30px;\">\n                    <h2 style=\"margin:0; font-weight:900; font-size:28px;\">Menu Control<\/h2>\n                    <div style=\"position:relative; width:300px;\">\n                        <span style=\"position:absolute; left:12px; top:50%; transform:translateY(-50%); opacity:0.5;\">\ud83d\udd0d<\/span>\n                        <input type=\"text\" id=\"mgr-menu-search\" placeholder=\"Search dishes...\" oninput=\"filterMgrMenu(this.value)\" style=\"width:100%; padding:10px 10px 10px 35px; border-radius:12px; border:1px solid #ddd; font-size:14px;\">\n                    <\/div>\n                <\/div>\n                <div id=\"mgr-menu-container\" style=\"display:grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap:20px;\"><\/div>\n            `;\n\n            window.mgrAllProducts = data.products;\n            window.mgrAllCategories = data.categories;\n            window.mgrVisibleCats = visibleCategories;\n            window.mgrVisibleProds = visibleProducts;\n\n            displayMgrMenu(data.categories, data.products);\n        }\n\n        function filterMgrMenu(query) {\n            const filteredProds = window.mgrAllProducts.filter(p => p.name.toLowerCase().includes(query.toLowerCase()));\n            displayMgrMenu(window.mgrAllCategories, filteredProds);\n        }\n\n        function displayMgrMenu(categories, products) {\n            const container = document.getElementById('mgr-menu-container');\n            container.innerHTML = `\n                <div style=\"grid-column: 1 \/ -1; margin-bottom: 20px;\">\n                    <h3 style=\"font-size:18px; font-weight:900; color:#60269E;\">Categories<\/h3>\n                    <div id=\"mgr-cats-container\" style=\"display:grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap:15px;\"><\/div>\n                <\/div>\n                <div style=\"grid-column: 1 \/ -1;\">\n                    <h3 style=\"font-size:18px; font-weight:900; color:#60269E;\">Products<\/h3>\n                    <div id=\"mgr-prods-container\" style=\"display:grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap:20px;\"><\/div>\n                <\/div>\n            `;\n\n            const catsContainer = document.getElementById('mgr-cats-container');\n            const prodsContainer = document.getElementById('mgr-prods-container');\n\n            categories.forEach(c => {\n                const isVisible = window.mgrVisibleCats.includes(parseInt(c.term_id));\n                catsContainer.innerHTML += `\n                    <div style=\"background:white; padding:15px; border-radius:15px; border:1px solid #eee; display:flex; align-items:center; justify-content:space-between;\">\n                        <span style=\"font-weight:700; font-size:13px;\">${c.name}<\/span>\n                        <div onclick=\"toggleMgrItem(${c.term_id}, 'category', ${isVisible ? 0 : 1})\" style=\"width:34px; height:18px; background:${isVisible ? '#4caf50' : '#ccc'}; border-radius:20px; position:relative; cursor:pointer; transition:0.3s;\">\n                            <div style=\"width:14px; height:14px; background:white; border-radius:50%; position:absolute; top:2px; left:${isVisible ? '18px' : '2px'}; transition:0.3s;\"><\/div>\n                        <\/div>\n                    <\/div>\n                `;\n            });\n\n            products.forEach(p => {\n                const isVisible = window.mgrVisibleProds.includes(parseInt(p.id));\n                prodsContainer.innerHTML += `\n                    <div style=\"background:white; padding:20px; border-radius:20px; border:1px solid #eee; display:flex; align-items:center; gap:15px;\">\n                        <img decoding=\"async\" src=\"${p.image_url || 'https:\/\/picsum.photos\/100'}\" style=\"width:60px; height:60px; border-radius:12px; object-fit:cover;\">\n                        <div style=\"flex:1;\">\n                            <h4 style=\"margin:0; font-size:14px;\">${p.name}<\/h4>\n                            <div style=\"display:flex; align-items:center; justify-content:space-between; margin-top:10px;\">\n                                <span style=\"font-size:12px; font-weight:800; color:${isVisible ? '#4caf50' : '#f44336'}\">${isVisible ? 'In Stock' : 'Out of Stock'}<\/span>\n                                <div onclick=\"toggleMgrItem(${p.id}, 'product', ${isVisible ? 0 : 1})\" style=\"width:34px; height:18px; background:${isVisible ? '#4caf50' : '#ccc'}; border-radius:20px; position:relative; cursor:pointer; transition:0.3s;\">\n                                    <div style=\"width:14px; height:14px; background:white; border-radius:50%; position:absolute; top:2px; left:${isVisible ? '18px' : '2px'}; transition:0.3s;\"><\/div>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                `;\n            });\n        }\n\n        window.toggleMgrItem = async (id, type, status) => {\n            await fetch(QS_API_M + '\/manager\/menu\/toggle', {\n                method: 'POST',\n                headers: {'Content-Type': 'application\/json'},\n                body: JSON.stringify({ \n                    branch_id: currentBranchId, \n                    target_id: id, \n                    target_type: type, \n                    is_visible: status \n                })\n            });\n            renderMgrMenu();\n        };\n\n        function startPolling(branchId) {\n            setInterval(async () => {\n                const orders = await fetch(QS_API_M + '\/manager\/orders?branch_id=' + branchId).then(r => r.json());\n                \n                const hasPending = orders.some(o => o.status === 'Pending');\n                if (hasPending && !isRinging) {\n                    bell.play().catch(e => console.log(\"Audio blocked\"));\n                    isRinging = true;\n                } else if (!hasPending && isRinging) {\n                    bell.pause();\n                    bell.currentTime = 0;\n                    isRinging = false;\n                }\n                \n                const container = document.getElementById('orders-container');\n                let html = '';\n                orders.forEach((o) => {\n                    const items = JSON.parse(o.items_json || '[]');\n                    html += `\n                        <div class=\"mgr-order-card ${o.status === 'Pending' ? 'pending' : ''}\">\n                            <div style=\"display:flex; justify-content:space-between; margin-bottom:15px;\">\n                                <span style=\"font-size:10px; font-weight:800; color:#aaa; text-transform:uppercase;\">Order #${o.id}<\/span>\n                                <span style=\"font-size:10px; font-weight:800; color:${o.status === 'Accepted' ? '#4caf50' : (o.status === 'Rejected' ? '#f44336' : '#60269E')}; background:${o.status === 'Accepted' ? '#e8f5e9' : (o.status === 'Rejected' ? '#ffebee' : '#f3e5f5')}; padding:4px 10px; border-radius:5px;\">${o.status}<\/span>\n                            <\/div>\n                            <h3 style=\"margin:0; font-weight:900; font-size:20px;\">${o.customer_name}<\/h3>\n                            <p style=\"color:#888; font-size:13px; margin:5px 0;\">${o.customer_phone || 'No phone'}<\/p>\n                            \n                            <div style=\"margin:20px 0; padding:15px 0; border-top:1px solid #eee; border-bottom:1px solid #eee;\">\n                                ${items.map(i => `<div style=\"display:flex; justify-content:space-between; font-size:13px; margin-bottom:5px; font-weight:600;\"><span>${i.name} x ${i.quantity || 1}<\/span><span>\u20b9${i.price}<\/span><\/div>`).join('')}\n                                <div style=\"display:flex; justify-content:space-between; font-weight:900; color:#60269E; font-size:16px; margin-top:10px;\"><span>Total<\/span><span>\u20b9${o.total_price}<\/span><\/div>\n                            <\/div>\n                            \n                            ${o.status === 'Pending' ? `\n                                <div style=\"display:flex; gap:10px;\">\n                                    <button onclick=\"updateStatus(${o.id}, 'Accepted')\" style=\"flex:1; background:#4caf50; color:white; border:none; padding:12px; border-radius:12px; font-weight:800; cursor:pointer;\">Accept<\/button>\n                                    <button onclick=\"updateStatus(${o.id}, 'Rejected')\" style=\"flex:1; background:#f44336; color:white; border:none; padding:12px; border-radius:12px; font-weight:800; cursor:pointer;\">Reject<\/button>\n                                <\/div>\n                            ` : ''}\n                            \n                            <div style=\"font-size:10px; color:#ccc; margin-top:15px; text-align:right;\">${o.created_at}<\/div>\n                        <\/div>\n                    `;\n                });\n                container.innerHTML = html || '<div style=\"grid-column: 1\/-1; text-align:center; color:#ccc; padding:100px;\">Waiting for orders...<\/div>';\n                lastOrderCount = orders.length;\n            }, 5000);\n        }\n\n        window.updateStatus = async (orderId, status) => {\n            await fetch(QS_API_M + '\/manager\/order\/status', {\n                method: 'POST',\n                headers: {'Content-Type': 'application\/json'},\n                body: JSON.stringify({ order_id: orderId, status: status })\n            });\n        };\n\n        document.addEventListener('click', () => { if (isRinging) bell.play(); }, { once: true });\n    <\/script>\n    <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"page-builder","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-2939","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages\/2939","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/comments?post=2939"}],"version-history":[{"count":39,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages\/2939\/revisions"}],"predecessor-version":[{"id":3368,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages\/2939\/revisions\/3368"}],"wp:attachment":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/media?parent=2939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}