This repository has been archived on 2026-03-21. You can view files and clone it, but cannot push or open issues or pull requests.
payfrit-biz/portal/index.html
John Mizerek 48bdbb362e Remove task categories from portal, fix HUD color logic
- Remove Task Categories section from Task Admin page (deprecated)
- Simplify HUD getCategoryColor() to use TaskTypeColor directly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 19:04:25 -08:00

777 lines
38 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payfrit Business Portal</title>
<link rel="stylesheet" href="portal.css">
<script>
// Auth check - redirect to signup if not logged in
(function() {
const token = localStorage.getItem('payfrit_portal_token');
if (!token) {
window.location.href = 'signup.html';
}
})();
</script>
</head>
<body>
<div class="app">
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<!-- Business Card -->
<div class="business-info" style="padding: 12px 16px; border-bottom: 1px solid var(--gray-200); display: flex; align-items: center; gap: 12px;">
<div class="business-avatar" id="businessAvatar">B</div>
<div class="business-details" style="flex: 1;">
<div class="business-name" id="businessName">Loading...</div>
<div class="business-status online">Online</div>
</div>
<button class="sidebar-toggle" id="sidebarToggle" style="background: none; border: none; cursor: pointer; padding: 4px;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 12h18M3 6h18M3 18h18"/>
</svg>
</button>
</div>
<nav class="sidebar-nav">
<a href="#dashboard" class="nav-item active" data-page="dashboard">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/>
<rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/>
</svg>
<span>Dashboard</span>
</a>
<a href="#orders" class="nav-item" data-page="orders">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/>
<rect x="9" y="3" width="6" height="4" rx="1"/>
<path d="M9 12h6M9 16h6"/>
</svg>
<span>Orders</span>
</a>
<a href="menu-builder.html" class="nav-item">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 6h18M3 12h18M3 18h18"/>
</svg>
<span>Menu</span>
</a>
<a href="#reports" class="nav-item" data-page="reports">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 20V10M12 20V4M6 20v-6"/>
</svg>
<span>Reports</span>
</a>
<a href="#team" class="nav-item" data-page="team">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/>
<circle cx="9" cy="7" r="4"/>
<path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/>
</svg>
<span>Team</span>
</a>
<a href="#services" class="nav-item" data-page="services">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9"/>
<path d="M13.73 21a2 2 0 01-3.46 0"/>
</svg>
<span>Services</span>
</a>
<a href="#service-points" class="nav-item" data-page="service-points">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="3"/>
<path d="M12 2v4M12 18v4M2 12h4M18 12h4"/>
<path d="M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>
</svg>
<span>Service Points</span>
</a>
<a href="#admin-tasks" class="nav-item" data-page="admin-tasks">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<span>Task Admin</span>
</a>
<a href="#settings" class="nav-item" data-page="settings">
<svg class="nav-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z"/>
</svg>
<span>Settings</span>
</a>
</nav>
</aside>
<!-- Main Content -->
<main class="main-content">
<header class="top-bar">
<div class="page-title">
<h1 id="pageTitle">Dashboard</h1>
</div>
<div class="top-bar-actions">
<button class="btn btn-icon" id="refreshBtn" title="Refresh">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M23 4v6h-6M1 20v-6h6"/>
<path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
</svg>
</button>
<div class="user-menu" style="position: relative;">
<button class="user-btn" id="userBtn" onclick="document.getElementById('userDropdown').classList.toggle('show')">
<span class="user-avatar" id="userAvatar">B</span>
</button>
<div class="user-dropdown" id="userDropdown" style="display:none; position:absolute; right:0; top:100%; margin-top:8px; background:var(--bg-card); border:1px solid var(--border-color); border-radius:8px; min-width:200px; box-shadow:0 4px 12px rgba(0,0,0,0.3); z-index:1000; overflow:hidden;">
<a href="#settings" class="nav-item" data-page="settings" onclick="document.getElementById('userDropdown').classList.remove('show'); Portal.navigate('settings');" style="display:flex; align-items:center; gap:10px; padding:12px 16px; color:var(--text-primary); text-decoration:none; transition:background 0.15s;" onmouseover="this.style.background='var(--bg-secondary)'" onmouseout="this.style.background=''">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.6 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.6a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
Settings
</a>
<a href="#" onclick="Portal.switchBusiness(); document.getElementById('userDropdown').classList.remove('show'); return false;" style="display:flex; align-items:center; gap:10px; padding:12px 16px; color:var(--text-primary); text-decoration:none; transition:background 0.15s;" onmouseover="this.style.background='var(--bg-secondary)'" onmouseout="this.style.background=''">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 3h5v5M8 3H3v5M3 16v5h5M21 16v5h-5M7 12h10"/></svg>
Switch Business
</a>
<a href="#" onclick="Portal.addNewBusiness(); document.getElementById('userDropdown').classList.remove('show'); return false;" style="display:flex; align-items:center; gap:10px; padding:12px 16px; color:var(--text-primary); text-decoration:none; transition:background 0.15s;" onmouseover="this.style.background='var(--bg-secondary)'" onmouseout="this.style.background=''">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 5v14M5 12h14"/></svg>
Add New Business
</a>
<div style="border-top: 1px solid var(--border-color);"></div>
<a href="#" onclick="Portal.logout(); return false;" style="display:flex; align-items:center; gap:10px; padding:12px 16px; color:#ef4444; text-decoration:none; transition:background 0.15s;" onmouseover="this.style.background='var(--bg-secondary)'" onmouseout="this.style.background=''">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4M16 17l5-5-5-5M21 12H9"/></svg>
Logout
</a>
</div>
</div>
</div>
</header>
<!-- Page Container -->
<div class="page-container" id="pageContainer">
<!-- Dashboard Page -->
<section class="page active" id="page-dashboard">
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon orders">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/>
</svg>
</div>
<div class="stat-content">
<div class="stat-value" id="statOrdersToday">0</div>
<div class="stat-label">Orders Today</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon revenue">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 1v22M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6"/>
</svg>
</div>
<div class="stat-content">
<div class="stat-value" id="statRevenueToday">$0</div>
<div class="stat-label">Revenue Today</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon pending">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/>
</svg>
</div>
<div class="stat-content">
<div class="stat-value" id="statPendingOrders">0</div>
<div class="stat-label">Pending Orders</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon items">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 6h18M3 12h18M3 18h18"/>
</svg>
</div>
<div class="stat-content">
<div class="stat-value" id="statMenuItems">0</div>
<div class="stat-label">Menu Items</div>
</div>
</div>
</div>
<div class="dashboard-grid">
<div class="card recent-orders">
<div class="card-header">
<h3>Recent Orders</h3>
<a href="#orders" class="link">View All</a>
</div>
<div class="card-body">
<div class="orders-list" id="recentOrdersList">
<div class="empty-state">No recent orders</div>
</div>
</div>
</div>
<div class="card quick-actions">
<div class="card-header">
<h3>Quick Actions</h3>
</div>
<div class="card-body">
<div class="action-grid">
<button class="action-btn" onclick="Portal.navigate('menu')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 5v14M5 12h14"/>
</svg>
Add Menu Item
</button>
<button class="action-btn" onclick="window.open('/kds/index.html', '_blank')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="2" y="3" width="20" height="14" rx="2"/>
<path d="M8 21h8M12 17v4"/>
</svg>
Open KDS
</button>
<button class="action-btn" onclick="Portal.openQuickTasks()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/>
</svg>
Quick Tasks
</button>
<button class="action-btn" onclick="Portal.openHUD()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 20V10M12 20V4M6 20v-6"/>
</svg>
Task HUD
</button>
<button class="action-btn" onclick="Portal.navigate('settings')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="3"/>
</svg>
Settings
</button>
</div>
</div>
</div>
</div>
</section>
<!-- Orders Page -->
<section class="page" id="page-orders">
<div class="page-header">
<div class="filters">
<select id="orderStatusFilter" class="form-select">
<option value="">All Statuses</option>
<option value="1">Submitted</option>
<option value="2">Preparing</option>
<option value="3">Ready</option>
<option value="4">Completed</option>
</select>
<input type="date" id="orderDateFilter" class="form-input">
</div>
</div>
<div class="card">
<div class="table-container">
<table class="data-table">
<thead>
<tr>
<th>Order #</th>
<th>Customer</th>
<th>Items</th>
<th>Total</th>
<th>Status</th>
<th>Time</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="ordersTableBody">
<tr><td colspan="7" class="empty-state">Loading orders...</td></tr>
</tbody>
</table>
</div>
</div>
</section>
<!-- Menu Page -->
<section class="page" id="page-menu">
<div class="page-header">
<a href="setup-wizard.html" class="btn btn-secondary" style="margin-right: auto;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
<path d="M2 12l10 5 10-5"/>
</svg>
Setup Wizard
</a>
<button class="btn btn-primary" onclick="Portal.showAddCategoryModal()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 5v14M5 12h14"/>
</svg>
Add Category
</button>
<button class="btn btn-primary" onclick="Portal.showAddItemModal()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 5v14M5 12h14"/>
</svg>
Add Item
</button>
</div>
<div class="menu-grid" id="menuGrid">
<div class="empty-state">Loading menu...</div>
</div>
</section>
<!-- Reports Page -->
<section class="page" id="page-reports">
<div class="reports-grid">
<div class="card">
<div class="card-header">
<h3>Sales Overview</h3>
<select id="reportPeriod" class="form-select">
<option value="7">Last 7 Days</option>
<option value="30">Last 30 Days</option>
<option value="90">Last 90 Days</option>
</select>
</div>
<div class="card-body">
<div class="chart-placeholder" id="salesChart">
<p>Sales chart will appear here</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h3>Top Selling Items</h3>
</div>
<div class="card-body">
<div id="topItemsList" class="top-items-list">
<div class="empty-state">No data available</div>
</div>
</div>
</div>
</div>
</section>
<!-- Team Page -->
<section class="page" id="page-team">
<div class="page-header">
<button class="btn btn-primary" onclick="Portal.showInviteModal()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M16 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/>
<circle cx="8.5" cy="7" r="4"/>
<path d="M20 8v6M23 11h-6"/>
</svg>
Invite Team Member
</button>
<div class="hiring-toggle">
<label class="toggle">
<input type="checkbox" id="hiringToggle">
<span class="toggle-slider"></span>
</label>
<span>Accepting Applications</span>
</div>
</div>
<div class="card">
<div class="table-container">
<table class="data-table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="teamTableBody">
<tr><td colspan="5" class="empty-state">Loading team...</td></tr>
</tbody>
</table>
</div>
</div>
</section>
<!-- Service Points Page (combined: Service Points, Beacons, Sharing) -->
<section class="page" id="page-service-points">
<div class="service-points-layout">
<!-- Service Points list -->
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Service Points</h3>
<button class="btn btn-sm btn-primary" onclick="Portal.showServicePointModal()">+ Add Service Point</button>
</div>
<div class="card-body">
<div class="list-group" id="servicePointsList">
<div class="empty-state">Loading service points...</div>
</div>
</div>
</div>
<!-- Beacons list -->
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Beacons</h3>
<button class="btn btn-sm btn-primary" onclick="Portal.showBeaconModal()">+ Add Beacon</button>
</div>
<div class="card-body">
<div class="list-group" id="beaconsList">
<div class="empty-state">Loading beacons...</div>
</div>
</div>
</div>
<!-- Beacon Assignments -->
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Beacon Assignments</h3>
<button class="btn btn-sm btn-primary" onclick="Portal.showAssignmentModal()">+ Assign</button>
</div>
<div class="card-body">
<div class="list-group" id="assignmentsList">
<div class="empty-state">Loading assignments...</div>
</div>
</div>
</div>
<!-- COMMENTED OUT FOR LAUNCH - Service Point Marketing / Grants (coming soon)
<div class="card" id="spSharingOwnerCard">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center">
<h3>Grants You've Created</h3>
<button class="btn btn-primary btn-sm" onclick="Portal.showInviteBusinessModal()">Invite Business</button>
</div>
<div class="card-body" id="ownerGrantsList">
<div class="loading-text">Loading...</div>
</div>
</div>
<div class="card" id="spSharingGuestCard">
<div class="card-header">
<h3>Invites &amp; Active Grants</h3>
</div>
<div class="card-body" id="guestGrantsList">
<div class="loading-text">Loading...</div>
</div>
</div>
</div>
<div class="modal-overlay" id="inviteBusinessModal" style="display:none">
<div class="modal" style="max-width:500px">
<div class="modal-header">
<h3>Invite Business to Service Point</h3>
<button class="modal-close" onclick="Portal.closeInviteModal()">&times;</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Search Business</label>
<input type="text" id="inviteBizSearch" class="form-input" placeholder="Business name or ID..." oninput="Portal.searchBusinessForInvite()">
<div id="inviteBizResults" style="margin-top:8px"></div>
</div>
<div class="form-group" id="inviteBizSelected" style="display:none">
<label>Selected Business</label>
<div id="inviteBizSelectedName" class="form-input" style="background:var(--bg-secondary)"></div>
</div>
<div class="form-group">
<label>Service Point</label>
<select id="inviteSPSelect" class="form-input"></select>
</div>
<div class="form-group">
<label>Economics</label>
<select id="inviteEconType" class="form-input" onchange="Portal.toggleEconValue()">
<option value="none">None</option>
<option value="flat_fee">Flat Fee ($/order)</option>
<option value="percent_of_orders">Percentage of Orders</option>
</select>
<input type="number" id="inviteEconValue" class="form-input" placeholder="0" step="0.01" min="0" style="display:none;margin-top:4px">
</div>
<div class="form-group">
<label>Eligibility</label>
<select id="inviteEligibility" class="form-input">
<option value="public">Public (anyone)</option>
<option value="employees">Employees only</option>
<option value="guests">Guests only</option>
<option value="internal">Internal (owner's employees)</option>
</select>
</div>
<div class="form-group">
<label>Time Policy</label>
<select id="inviteTimePolicy" class="form-input">
<option value="always">Always</option>
<option value="schedule">Schedule</option>
<option value="date_range">Date Range</option>
</select>
</div>
</div>
<div class="modal-footer">
<button class="btn" onclick="Portal.closeInviteModal()">Cancel</button>
<button class="btn btn-primary" onclick="Portal.submitGrantInvite()">Send Invite</button>
</div>
</div>
</div>
END COMMENTED OUT -->
</section>
<!-- Services Page (Task Types) -->
<section class="page" id="page-services">
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Bell Menu Services</h3>
<button class="btn btn-sm btn-primary" onclick="Portal.showAddServiceModal()">+ Add Service</button>
</div>
<div class="card-body">
<p style="color:#666;margin-bottom:16px;">These service options appear when customers tap the bell icon in the app. Customize the names, descriptions, and icons to match your business.</p>
<div class="list-group" id="servicesList">
<div class="empty-state">Loading...</div>
</div>
</div>
</div>
</section>
<!-- Admin Tasks Page -->
<section class="page" id="page-admin-tasks">
<div class="admin-tasks-layout">
<!-- Quick Tasks Section -->
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Quick Tasks</h3>
<button class="btn btn-sm btn-primary" onclick="Portal.showAddQuickTaskModal()">+ Add Quick Task</button>
</div>
<div class="card-body">
<p style="color:#666;margin-bottom:16px;">Create common tasks instantly with one tap.</p>
<div class="quick-tasks-grid" id="quickTasksGrid">
<div class="empty-state">Loading...</div>
</div>
<div id="quickTasksManageList" style="margin-top:24px;"></div>
</div>
</div>
<!-- Scheduled Tasks Section -->
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Scheduled Tasks</h3>
<button class="btn btn-sm btn-primary" onclick="Portal.showAddScheduledTaskModal()">+ Add Scheduled Task</button>
</div>
<div class="card-body">
<p style="color:#666;margin-bottom:16px;">Define recurring tasks that automatically create entries in the Tasks system.</p>
<div class="list-group" id="scheduledTasksList">
<div class="empty-state">Loading...</div>
</div>
</div>
</div>
<!-- Worker Ratings Section -->
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Worker Ratings</h3>
<button class="btn btn-sm btn-secondary" onclick="Portal.loadPendingRatings()">Refresh</button>
</div>
<div class="card-body">
<p style="color:#666;margin-bottom:16px;">Rate worker performance on recently completed tasks. These ratings help track performance over time.</p>
<div class="list-group" id="pendingRatingsList">
<div class="empty-state">Loading...</div>
</div>
</div>
</div>
</div>
</section>
<!-- Settings Page -->
<section class="page" id="page-settings">
<div class="settings-grid">
<div class="card">
<div class="card-header">
<h3>Business Information</h3>
</div>
<div class="card-body">
<form id="businessInfoForm" class="form" onsubmit="Portal.saveBusinessInfo(event)">
<div class="form-group">
<label>Business Name</label>
<input type="text" id="settingBusinessName" class="form-input" required>
</div>
<div class="form-group">
<label>Phone</label>
<input type="tel" id="settingPhone" class="form-input" placeholder="(555) 123-4567">
</div>
<div class="form-group">
<label>Sales Tax Rate (%)</label>
<input type="number" id="settingTaxRate" class="form-input" placeholder="8.25" step="0.01" min="0" max="25">
<small style="color:#666;font-size:12px;">Enter as percentage (e.g., 8.25 for 8.25%)</small>
</div>
<div class="form-group">
<label>Street Address</label>
<input type="text" id="settingAddressLine1" class="form-input" placeholder="123 Main St">
</div>
<div class="form-row" style="display:grid;grid-template-columns:2fr 1fr 1fr;gap:12px;">
<div class="form-group">
<label>City</label>
<input type="text" id="settingCity" class="form-input" placeholder="Los Angeles">
</div>
<div class="form-group">
<label>State</label>
<select id="settingState" class="form-input">
<option value="">--</option>
</select>
</div>
<div class="form-group">
<label>ZIP</label>
<input type="text" id="settingZip" class="form-input" placeholder="90001" maxlength="10">
</div>
</div>
<button type="submit" class="btn btn-primary" id="saveBusinessBtn">Save Changes</button>
</form>
</div>
</div>
<div class="card">
<div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
<h3>Business Hours</h3>
<button class="btn btn-sm btn-secondary" onclick="Portal.saveHours()">Save Hours</button>
</div>
<div class="card-body">
<div class="hours-list" id="hoursEditor">
<!-- Hours will be loaded here -->
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h3>Branding</h3>
</div>
<div class="card-body">
<div style="display: flex; flex-direction: column; gap: 16px;">
<div>
<label style="display: block; margin-bottom: 8px; font-weight: 500;">Header Image</label>
<p style="color: #666; font-size: 13px; margin-bottom: 8px;">Displayed at the top of your menu. Recommended: 1200x400px</p>
<div id="headerPreview" style="width: 100%; height: 120px; background: #fff; border-radius: 8px; margin-bottom: 8px; background-size: contain; background-position: center; background-repeat: no-repeat; border: 1px solid #ddd;"></div>
<button class="btn btn-secondary" onclick="Portal.uploadHeader()" style="width: 100%;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 8px;">
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12"/>
</svg>
Upload Header
</button>
</div>
<div>
<label style="display: block; margin-bottom: 8px; font-weight: 500;">Brand Color</label>
<p style="color: #666; font-size: 13px; margin-bottom: 8px;">Used for accents and fallback backgrounds</p>
<div style="display: flex; gap: 12px; align-items: center;">
<span id="brandColorSwatch" style="width: 40px; height: 40px; border-radius: 8px; background: #1B4D3E; border: 2px solid rgba(255,255,255,0.2); cursor: pointer;" onclick="Portal.showBrandColorPicker()"></span>
<button class="btn btn-secondary" onclick="Portal.showBrandColorPicker()" style="flex: 1;">
Change Color
</button>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h3>Payment Settings</h3>
</div>
<div class="card-body">
<div class="stripe-status" id="stripeStatus">
<div class="status-icon disconnected">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/>
<path d="M15 9l-6 6M9 9l6 6"/>
</svg>
</div>
<div class="status-text">
<strong>Stripe Not Connected</strong>
<p>Connect your Stripe account to accept payments</p>
</div>
<button class="btn btn-primary" onclick="Portal.connectStripe()">
Connect Stripe
</button>
</div>
</div>
</div>
<!-- COMMENTED OUT FOR LAUNCH - Tabs/Running Checks feature (coming soon)
<div class="card">
<div class="card-header">
<h3>Tabs / Running Checks</h3>
</div>
<div class="card-body">
<p style="color: #666; font-size: 13px; margin-bottom: 16px;">Allow customers to keep a tab open and order multiple rounds before closing out.</p>
<div class="form-group" style="display: flex; align-items: center; gap: 12px; margin-bottom: 16px;">
<label class="toggle">
<input type="checkbox" id="tabsEnabled" onchange="Portal.saveTabSettings()">
<span class="toggle-slider"></span>
</label>
<span>Enable Tabs</span>
</div>
<div id="tabSettingsDetails" style="display: none;">
<div class="form-group">
<label>Tab Lock Duration (minutes)</label>
<input type="number" id="tabLockMinutes" class="form-input" value="30" min="5" max="480" style="width: 120px;">
<small style="color:#666;font-size:12px;display:block;margin-top:4px;">How long a tab stays open without activity</small>
</div>
<div class="form-group" style="margin-top: 12px;">
<label>Payment Strategy</label>
<select id="tabPaymentStrategy" class="form-input" style="width: 200px;">
<option value="A">Pay at end (single charge)</option>
<option value="P">Pre-authorize card</option>
</select>
</div>
<button class="btn btn-primary" onclick="Portal.saveTabSettings()" style="margin-top: 12px;">Save Tab Settings</button>
</div>
</div>
</div>
END COMMENTED OUT -->
<div class="card">
<div class="card-header">
<h3>Customer Preview</h3>
</div>
<div class="card-body">
<p style="color: #666; font-size: 13px; margin-bottom: 12px;">See how your business looks in the Payfrit app. Open this link on your phone to preview your menu as a customer would see it.</p>
<a id="previewAppLink" href="#" onclick="Portal.openCustomerPreview(); return false;" class="btn btn-primary" style="display: inline-flex; align-items: center; gap: 8px; width: 100%; justify-content: center;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h4a2 2 0 012 2v14a2 2 0 01-2 2h-4M10 17l5-5-5-5M13 12H3"/>
</svg>
Open in Payfrit App
</a>
</div>
</div>
</div>
</section>
</div>
</main>
</div>
<!-- Modal Container -->
<div class="modal-overlay" id="modalOverlay">
<div class="modal" id="modal">
<div class="modal-header">
<h3 id="modalTitle">Modal</h3>
<button class="modal-close" onclick="Portal.closeModal()">&times;</button>
</div>
<div class="modal-body" id="modalBody">
<!-- Modal content loaded dynamically -->
</div>
</div>
</div>
<!-- Toast Container -->
<div class="toast-container" id="toastContainer"></div>
<script src="portal.js?v=13"></script>
<!-- Close dropdown when clicking outside -->
<script>
document.addEventListener('click', function(e) {
const dropdown = document.getElementById('userDropdown');
const userBtn = document.getElementById('userBtn');
if (dropdown && !dropdown.contains(e.target) && !userBtn.contains(e.target)) {
dropdown.classList.remove('show');
dropdown.style.display = 'none';
}
});
// Toggle show/hide
const origBtn = document.getElementById('userBtn');
if (origBtn) {
origBtn.addEventListener('click', function(e) {
e.stopPropagation();
const dd = document.getElementById('userDropdown');
if (dd.style.display === 'none' || dd.style.display === '') {
dd.style.display = 'block';
} else {
dd.style.display = 'none';
}
});
}
</script>
</body>
</html>