From 0b24bc21b61e82c299f2e8c1e246ce32fb675676 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Fri, 24 Jul 2026 22:55:34 +0300 Subject: [PATCH] Update: 2026-07-24 22:55:34 --- dashboard/siro-admin/css/main.css | 846 ++++++++++++++++++++++++++++ dashboard/siro-admin/index.html | 494 ++++++++++++++++ dashboard/siro-admin/js/app.js | 333 +++++++++++ dashboard/siro-service/css/main.css | 126 +++++ dashboard/siro-service/index.html | 61 ++ 5 files changed, 1860 insertions(+) create mode 100644 dashboard/siro-admin/css/main.css create mode 100644 dashboard/siro-admin/index.html create mode 100644 dashboard/siro-admin/js/app.js create mode 100644 dashboard/siro-service/css/main.css create mode 100644 dashboard/siro-service/index.html diff --git a/dashboard/siro-admin/css/main.css b/dashboard/siro-admin/css/main.css new file mode 100644 index 00000000..b4a752d3 --- /dev/null +++ b/dashboard/siro-admin/css/main.css @@ -0,0 +1,846 @@ +/* ========================================================================== + Siro Admin Web Portal - Modern Design System & CSS Stylesheet + ========================================================================== */ + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700&display=swap'); + +:root { + /* Color Tokens */ + --bg-dark: #090d16; + --bg-card: rgba(17, 24, 39, 0.7); + --bg-card-hover: rgba(30, 41, 59, 0.8); + --bg-surface: #111827; + --bg-elevated: #1e293b; + + --border-color: rgba(255, 255, 255, 0.08); + --border-active: rgba(99, 102, 241, 0.4); + + --primary: #6366f1; + --primary-hover: #4f46e5; + --primary-light: rgba(99, 102, 241, 0.15); + --accent-purple: #8b5cf6; + + --success: #10b981; + --success-bg: rgba(16, 185, 129, 0.15); + --warning: #f59e0b; + --warning-bg: rgba(245, 158, 11, 0.15); + --danger: #f43f5e; + --danger-bg: rgba(244, 63, 94, 0.15); + --info: #06b6d4; + --info-bg: rgba(6, 182, 212, 0.15); + + --text-main: #f8fafc; + --text-muted: #94a3b8; + --text-subtle: #64748b; + + --sidebar-width: 260px; + --header-height: 70px; + + --radius-sm: 8px; + --radius-md: 12px; + --radius-lg: 18px; + --radius-full: 9999px; + + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2); + --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.3); + --shadow-glow: 0 0 25px rgba(99, 102, 241, 0.25); + + --transition-fast: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + --transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +/* Reset & Global */ +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + font-family: 'Inter', system-ui, -apple-system, sans-serif; + background-color: var(--bg-dark); + color: var(--text-main); + min-height: 100vh; + overflow-x: hidden; + line-height: 1.5; +} + +h1, h2, h3, h4, h5, h6 { + font-family: 'Outfit', sans-serif; + letter-spacing: -0.02em; +} + +/* Custom Scrollbar */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: var(--bg-dark); +} + +::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.15); + border-radius: var(--radius-full); +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.3); +} + +/* Auth Page Overlay / Container */ +.auth-wrapper { + position: fixed; + inset: 0; + z-index: 1000; + background: radial-gradient(circle at 10% 20%, rgba(99, 102, 241, 0.15) 0%, transparent 40%), + radial-gradient(circle at 90% 80%, rgba(139, 92, 246, 0.15) 0%, transparent 40%), + var(--bg-dark); + display: flex; + align-items: center; + justify-content: center; + padding: 1.5rem; + transition: opacity 0.4s ease, visibility 0.4s ease; +} + +.auth-wrapper.hidden { + opacity: 0; + visibility: hidden; + pointer-events: none; +} + +.auth-card { + width: 100%; + max-width: 440px; + background: var(--bg-card); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 2.5rem; + box-shadow: var(--shadow-md); + position: relative; + overflow: hidden; +} + +.auth-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, var(--primary), var(--accent-purple)); +} + +.auth-header { + text-align: center; + margin-bottom: 2rem; +} + +.auth-logo { + display: inline-flex; + align-items: center; + gap: 0.75rem; + font-size: 1.75rem; + font-weight: 700; + color: #fff; + margin-bottom: 0.5rem; +} + +.auth-logo i { + color: var(--primary); + filter: drop-shadow(0 0 10px rgba(99, 102, 241, 0.6)); +} + +.auth-subtitle { + color: var(--text-muted); + font-size: 0.9rem; +} + +.form-group { + margin-bottom: 1.25rem; +} + +.form-label { + display: block; + font-size: 0.85rem; + font-weight: 500; + color: var(--text-muted); + margin-bottom: 0.5rem; +} + +.form-input-group { + position: relative; +} + +.form-input-group i { + position: absolute; + left: 1rem; + top: 50%; + transform: translateY(-50%); + color: var(--text-subtle); + font-size: 1.1rem; + transition: var(--transition-fast); +} + +.form-input { + width: 100%; + background: rgba(15, 23, 42, 0.6); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 0.75rem 1rem 0.75rem 2.8rem; + color: var(--text-main); + font-size: 0.95rem; + outline: none; + transition: var(--transition-fast); +} + +.form-input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px var(--primary-light); +} + +.form-input:focus + i, .form-input-group:focus-within i { + color: var(--primary); +} + +.btn-primary { + width: 100%; + padding: 0.85rem; + border-radius: var(--radius-md); + border: none; + background: linear-gradient(135deg, var(--primary), var(--accent-purple)); + color: #fff; + font-weight: 600; + font-size: 1rem; + cursor: pointer; + box-shadow: var(--shadow-glow); + transition: var(--transition-fast); + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; +} + +.btn-primary:hover { + opacity: 0.95; + transform: translateY(-1px); +} + +/* App Main Layout */ +.app-container { + display: flex; + min-height: 100vh; +} + +/* Sidebar */ +.sidebar { + width: var(--sidebar-width); + background: rgba(15, 23, 42, 0.95); + border-right: 1px solid var(--border-color); + display: flex; + flex-direction: column; + position: fixed; + top: 0; + bottom: 0; + left: 0; + z-index: 100; + transition: var(--transition-smooth); + backdrop-filter: blur(12px); +} + +.sidebar-header { + height: var(--header-height); + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 1.5rem; + border-bottom: 1px solid var(--border-color); +} + +.brand { + display: flex; + align-items: center; + gap: 0.75rem; + font-size: 1.4rem; + font-weight: 700; + color: var(--text-main); + text-decoration: none; +} + +.brand-icon { + width: 36px; + height: 36px; + border-radius: var(--radius-md); + background: linear-gradient(135deg, var(--primary), var(--accent-purple)); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 1.1rem; + box-shadow: var(--shadow-glow); +} + +.brand-badge { + font-size: 0.65rem; + padding: 0.15rem 0.4rem; + border-radius: var(--radius-sm); + background: var(--primary-light); + color: var(--primary); + font-weight: 600; + text-transform: uppercase; +} + +.sidebar-menu { + padding: 1.25rem 0.75rem; + flex: 1; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 0.35rem; +} + +.menu-label { + font-size: 0.75rem; + text-transform: uppercase; + color: var(--text-subtle); + font-weight: 600; + padding: 0.75rem 0.75rem 0.25rem; + letter-spacing: 0.05em; +} + +.nav-item { + display: flex; + align-items: center; + gap: 0.85rem; + padding: 0.75rem 1rem; + color: var(--text-muted); + text-decoration: none; + border-radius: var(--radius-md); + font-weight: 500; + font-size: 0.92rem; + transition: var(--transition-fast); + cursor: pointer; +} + +.nav-item i { + font-size: 1.1rem; + width: 20px; + text-align: center; +} + +.nav-item:hover { + color: var(--text-main); + background: rgba(255, 255, 255, 0.05); +} + +.nav-item.active { + color: #fff; + background: linear-gradient(90deg, var(--primary-light), transparent); + border-left: 3px solid var(--primary); +} + +.nav-item.active i { + color: var(--primary); +} + +.sidebar-footer { + padding: 1rem 1.25rem; + border-top: 1px solid var(--border-color); + display: flex; + align-items: center; + justify-content: space-between; +} + +.user-profile-mini { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.avatar { + width: 38px; + height: 38px; + border-radius: var(--radius-full); + background: linear-gradient(135deg, var(--info), var(--primary)); + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + color: #fff; +} + +.user-info .name { + font-size: 0.88rem; + font-weight: 600; + color: var(--text-main); +} + +.user-info .role { + font-size: 0.75rem; + color: var(--text-subtle); +} + +.btn-icon { + background: transparent; + border: 1px solid var(--border-color); + color: var(--text-muted); + width: 34px; + height: 34px; + border-radius: var(--radius-md); + display: inline-flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: var(--transition-fast); +} + +.btn-icon:hover { + color: var(--text-main); + border-color: rgba(255, 255, 255, 0.2); + background: rgba(255, 255, 255, 0.05); +} + +/* Main Content Area */ +.main-wrapper { + margin-left: var(--sidebar-width); + flex: 1; + display: flex; + flex-direction: column; + min-width: 0; +} + +/* Header */ +.top-header { + height: var(--header-height); + background: rgba(15, 23, 42, 0.8); + backdrop-filter: blur(12px); + border-bottom: 1px solid var(--border-color); + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 2rem; + position: sticky; + top: 0; + z-index: 90; +} + +.header-left { + display: flex; + align-items: center; + gap: 1rem; +} + +.toggle-sidebar-btn { + display: none; +} + +.search-box { + position: relative; + width: 320px; +} + +.search-box input { + width: 100%; + background: rgba(30, 41, 59, 0.5); + border: 1px solid var(--border-color); + border-radius: var(--radius-full); + padding: 0.5rem 1rem 0.5rem 2.5rem; + color: var(--text-main); + font-size: 0.88rem; + outline: none; + transition: var(--transition-fast); +} + +.search-box input:focus { + border-color: var(--primary); + background: rgba(30, 41, 59, 0.8); +} + +.search-box i { + position: absolute; + left: 0.9rem; + top: 50%; + transform: translateY(-50%); + color: var(--text-subtle); +} + +.header-right { + display: flex; + align-items: center; + gap: 1rem; +} + +.live-indicator { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.8rem; + color: var(--success); + background: var(--success-bg); + padding: 0.35rem 0.75rem; + border-radius: var(--radius-full); + font-weight: 500; +} + +.pulse-dot { + width: 8px; + height: 8px; + border-radius: var(--radius-full); + background: var(--success); + box-shadow: 0 0 8px var(--success); + animation: pulse 1.8s infinite; +} + +@keyframes pulse { + 0% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.4; transform: scale(0.85); } + 100% { opacity: 1; transform: scale(1); } +} + +/* Page Views */ +.content-body { + padding: 2rem; + flex: 1; +} + +.page-view { + display: none; + animation: fadeIn 0.3s ease; +} + +.page-view.active { + display: block; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(6px); } + to { opacity: 1; transform: translateY(0); } +} + +.page-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 1.75rem; +} + +.page-title h1 { + font-size: 1.75rem; + font-weight: 700; + color: #fff; +} + +.page-title p { + color: var(--text-muted); + font-size: 0.9rem; + margin-top: 0.2rem; +} + +.page-actions { + display: flex; + align-items: center; + gap: 0.75rem; +} + +/* Cards & Stats Grid */ +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 1.25rem; + margin-bottom: 1.75rem; +} + +.stat-card { + background: var(--bg-card); + backdrop-filter: blur(16px); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 1.5rem; + position: relative; + overflow: hidden; + transition: var(--transition-smooth); +} + +.stat-card:hover { + transform: translateY(-3px); + border-color: rgba(255, 255, 255, 0.15); + box-shadow: var(--shadow-md); +} + +.stat-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 1rem; +} + +.stat-icon { + width: 44px; + height: 44px; + border-radius: var(--radius-md); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.25rem; +} + +.stat-icon.primary { background: var(--primary-light); color: var(--primary); } +.stat-icon.success { background: var(--success-bg); color: var(--success); } +.stat-icon.warning { background: var(--warning-bg); color: var(--warning); } +.stat-icon.info { background: var(--info-bg); color: var(--info); } +.stat-icon.danger { background: var(--danger-bg); color: var(--danger); } + +.stat-value { + font-size: 1.85rem; + font-weight: 700; + color: #fff; + line-height: 1.2; +} + +.stat-title { + color: var(--text-muted); + font-size: 0.85rem; + font-weight: 500; + margin-top: 0.25rem; +} + +.stat-footer { + margin-top: 1rem; + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.8rem; +} + +.trend-badge { + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.15rem 0.5rem; + border-radius: var(--radius-full); + font-weight: 600; +} + +.trend-badge.up { background: var(--success-bg); color: var(--success); } +.trend-badge.down { background: var(--danger-bg); color: var(--danger); } + +.trend-text { + color: var(--text-subtle); +} + +/* Section Grid (Charts & Tables) */ +.dashboard-grid { + display: grid; + grid-template-columns: 2fr 1fr; + gap: 1.5rem; + margin-bottom: 1.75rem; +} + +@media (max-width: 1200px) { + .dashboard-grid { + grid-template-columns: 1fr; + } +} + +.card { + background: var(--bg-card); + backdrop-filter: blur(16px); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 1.5rem; +} + +.card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 1.25rem; +} + +.card-title { + font-size: 1.1rem; + font-weight: 600; + color: #fff; +} + +/* Custom CSS Charts */ +.chart-container { + height: 280px; + width: 100%; + position: relative; +} + +/* Data Tables */ +.table-responsive { + width: 100%; + overflow-x: auto; +} + +.data-table { + width: 100%; + border-collapse: collapse; + text-align: left; +} + +.data-table th { + background: rgba(15, 23, 42, 0.5); + color: var(--text-subtle); + font-size: 0.78rem; + text-transform: uppercase; + font-weight: 600; + padding: 0.85rem 1rem; + border-bottom: 1px solid var(--border-color); + letter-spacing: 0.05em; +} + +.data-table td { + padding: 0.95rem 1rem; + border-bottom: 1px solid var(--border-color); + color: var(--text-main); + font-size: 0.88rem; + vertical-align: middle; +} + +.data-table tbody tr { + transition: var(--transition-fast); +} + +.data-table tbody tr:hover { + background: rgba(255, 255, 255, 0.03); +} + +/* Badges */ +.badge { + display: inline-flex; + align-items: center; + gap: 0.35rem; + padding: 0.25rem 0.65rem; + border-radius: var(--radius-full); + font-size: 0.75rem; + font-weight: 600; +} + +.badge-success { background: var(--success-bg); color: var(--success); } +.badge-warning { background: var(--warning-bg); color: var(--warning); } +.badge-danger { background: var(--danger-bg); color: var(--danger); } +.badge-info { background: var(--info-bg); color: var(--info); } +.badge-primary { background: var(--primary-light); color: var(--primary); } + +/* Buttons */ +.btn { + padding: 0.55rem 1.1rem; + border-radius: var(--radius-md); + font-size: 0.88rem; + font-weight: 500; + cursor: pointer; + border: 1px solid transparent; + display: inline-flex; + align-items: center; + gap: 0.5rem; + transition: var(--transition-fast); + text-decoration: none; +} + +.btn-secondary { + background: rgba(255, 255, 255, 0.06); + border-color: var(--border-color); + color: var(--text-main); +} + +.btn-secondary:hover { + background: rgba(255, 255, 255, 0.12); +} + +.btn-sm { + padding: 0.35rem 0.75rem; + font-size: 0.8rem; +} + +/* Modal Overlay */ +.modal-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(8px); + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + pointer-events: none; + transition: var(--transition-smooth); +} + +.modal-overlay.active { + opacity: 1; + pointer-events: auto; +} + +.modal-content { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + width: 90%; + max-width: 550px; + padding: 2rem; + box-shadow: var(--shadow-md); + transform: translateY(20px); + transition: var(--transition-smooth); +} + +.modal-overlay.active .modal-content { + transform: translateY(0); +} + +/* Filter Bar */ +.filter-bar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + background: var(--bg-card); + padding: 1rem 1.25rem; + border-radius: var(--radius-lg); + border: 1px solid var(--border-color); + margin-bottom: 1.5rem; + flex-wrap: wrap; +} + +.filter-inputs { + display: flex; + align-items: center; + gap: 0.75rem; + flex-wrap: wrap; +} + +.select-input { + background: rgba(15, 23, 42, 0.7); + border: 1px solid var(--border-color); + color: var(--text-main); + padding: 0.5rem 1rem; + border-radius: var(--radius-md); + font-size: 0.88rem; + outline: none; +} + +/* Responsive adjustments */ +@media (max-width: 992px) { + .sidebar { + transform: translateX(-100%); + } + .sidebar.open { + transform: translateX(0); + } + .main-wrapper { + margin-left: 0; + } + .toggle-sidebar-btn { + display: inline-flex; + } + .search-box { + width: 200px; + } +} diff --git a/dashboard/siro-admin/index.html b/dashboard/siro-admin/index.html new file mode 100644 index 00000000..2e3ad481 --- /dev/null +++ b/dashboard/siro-admin/index.html @@ -0,0 +1,494 @@ + + + + + + Siro Admin | Enterprise Operations Dashboard + + + + + + + + + + + + + +
+
+
+ +

Enterprise Operations & Control Portal

+
+ +
+
+ +
+ + +
+
+ +
+ +
+ + +
+
+ + +
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+ +
+
+ Live Fleet Network +
+ + +
+
+ +
+ + +
+ + + +
+
+
+
+
$42,850
+
Today's Revenue
+
+
+
+ +
+ +
+
+
+
1,482
+
Active Rides
+
+
+
+ +
+ +
+
+
+
324
+
Captains Online
+
+
+
+ +
+ +
+
+
+
98.4%
+
Dispatch Rate
+
+
+
+ +
+
+ + +
+
+
+

Revenue & Trip Surge Analytics

+ +
+
+ +
+
+ +
+
+

Live Dispatch Feed

+
+
+
+
+ +
+
+
Ride SR-9842 Completed
+
Driver: Khalid H. | $14.50
+
+
+ +
+
+ +
+
+
New Dispatch SR-9846
+
Driver: Bilal M. | Sweifieh
+
+
+ +
+
+ +
+
+
5-Star Rating Submitted
+
Rider: Sarah M.
+
+
+
+
+
+
+ + +
+ + +
+
+ + +
+
+ +
+
+ + + + + + + + + + + + + + + + +
Trip IDPassengerDriverRouteFareStatusTimeAction
+
+
+
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + +
Driver IDNamePhoneVehicleRatingTotal TripsStatusAction
+
+
+
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + +
Customer IDNameEmailTrips CountRatingJoined DateAccount StatusAction
+
+
+
+ + +
+ + +
+
+
$184,200
+
Gross Revenue (This Month)
+
+
+
$27,630
+
Platform Net Commission (15%)
+
+
+
$156,570
+
Driver Payouts Processed
+
+
+
+ + +
+ + +
+
+ +

All high-priority complaints resolved

+

0 active tickets requiring immediate escalation.

+
+
+
+ + +
+ + +
+
+
+
+
Healthy
+
Location Server
+
+
+
+ +
+ +
+
+
+
Healthy
+
Ride Dispatch Engine
+
+
+
+ +
+ +
+
+
+
Healthy
+
Payment Server
+
+
+
+ +
+
+
+ +
+
+
+ + + + + + + diff --git a/dashboard/siro-admin/js/app.js b/dashboard/siro-admin/js/app.js new file mode 100644 index 00000000..ec8404f5 --- /dev/null +++ b/dashboard/siro-admin/js/app.js @@ -0,0 +1,333 @@ +/* ========================================================================== + Siro Admin Web Portal - Interactive Application Engine + ========================================================================== */ + +document.addEventListener('DOMContentLoaded', () => { + // DOM Elements + const authWrapper = document.getElementById('authWrapper'); + const loginForm = document.getElementById('loginForm'); + const navItems = document.querySelectorAll('.nav-item[data-view]'); + const pageViews = document.querySelectorAll('.page-view'); + const logoutBtn = document.getElementById('logoutBtn'); + const sidebar = document.getElementById('sidebar'); + const toggleSidebarBtn = document.getElementById('toggleSidebar'); + + // Sample State & Datasets + let currentUser = JSON.parse(localStorage.getItem('siro_admin_user')) || null; + + const mockRides = [ + { id: 'SR-9842', rider: 'Ahmad Al-Mansoor', driver: 'Khalid Hassan', pickup: 'Abdoun, Amman', dropoff: '7th Circle', fare: '$14.50', status: 'Completed', time: '10 mins ago' }, + { id: 'SR-9843', rider: 'Sarah Mahmoud', driver: 'Omar Farooq', pickup: 'Jabal Amman', dropoff: 'Queen Alia Airport', fare: '$28.00', status: 'In Progress', time: 'Just now' }, + { id: 'SR-9844', rider: 'Tariq Ziyad', driver: 'Youssef Ali', pickup: 'Sweifieh Mall', dropoff: 'University of Jordan', fare: '$9.20', status: 'Completed', time: '25 mins ago' }, + { id: 'SR-9845', rider: 'Reem Kanaan', driver: 'Hassan Nabil', pickup: 'Mecca Street', dropoff: 'Tabarbour', fare: '$11.80', status: 'Cancelled', time: '40 mins ago' }, + { id: 'SR-9846', rider: 'Fadi Jarrah', driver: 'Bilal Mustafa', pickup: 'Khalda', dropoff: 'Shmeisani', fare: '$16.00', status: 'In Progress', time: '5 mins ago' }, + ]; + + const mockDrivers = [ + { id: 'DRV-101', name: 'Khalid Hassan', phone: '+962 7 9123 4567', vehicle: 'Toyota Camry 2022', rating: '4.95', trips: 1420, status: 'Online', verified: true }, + { id: 'DRV-102', name: 'Omar Farooq', phone: '+962 7 8876 5432', vehicle: 'Hyundai Elantra 2021', rating: '4.88', trips: 980, status: 'In Trip', verified: true }, + { id: 'DRV-103', name: 'Youssef Ali', phone: '+962 7 7654 3210', vehicle: 'Kia Optima 2023', rating: '4.90', trips: 1150, status: 'Online', verified: true }, + { id: 'DRV-104', name: 'Hassan Nabil', phone: '+962 7 9988 7766', vehicle: 'Nissan Sentra 2020', rating: '4.72', trips: 620, status: 'Offline', verified: false }, + ]; + + const mockPassengers = [ + { id: 'PSG-501', name: 'Ahmad Al-Mansoor', email: 'ahmad@example.com', trips: 45, rating: '4.9', joined: 'Jan 2025', status: 'Active' }, + { id: 'PSG-502', name: 'Sarah Mahmoud', email: 'sarah.m@example.com', trips: 89, rating: '5.0', joined: 'Nov 2024', status: 'Active' }, + { id: 'PSG-503', name: 'Reem Kanaan', email: 'reem.k@example.com', trips: 12, rating: '4.6', joined: 'Mar 2025', status: 'Suspended' }, + ]; + + // Initialize App + function initApp() { + checkAuth(); + setupNavigation(); + renderRidesTable(); + renderDriversTable(); + renderPassengersTable(); + initCharts(); + setupEvents(); + } + + // Auth Functions + function checkAuth() { + if (currentUser) { + authWrapper.classList.add('hidden'); + } else { + authWrapper.classList.remove('hidden'); + } + } + + loginForm?.addEventListener('submit', (e) => { + e.preventDefault(); + const email = document.getElementById('loginEmail').value; + currentUser = { name: 'Super Admin', email: email, role: 'Administrator' }; + localStorage.setItem('siro_admin_user', JSON.stringify(currentUser)); + authWrapper.classList.add('hidden'); + showNotification('Welcome back, Super Admin!', 'success'); + }); + + logoutBtn?.addEventListener('click', () => { + localStorage.removeItem('siro_admin_user'); + currentUser = null; + authWrapper.classList.remove('hidden'); + }); + + // Sidebar & Navigation + function setupNavigation() { + navItems.forEach(item => { + item.addEventListener('click', (e) => { + e.preventDefault(); + const targetView = item.getAttribute('data-view'); + + navItems.forEach(n => n.classList.remove('active')); + item.classList.add('active'); + + pageViews.forEach(view => { + if (view.id === targetView) { + view.classList.add('active'); + } else { + view.classList.remove('active'); + } + }); + + // Close sidebar on mobile + if (window.innerWidth <= 992) { + sidebar.classList.remove('open'); + } + }); + }); + + toggleSidebarBtn?.addEventListener('click', () => { + sidebar.classList.toggle('open'); + }); + } + + // Render Data Tables + function renderRidesTable() { + const tbody = document.getElementById('ridesTableBody'); + if (!tbody) return; + tbody.innerHTML = mockRides.map(ride => ` + + ${ride.id} + ${ride.rider} + ${ride.driver} + ${ride.pickup} → ${ride.dropoff} + ${ride.fare} + ${ride.status} + ${ride.time} + + + + + `).join(''); + } + + function renderDriversTable() { + const tbody = document.getElementById('driversTableBody'); + if (!tbody) return; + tbody.innerHTML = mockDrivers.map(drv => ` + + ${drv.id} + +
+ ${drv.name} + ${drv.verified ? '' : ''} +
+ + ${drv.phone} + ${drv.vehicle} + ${drv.rating} + ${drv.trips} + ${drv.status} + + + + + `).join(''); + } + + function renderPassengersTable() { + const tbody = document.getElementById('passengersTableBody'); + if (!tbody) return; + tbody.innerHTML = mockPassengers.map(p => ` + + ${p.id} + ${p.name} + ${p.email} + ${p.trips} trips + ${p.rating} + ${p.joined} + ${p.status} + + + + + `).join(''); + } + + function getStatusBadge(status) { + switch (status) { + case 'Completed': + case 'Online': + case 'Active': + return 'badge-success'; + case 'In Progress': + case 'In Trip': + return 'badge-primary'; + case 'Cancelled': + case 'Offline': + case 'Suspended': + return 'badge-danger'; + default: + return 'badge-info'; + } + } + + // Dynamic Canvas Charts + function initCharts() { + const canvas = document.getElementById('revenueChart'); + if (!canvas) return; + const ctx = canvas.getContext('2d'); + + // Resize canvas + canvas.width = canvas.parentElement.clientWidth; + canvas.height = canvas.parentElement.clientHeight; + + const data = [12000, 18500, 15000, 24000, 29000, 34500, 42000]; + const labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; + + const W = canvas.width; + const H = canvas.height; + const padding = 40; + + // Draw Grid Lines + ctx.strokeStyle = 'rgba(255, 255, 255, 0.05)'; + ctx.lineWidth = 1; + for (let i = 0; i <= 4; i++) { + const y = padding + (i * (H - padding * 2) / 4); + ctx.beginPath(); + ctx.moveTo(padding, y); + ctx.lineTo(W - padding, y); + ctx.stroke(); + } + + // Draw Smooth Line + const max = 50000; + const points = data.map((val, idx) => { + const x = padding + (idx * (W - padding * 2) / (data.length - 1)); + const y = H - padding - (val / max * (H - padding * 2)); + return { x, y }; + }); + + // Area Gradient + const gradient = ctx.createLinearGradient(0, 0, 0, H); + gradient.addColorStop(0, 'rgba(99, 102, 241, 0.4)'); + gradient.addColorStop(1, 'rgba(99, 102, 241, 0.0)'); + + ctx.beginPath(); + ctx.moveTo(points[0].x, points[0].y); + for (let i = 1; i < points.length; i++) { + const xc = (points[i].x + points[i - 1].x) / 2; + const yc = (points[i].y + points[i - 1].y) / 2; + ctx.quadraticCurveTo(points[i - 1].x, points[i - 1].y, xc, yc); + } + ctx.lineTo(points[points.length - 1].x, points[points.length - 1].y); + ctx.lineTo(points[points.length - 1].x, H - padding); + ctx.lineTo(points[0].x, H - padding); + ctx.closePath(); + ctx.fillStyle = gradient; + ctx.fill(); + + // Line Path + ctx.beginPath(); + ctx.moveTo(points[0].x, points[0].y); + for (let i = 1; i < points.length; i++) { + const xc = (points[i].x + points[i - 1].x) / 2; + const yc = (points[i].y + points[i - 1].y) / 2; + ctx.quadraticCurveTo(points[i - 1].x, points[i - 1].y, xc, yc); + } + ctx.lineTo(points[points.length - 1].x, points[points.length - 1].y); + ctx.strokeStyle = '#6366f1'; + ctx.lineWidth = 3; + ctx.stroke(); + + // Draw Points + points.forEach((p, idx) => { + ctx.beginPath(); + ctx.arc(p.x, p.y, 5, 0, Math.PI * 2); + ctx.fillStyle = '#6366f1'; + ctx.fill(); + ctx.lineWidth = 2; + ctx.strokeStyle = '#fff'; + ctx.stroke(); + + // Labels + ctx.fillStyle = '#94a3b8'; + ctx.font = '12px Inter'; + ctx.textAlign = 'center'; + ctx.fillText(labels[idx], p.x, H - 15); + }); + } + + // Setup Event Listeners & Search Filters + function setupEvents() { + window.addEventListener('resize', () => { + initCharts(); + }); + + const searchInput = document.getElementById('globalSearch'); + searchInput?.addEventListener('input', (e) => { + const query = e.target.value.toLowerCase(); + // Highlight matching items in tables if any + }); + } + + // Notifications Helper + function showNotification(msg, type = 'info') { + const toast = document.createElement('div'); + toast.style.cssText = ` + position: fixed; + bottom: 24px; + right: 24px; + background: var(--bg-elevated); + border: 1px solid var(--border-active); + color: #fff; + padding: 12px 20px; + border-radius: 12px; + box-shadow: var(--shadow-md); + z-index: 9999; + font-size: 0.9rem; + animation: fadeIn 0.3s ease; + `; + toast.innerHTML = ` ${msg}`; + document.body.appendChild(toast); + setTimeout(() => toast.remove(), 3500); + } + + window.viewDetails = function(id) { + const modal = document.getElementById('detailsModal'); + const modalBody = document.getElementById('modalBodyContent'); + if (!modal || !modalBody) return; + + modalBody.innerHTML = ` +

Ride Details: ${id}

+

Pickup: Abdoun Circle, Amman

+

Dropoff: Queen Alia International Airport

+

Fare Breakdown: Base Fare ($4.00) + Distance ($20.00) + Peak Surge ($4.00)

+

Payment Method: Credit Card (Visa **** 4921)

+
+ +
+ `; + modal.classList.add('active'); + }; + + window.closeModal = function() { + const modal = document.getElementById('detailsModal'); + modal?.classList.remove('active'); + }; + + // Run initial state + initApp(); +}); diff --git a/dashboard/siro-service/css/main.css b/dashboard/siro-service/css/main.css new file mode 100644 index 00000000..ca917433 --- /dev/null +++ b/dashboard/siro-service/css/main.css @@ -0,0 +1,126 @@ +/* ========================================================================== + Siro Service Web Portal - Modern Design System + ========================================================================== */ + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700&display=swap'); + +:root { + --bg-dark: #090d16; + --bg-card: rgba(17, 24, 39, 0.75); + --border-color: rgba(255, 255, 255, 0.08); + --primary: #06b6d4; + --accent: #3b82f6; + --text-main: #f8fafc; + --text-muted: #94a3b8; + --radius-lg: 18px; +} + +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + font-family: 'Inter', sans-serif; + background-color: var(--bg-dark); + color: var(--text-main); + min-height: 100vh; + display: flex; + flex-direction: column; +} + +header { + padding: 1.5rem 3rem; + border-bottom: 1px solid var(--border-color); + display: flex; + align-items: center; + justify-content: space-between; + backdrop-filter: blur(12px); +} + +.logo { + display: flex; + align-items: center; + gap: 0.75rem; + font-family: 'Outfit', sans-serif; + font-size: 1.5rem; + font-weight: 700; +} + +.logo i { + color: var(--primary); +} + +main { + flex: 1; + padding: 3rem; + max-width: 1200px; + margin: 0 auto; + width: 100%; +} + +.hero-card { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 3rem; + text-align: center; + backdrop-filter: blur(16px); +} + +.hero-card h1 { + font-size: 2.25rem; + margin-bottom: 1rem; + background: linear-gradient(135deg, #fff, var(--primary)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.services-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; + margin-top: 2.5rem; +} + +.service-card { + background: rgba(30, 41, 59, 0.4); + border: 1px solid var(--border-color); + border-radius: 14px; + padding: 1.75rem; + text-align: left; + transition: all 0.3s ease; +} + +.service-card:hover { + transform: translateY(-4px); + border-color: var(--primary); +} + +.service-icon { + width: 48px; + height: 48px; + border-radius: 12px; + background: rgba(6, 182, 212, 0.15); + color: var(--primary); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + margin-bottom: 1rem; +} + +.btn-cyan { + background: linear-gradient(135deg, var(--primary), var(--accent)); + color: white; + padding: 0.75rem 1.5rem; + border-radius: 10px; + border: none; + font-weight: 600; + cursor: pointer; + margin-top: 1.5rem; + display: inline-flex; + align-items: center; + gap: 0.5rem; +} diff --git a/dashboard/siro-service/index.html b/dashboard/siro-service/index.html new file mode 100644 index 00000000..1d54ab81 --- /dev/null +++ b/dashboard/siro-service/index.html @@ -0,0 +1,61 @@ + + + + + + Siro Service | Fleet & Maintenance Portal + + + + + + + + + + +
+ +
+ Service Hub Online +
+
+ +
+
+

Siro Fleet Maintenance & Service Center

+

+ Dedicated web portal for registered service centers, vehicle inspection, maintenance scheduling, and captain support services. +

+ +
+
+
+

Vehicle Inspection

+

Perform 50-point technical inspections and issue digital safety permits for captains.

+
+ +
+
+

Fuel & EV Charging

+

Manage partner station discounts, EV charging session ledgers, and fuel vouchers.

+
+ +
+
+

Maintenance Scheduling

+

Routine oil changes, tire rotations, and scheduled service appointments for active fleet.

+
+
+ + +
+
+ + +