Updates currency representation consistently to use 'DKK' instead of 'kr' Standardizes number formatting across product, order, and pricing displays Improves localization and visual consistency
2509 lines
68 KiB
HTML
2509 lines
68 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="da">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Salon OS</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/regular/style.css" />
|
|
<style>
|
|
/* ==========================================
|
|
FONT FACE (Poppins)
|
|
========================================== */
|
|
@font-face {
|
|
font-family: 'Poppins';
|
|
src: url('fonts/Poppins-Regular.woff') format('woff');
|
|
font-weight: 400;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
}
|
|
@font-face {
|
|
font-family: 'Poppins';
|
|
src: url('fonts/Poppins-Medium.woff') format('woff');
|
|
font-weight: 500;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
}
|
|
@font-face {
|
|
font-family: 'Poppins';
|
|
src: url('fonts/Poppins-SemiBold.woff') format('woff');
|
|
font-weight: 600;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
}
|
|
@font-face {
|
|
font-family: 'Poppins';
|
|
src: url('fonts/Poppins-Bold.woff') format('woff');
|
|
font-weight: 700;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
}
|
|
|
|
/* ==========================================
|
|
CSS VARIABLES (Design System)
|
|
========================================== */
|
|
:root {
|
|
--color-surface: #fff;
|
|
--color-background: #f5f5f5;
|
|
--color-background-hover: #f0f0f0;
|
|
--color-background-alt: #fafafa;
|
|
--color-border: #e0e0e0;
|
|
--color-text: #333;
|
|
--color-text-secondary: #666;
|
|
--color-teal: #00897b;
|
|
--color-blue: #1976d2;
|
|
--color-red: #e53935;
|
|
--color-amber: #f59e0b;
|
|
--color-purple: #8b5cf6;
|
|
--color-green: #43a047;
|
|
--font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
--font-mono: 'JetBrains Mono', monospace;
|
|
|
|
/* Layout */
|
|
--side-menu-width: 240px;
|
|
--side-menu-width-collapsed: 64px;
|
|
--topbar-height: 56px;
|
|
}
|
|
|
|
/* Dark mode - system preference */
|
|
@media (prefers-color-scheme: dark) {
|
|
:root:not(.light-mode) {
|
|
--color-surface: #1e1e1e;
|
|
--color-background: #121212;
|
|
--color-background-hover: #2a2a2a;
|
|
--color-background-alt: #1a1a1a;
|
|
--color-border: #333;
|
|
--color-text: #e0e0e0;
|
|
--color-text-secondary: #999;
|
|
--color-teal: #26a69a;
|
|
--color-blue: #42a5f5;
|
|
--color-red: #ef5350;
|
|
--color-amber: #ffb74d;
|
|
--color-purple: #a78bfa;
|
|
--color-green: #66bb6a;
|
|
}
|
|
}
|
|
|
|
/* Manual dark mode override */
|
|
:root.dark-mode {
|
|
--color-surface: #1e1e1e;
|
|
--color-background: #121212;
|
|
--color-background-hover: #2a2a2a;
|
|
--color-background-alt: #1a1a1a;
|
|
--color-border: #333;
|
|
--color-text: #e0e0e0;
|
|
--color-text-secondary: #999;
|
|
--color-teal: #26a69a;
|
|
--color-blue: #42a5f5;
|
|
--color-red: #ef5350;
|
|
--color-amber: #ffb74d;
|
|
--color-purple: #a78bfa;
|
|
--color-green: #66bb6a;
|
|
}
|
|
|
|
/* ==========================================
|
|
RESET & BASE
|
|
========================================== */
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html, body {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-family);
|
|
font-size: 14px;
|
|
color: var(--color-text);
|
|
background: var(--color-background);
|
|
line-height: 1.5;
|
|
}
|
|
|
|
a {
|
|
color: var(--color-teal);
|
|
text-decoration: none;
|
|
}
|
|
|
|
a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* ==========================================
|
|
APP LAYOUT
|
|
========================================== */
|
|
swp-app-layout {
|
|
display: grid;
|
|
grid-template-columns: var(--side-menu-width) 1fr;
|
|
grid-template-rows: var(--topbar-height) 1fr;
|
|
height: 100vh;
|
|
}
|
|
|
|
/* ==========================================
|
|
SIDE MENU
|
|
========================================== */
|
|
swp-side-menu {
|
|
grid-row: 1 / -1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: var(--color-surface);
|
|
border-right: 1px solid var(--color-border);
|
|
overflow-y: auto;
|
|
}
|
|
|
|
swp-side-menu-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
height: var(--topbar-height);
|
|
padding: 0 16px;
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-side-menu-header i {
|
|
font-size: 26px;
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
swp-side-menu-logo {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-menu-toggle {
|
|
margin-left: auto;
|
|
width: 28px;
|
|
height: 28px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: none;
|
|
background: transparent;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
color: var(--color-text-secondary);
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-menu-toggle:hover {
|
|
background: var(--color-background-hover);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-menu-toggle i {
|
|
font-size: 18px;
|
|
color: inherit;
|
|
transition: transform 200ms ease;
|
|
}
|
|
|
|
swp-side-menu-nav {
|
|
flex: 1;
|
|
padding: 12px 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
swp-side-menu-group {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
swp-side-menu-label {
|
|
display: block;
|
|
padding: 8px 16px 6px;
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-side-menu-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 10px 16px;
|
|
color: var(--color-text);
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
border-left: 3px solid transparent;
|
|
text-decoration: none;
|
|
}
|
|
|
|
swp-side-menu-item:hover {
|
|
background: var(--color-background-hover);
|
|
text-decoration: none;
|
|
}
|
|
|
|
swp-side-menu-item[data-active="true"] {
|
|
background: color-mix(in srgb, var(--color-teal) 10%, transparent);
|
|
border-left-color: var(--color-teal);
|
|
color: var(--color-teal);
|
|
font-weight: 500;
|
|
}
|
|
|
|
swp-side-menu-item i {
|
|
font-size: 20px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
swp-side-menu-footer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
padding: 12px 16px;
|
|
border-top: 1px solid var(--color-border);
|
|
margin-top: auto;
|
|
}
|
|
|
|
swp-side-menu-action {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
padding: 10px;
|
|
font-size: 13px;
|
|
color: var(--color-text-secondary);
|
|
background: transparent;
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
font-family: var(--font-family);
|
|
}
|
|
|
|
swp-side-menu-action:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-side-menu-action.lock:hover {
|
|
color: var(--color-amber);
|
|
border-color: var(--color-amber);
|
|
}
|
|
|
|
swp-side-menu-action.logout:hover {
|
|
color: var(--color-red);
|
|
border-color: var(--color-red);
|
|
}
|
|
|
|
swp-side-menu-action i {
|
|
font-size: 18px;
|
|
}
|
|
|
|
/* ==========================================
|
|
SIDE MENU - COLLAPSED STATE
|
|
========================================== */
|
|
swp-app-layout {
|
|
transition: grid-template-columns 200ms ease;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed {
|
|
grid-template-columns: var(--side-menu-width-collapsed) 1fr;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-side-menu {
|
|
overflow: visible;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-side-menu-logo,
|
|
swp-app-layout.menu-collapsed swp-side-menu-label,
|
|
swp-app-layout.menu-collapsed swp-side-menu-item span,
|
|
swp-app-layout.menu-collapsed swp-side-menu-action span {
|
|
display: none;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-side-menu-header {
|
|
justify-content: center;
|
|
padding: 0;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-menu-toggle {
|
|
margin-left: 0;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-menu-toggle i {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-side-menu-item {
|
|
justify-content: center;
|
|
padding: 12px;
|
|
border-left: none;
|
|
position: relative;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-side-menu-item[data-active="true"] {
|
|
border-left: none;
|
|
border-radius: 8px;
|
|
margin: 0 8px;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-side-menu-action {
|
|
justify-content: center;
|
|
padding: 12px;
|
|
}
|
|
|
|
swp-app-layout.menu-collapsed swp-side-menu-footer {
|
|
padding: 12px 8px;
|
|
}
|
|
|
|
/* Popover tooltip for collapsed menu */
|
|
.swp-menu-tooltip {
|
|
position: fixed;
|
|
margin: 0;
|
|
padding: 6px 12px;
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 6px;
|
|
font-size: 13px;
|
|
font-family: var(--font-family);
|
|
color: var(--color-text);
|
|
white-space: nowrap;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* ==========================================
|
|
TOP BAR
|
|
========================================== */
|
|
swp-app-topbar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 20px;
|
|
background: var(--color-surface);
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-topbar-search {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 8px 14px;
|
|
background: var(--color-background);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 6px;
|
|
width: 320px;
|
|
transition: border-color 150ms ease;
|
|
}
|
|
|
|
swp-topbar-search:focus-within {
|
|
border-color: var(--color-teal);
|
|
}
|
|
|
|
swp-topbar-search i {
|
|
font-size: 18px;
|
|
color: var(--color-text-secondary);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
swp-topbar-search input {
|
|
flex: 1;
|
|
border: none;
|
|
outline: none;
|
|
background: transparent;
|
|
font-size: 13px;
|
|
font-family: var(--font-family);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-topbar-search input::placeholder {
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-topbar-search kbd {
|
|
font-size: 11px;
|
|
font-family: var(--font-mono);
|
|
padding: 2px 6px;
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 4px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-topbar-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
swp-topbar-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 38px;
|
|
height: 38px;
|
|
border: none;
|
|
background: transparent;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: background 150ms ease;
|
|
position: relative;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-topbar-btn:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-topbar-btn i {
|
|
font-size: 22px;
|
|
}
|
|
|
|
swp-notification-badge {
|
|
position: absolute;
|
|
top: 6px;
|
|
right: 6px;
|
|
min-width: 16px;
|
|
height: 16px;
|
|
padding: 0 4px;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
background: var(--color-red);
|
|
color: white;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
swp-topbar-divider {
|
|
width: 1px;
|
|
height: 24px;
|
|
background: var(--color-border);
|
|
margin: 0 8px;
|
|
}
|
|
|
|
swp-topbar-profile {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 6px 12px 6px 6px;
|
|
background: transparent;
|
|
border: 1px solid transparent;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
position: relative;
|
|
}
|
|
|
|
swp-topbar-profile:hover {
|
|
background: var(--color-background-hover);
|
|
border-color: var(--color-border);
|
|
}
|
|
|
|
swp-profile-avatar {
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
background: var(--color-purple);
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
swp-profile-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
text-align: left;
|
|
}
|
|
|
|
swp-profile-name {
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-profile-role {
|
|
font-size: 11px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
/* ==========================================
|
|
PROFILE DRAWER
|
|
========================================== */
|
|
swp-drawer-overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0, 0, 0, 0.2);
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 200ms ease, visibility 200ms ease;
|
|
z-index: 900;
|
|
}
|
|
|
|
swp-drawer-overlay.open {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
swp-profile-drawer {
|
|
position: fixed;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
width: 320px;
|
|
background: var(--color-surface);
|
|
border-left: 1px solid var(--color-border);
|
|
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
|
transform: translateX(100%);
|
|
transition: transform 200ms ease;
|
|
display: flex;
|
|
flex-direction: column;
|
|
z-index: 1000;
|
|
}
|
|
|
|
swp-profile-drawer.open {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
swp-drawer-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 14px 16px;
|
|
border-bottom: 1px solid var(--color-border);
|
|
background: var(--color-background-alt);
|
|
}
|
|
|
|
swp-drawer-title {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-drawer-close {
|
|
width: 32px;
|
|
height: 32px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: none;
|
|
background: transparent;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
color: var(--color-text-secondary);
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-drawer-close:hover {
|
|
background: var(--color-background-hover);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-drawer-close i {
|
|
font-size: 20px;
|
|
}
|
|
|
|
swp-drawer-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 20px 16px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
}
|
|
|
|
/* Profile header in drawer */
|
|
swp-drawer-profile {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
text-align: center;
|
|
padding-bottom: 20px;
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-drawer-avatar {
|
|
width: 72px;
|
|
height: 72px;
|
|
border-radius: 50%;
|
|
background: var(--color-purple);
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
swp-drawer-name {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: var(--color-text);
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
swp-drawer-role {
|
|
font-size: 13px;
|
|
color: var(--color-text-secondary);
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
swp-drawer-email {
|
|
font-size: 13px;
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
/* Drawer sections */
|
|
swp-drawer-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
swp-drawer-section-label {
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
color: var(--color-text-secondary);
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
swp-drawer-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 12px;
|
|
background: var(--color-background-alt);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: background 150ms ease;
|
|
}
|
|
|
|
swp-drawer-item:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-drawer-item i {
|
|
font-size: 20px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-drawer-item-text {
|
|
flex: 1;
|
|
font-size: 14px;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-drawer-item-hint {
|
|
font-size: 12px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
/* Theme toggle in drawer - two icons */
|
|
swp-theme-toggle {
|
|
display: flex;
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
swp-theme-option {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 12px;
|
|
background: var(--color-background-alt);
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-theme-option:first-child {
|
|
border-right: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-theme-option i {
|
|
font-size: 20px;
|
|
color: var(--color-text-secondary);
|
|
transition: color 150ms ease;
|
|
}
|
|
|
|
swp-theme-option:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-theme-option.active {
|
|
background: color-mix(in srgb, var(--color-teal) 12%, transparent);
|
|
}
|
|
|
|
swp-theme-option.active i {
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
/* Drawer footer */
|
|
swp-drawer-footer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
padding: 16px;
|
|
border-top: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-drawer-action {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
padding: 12px;
|
|
font-size: 14px;
|
|
font-family: var(--font-family);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
background: transparent;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-drawer-action:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-drawer-action.lock:hover {
|
|
color: var(--color-amber);
|
|
border-color: var(--color-amber);
|
|
}
|
|
|
|
swp-drawer-action.logout:hover {
|
|
color: var(--color-red);
|
|
border-color: var(--color-red);
|
|
}
|
|
|
|
swp-drawer-action i {
|
|
font-size: 18px;
|
|
}
|
|
|
|
/* ==========================================
|
|
NOTIFICATION DRAWER
|
|
========================================== */
|
|
swp-notification-drawer {
|
|
position: fixed;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
width: 380px;
|
|
background: var(--color-surface);
|
|
border-left: 1px solid var(--color-border);
|
|
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
|
transform: translateX(100%);
|
|
transition: transform 200ms ease;
|
|
display: flex;
|
|
flex-direction: column;
|
|
z-index: 1000;
|
|
}
|
|
|
|
swp-notification-drawer.open {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
swp-notification-drawer swp-drawer-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 14px 16px;
|
|
border-bottom: 1px solid var(--color-border);
|
|
background: var(--color-background-alt);
|
|
}
|
|
|
|
swp-drawer-header-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
swp-mark-read-btn {
|
|
padding: 6px 12px;
|
|
font-size: 12px;
|
|
font-family: var(--font-family);
|
|
color: var(--color-teal);
|
|
background: transparent;
|
|
border: 1px solid var(--color-teal);
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-mark-read-btn:hover {
|
|
background: var(--color-teal);
|
|
color: white;
|
|
}
|
|
|
|
swp-notification-drawer swp-drawer-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
swp-notification-item {
|
|
display: flex;
|
|
gap: 12px;
|
|
padding: 12px;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: background 150ms ease;
|
|
background: transparent;
|
|
}
|
|
|
|
swp-notification-item:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-notification-item[data-unread="true"] {
|
|
background: var(--color-background-alt);
|
|
}
|
|
|
|
swp-notification-item[data-unread="true"]::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 4px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 6px;
|
|
height: 6px;
|
|
background: var(--color-teal);
|
|
border-radius: 50%;
|
|
}
|
|
|
|
swp-notification-icon {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
swp-notification-icon i {
|
|
font-size: 20px;
|
|
}
|
|
|
|
swp-notification-icon.booking {
|
|
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
swp-notification-icon.smiley {
|
|
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
|
|
color: var(--color-amber);
|
|
}
|
|
|
|
swp-notification-icon.call {
|
|
background: color-mix(in srgb, var(--color-blue) 15%, transparent);
|
|
color: var(--color-blue);
|
|
}
|
|
|
|
swp-notification-icon.mail {
|
|
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
|
|
color: var(--color-purple);
|
|
}
|
|
|
|
swp-notification-icon.chat {
|
|
background: color-mix(in srgb, var(--color-green) 15%, transparent);
|
|
color: var(--color-green);
|
|
}
|
|
|
|
swp-notification-icon.reminder {
|
|
background: color-mix(in srgb, var(--color-red) 15%, transparent);
|
|
color: var(--color-red);
|
|
}
|
|
|
|
swp-notification-content {
|
|
flex: 1;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
swp-notification-title {
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-notification-text {
|
|
font-size: 13px;
|
|
color: var(--color-text-secondary);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
swp-notification-time {
|
|
font-size: 11px;
|
|
color: var(--color-text-secondary);
|
|
margin-top: 2px;
|
|
}
|
|
|
|
swp-notification-empty {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 48px 24px;
|
|
text-align: center;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-notification-empty i {
|
|
font-size: 48px;
|
|
margin-bottom: 12px;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
/* ==========================================
|
|
TODO DRAWER
|
|
========================================== */
|
|
swp-todo-drawer {
|
|
position: fixed;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
width: 380px;
|
|
background: var(--color-surface);
|
|
border-left: 1px solid var(--color-border);
|
|
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
|
transform: translateX(100%);
|
|
transition: transform 200ms ease;
|
|
display: flex;
|
|
flex-direction: column;
|
|
z-index: 1001;
|
|
}
|
|
|
|
swp-todo-drawer.open {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
/* New Todo Drawer - slides from left of todo drawer */
|
|
swp-new-todo-drawer {
|
|
position: fixed;
|
|
top: 0;
|
|
right: 380px;
|
|
bottom: 0;
|
|
width: 340px;
|
|
background: var(--color-surface);
|
|
border-left: 1px solid var(--color-border);
|
|
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
|
transform: translateX(100%);
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1),
|
|
opacity 200ms ease;
|
|
display: flex;
|
|
flex-direction: column;
|
|
z-index: 1000;
|
|
}
|
|
|
|
swp-new-todo-drawer.open {
|
|
transform: translateX(0);
|
|
opacity: 1;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
swp-todo-drawer swp-drawer-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 14px 16px;
|
|
border-bottom: 1px solid var(--color-border);
|
|
background: var(--color-background-alt);
|
|
}
|
|
|
|
swp-todo-drawer swp-drawer-title {
|
|
flex: 1;
|
|
}
|
|
|
|
swp-drawer-back {
|
|
width: 32px;
|
|
height: 32px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: none;
|
|
background: transparent;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
color: var(--color-text-secondary);
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-drawer-back:hover {
|
|
background: var(--color-background-hover);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-drawer-back i {
|
|
font-size: 20px;
|
|
}
|
|
|
|
swp-add-todo-btn {
|
|
width: 32px;
|
|
height: 32px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: var(--color-teal);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-add-todo-btn:hover {
|
|
background: color-mix(in srgb, var(--color-teal) 85%, black);
|
|
}
|
|
|
|
swp-add-todo-btn i {
|
|
font-size: 18px;
|
|
}
|
|
|
|
swp-todo-drawer swp-drawer-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 16px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
}
|
|
|
|
swp-todo-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
swp-todo-section-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 4px 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
swp-todo-section-header i {
|
|
font-size: 14px;
|
|
color: var(--color-text-secondary);
|
|
transition: transform 200ms ease;
|
|
}
|
|
|
|
swp-todo-section.collapsed swp-todo-section-header i {
|
|
transform: rotate(-90deg);
|
|
}
|
|
|
|
swp-todo-section.collapsed swp-todo-items {
|
|
display: none;
|
|
}
|
|
|
|
swp-todo-section-title {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-todo-section-count {
|
|
font-size: 11px;
|
|
padding: 2px 6px;
|
|
background: var(--color-background);
|
|
border-radius: 10px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-todo-items {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
swp-todo-item {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 12px;
|
|
padding: 10px 12px;
|
|
background: var(--color-background-alt);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-todo-item:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-todo-item[data-completed="true"] {
|
|
opacity: 0.6;
|
|
}
|
|
|
|
swp-todo-item[data-completed="true"] swp-todo-title {
|
|
text-decoration: line-through;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-todo-checkbox {
|
|
width: 20px;
|
|
height: 20px;
|
|
border: 2px solid var(--color-border);
|
|
border-radius: 4px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
margin-top: 1px;
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-todo-checkbox i {
|
|
font-size: 14px;
|
|
color: white;
|
|
opacity: 0;
|
|
}
|
|
|
|
swp-todo-item[data-completed="true"] swp-todo-checkbox {
|
|
background: var(--color-teal);
|
|
border-color: var(--color-teal);
|
|
}
|
|
|
|
swp-todo-item[data-completed="true"] swp-todo-checkbox i {
|
|
opacity: 1;
|
|
}
|
|
|
|
swp-todo-content {
|
|
flex: 1;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
swp-todo-title {
|
|
font-size: 14px;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-todo-meta {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 12px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-todo-meta i {
|
|
font-size: 14px;
|
|
}
|
|
|
|
swp-todo-time {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
swp-todo-priority {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
swp-todo-priority.high {
|
|
color: var(--color-red);
|
|
}
|
|
|
|
swp-todo-priority.low {
|
|
color: var(--color-text-secondary);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
swp-todo-date {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
/* New Todo Drawer - Header */
|
|
swp-new-todo-drawer swp-drawer-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 14px 16px;
|
|
border-bottom: 1px solid var(--color-border);
|
|
background: var(--color-background-alt);
|
|
}
|
|
|
|
swp-new-todo-drawer swp-drawer-title {
|
|
flex: 1;
|
|
}
|
|
|
|
swp-new-todo-drawer swp-drawer-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 16px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
|
|
/* Form Elements - matches detail-drawer patterns */
|
|
swp-new-todo-drawer swp-section-label {
|
|
display: block;
|
|
font-size: 11px;
|
|
font-weight: 400;
|
|
color: var(--color-text-secondary);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
swp-new-todo-drawer swp-form-field {
|
|
display: block;
|
|
}
|
|
|
|
swp-new-todo-drawer swp-form-row {
|
|
display: flex;
|
|
gap: 12px;
|
|
}
|
|
|
|
swp-new-todo-drawer swp-form-row swp-form-field {
|
|
flex: 1;
|
|
}
|
|
|
|
swp-new-todo-drawer input[type="text"],
|
|
swp-new-todo-drawer input[type="date"],
|
|
swp-new-todo-drawer input[type="time"],
|
|
swp-new-todo-drawer select,
|
|
swp-new-todo-drawer textarea {
|
|
width: 100%;
|
|
padding: 10px 12px;
|
|
font-size: 14px;
|
|
font-family: var(--font-family);
|
|
color: var(--color-text);
|
|
background: var(--color-background-alt);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 4px;
|
|
outline: none;
|
|
transition: border-color 150ms ease;
|
|
}
|
|
|
|
swp-new-todo-drawer input:focus,
|
|
swp-new-todo-drawer select:focus,
|
|
swp-new-todo-drawer textarea:focus {
|
|
border-color: var(--color-teal);
|
|
}
|
|
|
|
swp-new-todo-drawer input::placeholder,
|
|
swp-new-todo-drawer textarea::placeholder {
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-new-todo-drawer select {
|
|
cursor: pointer;
|
|
appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 256 256'%3E%3Cpath fill='%23666' d='M213.66 101.66l-80 80a8 8 0 0 1-11.32 0l-80-80a8 8 0 0 1 11.32-11.32L128 164.69l74.34-74.35a8 8 0 0 1 11.32 11.32Z'/%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 10px center;
|
|
padding-right: 36px;
|
|
}
|
|
|
|
swp-new-todo-drawer textarea {
|
|
resize: none;
|
|
min-height: 80px;
|
|
}
|
|
|
|
/* Visibility toggle */
|
|
swp-visibility-toggle {
|
|
display: flex;
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
swp-visibility-option {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
padding: 10px 12px;
|
|
font-size: 13px;
|
|
color: var(--color-text-secondary);
|
|
background: var(--color-background-alt);
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
border: none;
|
|
}
|
|
|
|
swp-visibility-option:first-child {
|
|
border-right: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-visibility-option i {
|
|
font-size: 16px;
|
|
}
|
|
|
|
swp-visibility-option:hover {
|
|
background: var(--color-background-hover);
|
|
}
|
|
|
|
swp-visibility-option.active {
|
|
background: color-mix(in srgb, var(--color-teal) 12%, transparent);
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
/* Footer with buttons */
|
|
swp-new-todo-drawer swp-drawer-footer {
|
|
padding: 16px;
|
|
border-top: 1px solid var(--color-border);
|
|
display: flex;
|
|
gap: 12px;
|
|
}
|
|
|
|
swp-new-todo-drawer swp-btn {
|
|
flex: 1;
|
|
padding: 10px 16px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
font-family: var(--font-family);
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
text-align: center;
|
|
border: none;
|
|
}
|
|
|
|
swp-new-todo-drawer swp-btn.secondary {
|
|
background: transparent;
|
|
border: 1px solid var(--color-border);
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-new-todo-drawer swp-btn.secondary:hover {
|
|
background: var(--color-background-hover);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-new-todo-drawer swp-btn.primary {
|
|
background: var(--color-teal);
|
|
color: white;
|
|
}
|
|
|
|
swp-new-todo-drawer swp-btn.primary:hover {
|
|
background: color-mix(in srgb, var(--color-teal) 85%, black);
|
|
}
|
|
|
|
/* ==========================================
|
|
LOCK SCREEN
|
|
========================================== */
|
|
swp-lock-screen {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: var(--color-background);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 2000;
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 300ms ease, visibility 300ms ease;
|
|
}
|
|
|
|
swp-lock-screen.active {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
swp-lock-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 24px;
|
|
padding: 40px;
|
|
background: var(--color-surface);
|
|
border-radius: 16px;
|
|
border: 1px solid var(--color-border);
|
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
swp-lock-icon {
|
|
width: 80px;
|
|
height: 80px;
|
|
border-radius: 50%;
|
|
background: color-mix(in srgb, var(--color-teal) 12%, transparent);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
swp-lock-icon i {
|
|
font-size: 36px;
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
swp-lock-title {
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
swp-lock-subtitle {
|
|
font-size: 14px;
|
|
color: var(--color-text-secondary);
|
|
margin-top: -16px;
|
|
}
|
|
|
|
swp-pin-input {
|
|
display: flex;
|
|
gap: 12px;
|
|
}
|
|
|
|
swp-pin-digit {
|
|
width: 56px;
|
|
height: 64px;
|
|
border: 2px solid var(--color-border);
|
|
border-radius: 12px;
|
|
background: var(--color-surface);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
font-family: var(--font-mono);
|
|
color: var(--color-text);
|
|
transition: all 150ms ease;
|
|
}
|
|
|
|
swp-pin-digit.filled {
|
|
border-color: var(--color-teal);
|
|
background: color-mix(in srgb, var(--color-teal) 8%, transparent);
|
|
}
|
|
|
|
swp-pin-digit.error {
|
|
border-color: var(--color-red);
|
|
background: color-mix(in srgb, var(--color-red) 8%, transparent);
|
|
animation: shake 0.4s ease;
|
|
}
|
|
|
|
@keyframes shake {
|
|
0%, 100% { transform: translateX(0); }
|
|
20%, 60% { transform: translateX(-8px); }
|
|
40%, 80% { transform: translateX(8px); }
|
|
}
|
|
|
|
swp-pin-keypad {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 12px;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
swp-pin-key {
|
|
width: 72px;
|
|
height: 56px;
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 10px;
|
|
background: var(--color-surface);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 22px;
|
|
font-weight: 500;
|
|
color: var(--color-text);
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
font-family: var(--font-family);
|
|
}
|
|
|
|
swp-pin-key:hover {
|
|
background: var(--color-background-hover);
|
|
border-color: var(--color-teal);
|
|
}
|
|
|
|
swp-pin-key:active {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
swp-pin-key.empty {
|
|
visibility: hidden;
|
|
}
|
|
|
|
swp-pin-key.backspace {
|
|
font-size: 20px;
|
|
}
|
|
|
|
swp-pin-key.backspace i {
|
|
font-size: 24px;
|
|
}
|
|
|
|
swp-lock-time {
|
|
font-size: 13px;
|
|
color: var(--color-text-secondary);
|
|
margin-top: -12px;
|
|
}
|
|
|
|
swp-lock-hint {
|
|
font-size: 12px;
|
|
color: var(--color-text-secondary);
|
|
margin-top: -8px;
|
|
}
|
|
|
|
/* ==========================================
|
|
MAIN CONTENT
|
|
========================================== */
|
|
swp-main-content {
|
|
display: block;
|
|
overflow-y: auto;
|
|
padding: 24px;
|
|
background: var(--color-background);
|
|
}
|
|
|
|
/* Demo placeholder */
|
|
swp-content-placeholder {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
min-height: 400px;
|
|
background: var(--color-surface);
|
|
border: 2px dashed var(--color-border);
|
|
border-radius: 12px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
swp-content-placeholder i {
|
|
font-size: 64px;
|
|
color: var(--color-border);
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
swp-content-placeholder-title {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: var(--color-text);
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
swp-content-placeholder-text {
|
|
font-size: 14px;
|
|
text-align: center;
|
|
max-width: 400px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<swp-app-layout>
|
|
<!-- Side Menu -->
|
|
<swp-side-menu>
|
|
<swp-side-menu-header>
|
|
<i class="ph ph-squares-four"></i>
|
|
<swp-side-menu-logo>Salon OS</swp-side-menu-logo>
|
|
<swp-menu-toggle id="menuToggle">
|
|
<i class="ph ph-caret-left"></i>
|
|
</swp-menu-toggle>
|
|
</swp-side-menu-header>
|
|
|
|
<swp-side-menu-nav>
|
|
<!-- DASHBOARD -->
|
|
<swp-side-menu-group>
|
|
<swp-side-menu-label>Dashboard</swp-side-menu-label>
|
|
<swp-side-menu-item data-active="true" data-tooltip="Dashboard">
|
|
<i class="ph ph-squares-four"></i>
|
|
<span>Dashboard</span>
|
|
</swp-side-menu-item>
|
|
<swp-side-menu-item onclick="location.href='poc-calendar.html'" data-tooltip="Kalender">
|
|
<i class="ph ph-calendar"></i>
|
|
<span>Kalender</span>
|
|
</swp-side-menu-item>
|
|
<swp-side-menu-item data-tooltip="Kasse">
|
|
<i class="ph ph-device-mobile"></i>
|
|
<span>Kasse</span>
|
|
</swp-side-menu-item>
|
|
</swp-side-menu-group>
|
|
|
|
<!-- DATA -->
|
|
<swp-side-menu-group>
|
|
<swp-side-menu-label>Data</swp-side-menu-label>
|
|
<swp-side-menu-item onclick="location.href='poc-produkter.html'" data-tooltip="Produkter & Lager">
|
|
<i class="ph ph-package"></i>
|
|
<span>Produkter & Lager</span>
|
|
</swp-side-menu-item>
|
|
<swp-side-menu-item onclick="location.href='poc-leverandoerer.html'" data-tooltip="Leverandører">
|
|
<i class="ph ph-truck"></i>
|
|
<span>Leverandører</span>
|
|
</swp-side-menu-item>
|
|
<swp-side-menu-item data-tooltip="Kunder">
|
|
<i class="ph ph-users"></i>
|
|
<span>Kunder</span>
|
|
</swp-side-menu-item>
|
|
<swp-side-menu-item onclick="location.href='poc-employee.html'" data-tooltip="Medarbejdere">
|
|
<i class="ph ph-user"></i>
|
|
<span>Medarbejdere</span>
|
|
</swp-side-menu-item>
|
|
</swp-side-menu-group>
|
|
|
|
<!-- ANALYSE -->
|
|
<swp-side-menu-group>
|
|
<swp-side-menu-label>Analyse</swp-side-menu-label>
|
|
<swp-side-menu-item data-tooltip="Statistik & Rapporter">
|
|
<i class="ph ph-chart-bar"></i>
|
|
<span>Statistik & Rapporter</span>
|
|
</swp-side-menu-item>
|
|
</swp-side-menu-group>
|
|
|
|
<!-- SYSTEM -->
|
|
<swp-side-menu-group>
|
|
<swp-side-menu-label>System</swp-side-menu-label>
|
|
<swp-side-menu-item data-tooltip="Indstillinger">
|
|
<i class="ph ph-gear"></i>
|
|
<span>Indstillinger</span>
|
|
</swp-side-menu-item>
|
|
<swp-side-menu-item data-tooltip="Abonnement & Konto">
|
|
<i class="ph ph-credit-card"></i>
|
|
<span>Abonnement & Konto</span>
|
|
</swp-side-menu-item>
|
|
</swp-side-menu-group>
|
|
</swp-side-menu-nav>
|
|
|
|
<swp-side-menu-footer>
|
|
<swp-side-menu-action class="lock" title="Lås skærm">
|
|
<i class="ph ph-lock"></i>
|
|
<span>Lås skærm</span>
|
|
</swp-side-menu-action>
|
|
</swp-side-menu-footer>
|
|
</swp-side-menu>
|
|
|
|
<!-- Top Bar -->
|
|
<swp-app-topbar>
|
|
<swp-topbar-search>
|
|
<i class="ph ph-magnifying-glass"></i>
|
|
<input type="text" placeholder="Søg i Salon OS..." id="globalSearch">
|
|
<kbd>⌘K</kbd>
|
|
</swp-topbar-search>
|
|
|
|
<swp-topbar-actions>
|
|
<!-- Notifications -->
|
|
<swp-topbar-btn id="notificationsBtn" title="Notifikationer">
|
|
<i class="ph ph-bell"></i>
|
|
<swp-notification-badge>3</swp-notification-badge>
|
|
</swp-topbar-btn>
|
|
|
|
<swp-topbar-divider></swp-topbar-divider>
|
|
|
|
<!-- Profile (opens drawer) -->
|
|
<swp-topbar-profile id="profileTrigger">
|
|
<swp-profile-avatar>MJ</swp-profile-avatar>
|
|
<swp-profile-info>
|
|
<swp-profile-name>Maria Jensen</swp-profile-name>
|
|
<swp-profile-role>Administrator</swp-profile-role>
|
|
</swp-profile-info>
|
|
</swp-topbar-profile>
|
|
</swp-topbar-actions>
|
|
</swp-app-topbar>
|
|
|
|
<!-- Main Content -->
|
|
<swp-main-content>
|
|
<swp-content-placeholder>
|
|
<i class="ph ph-squares-four"></i>
|
|
<swp-content-placeholder-title>Dashboard</swp-content-placeholder-title>
|
|
<swp-content-placeholder-text>
|
|
Vælg et menupunkt i venstre side for at navigere til den ønskede sektion.
|
|
<br><br>
|
|
Prøv f.eks. <a href="poc-produkter.html">Produkter & Lager</a> eller <a href="poc-leverandoerer.html">Leverandører</a>.
|
|
</swp-content-placeholder-text>
|
|
</swp-content-placeholder>
|
|
</swp-main-content>
|
|
</swp-app-layout>
|
|
|
|
<!-- Profile Drawer -->
|
|
<swp-drawer-overlay id="drawerOverlay"></swp-drawer-overlay>
|
|
<swp-profile-drawer id="profileDrawer">
|
|
<swp-drawer-header>
|
|
<swp-drawer-title>Min profil</swp-drawer-title>
|
|
<swp-drawer-close id="drawerClose">
|
|
<i class="ph ph-x"></i>
|
|
</swp-drawer-close>
|
|
</swp-drawer-header>
|
|
|
|
<swp-drawer-content>
|
|
<swp-drawer-profile>
|
|
<swp-drawer-avatar>MJ</swp-drawer-avatar>
|
|
<swp-drawer-name>Maria Jensen</swp-drawer-name>
|
|
<swp-drawer-role>Administrator</swp-drawer-role>
|
|
<swp-drawer-email>maria@salon.dk</swp-drawer-email>
|
|
</swp-drawer-profile>
|
|
|
|
<swp-drawer-section>
|
|
<swp-drawer-section-label>Konto</swp-drawer-section-label>
|
|
<swp-drawer-item>
|
|
<i class="ph ph-user-circle"></i>
|
|
<swp-drawer-item-text>Rediger profil</swp-drawer-item-text>
|
|
<i class="ph ph-caret-right"></i>
|
|
</swp-drawer-item>
|
|
<swp-drawer-item>
|
|
<i class="ph ph-key"></i>
|
|
<swp-drawer-item-text>Skift adgangskode</swp-drawer-item-text>
|
|
<i class="ph ph-caret-right"></i>
|
|
</swp-drawer-item>
|
|
<swp-drawer-item>
|
|
<i class="ph ph-bell"></i>
|
|
<swp-drawer-item-text>Notifikationer</swp-drawer-item-text>
|
|
<swp-drawer-item-hint>3 ulæste</swp-drawer-item-hint>
|
|
</swp-drawer-item>
|
|
<swp-drawer-item id="openTodoDrawer">
|
|
<i class="ph ph-check-square"></i>
|
|
<swp-drawer-item-text>Mine opgaver</swp-drawer-item-text>
|
|
<swp-drawer-item-hint>2 i dag</swp-drawer-item-hint>
|
|
</swp-drawer-item>
|
|
</swp-drawer-section>
|
|
|
|
<swp-drawer-section>
|
|
<swp-drawer-section-label>Udseende</swp-drawer-section-label>
|
|
<swp-theme-toggle id="themeToggleDrawer">
|
|
<swp-theme-option data-theme="light" title="Lyst tema">
|
|
<i class="ph ph-sun"></i>
|
|
</swp-theme-option>
|
|
<swp-theme-option data-theme="dark" title="Mørkt tema">
|
|
<i class="ph ph-moon"></i>
|
|
</swp-theme-option>
|
|
</swp-theme-toggle>
|
|
</swp-drawer-section>
|
|
|
|
<swp-drawer-section>
|
|
<swp-drawer-section-label>Support</swp-drawer-section-label>
|
|
<swp-drawer-item>
|
|
<i class="ph ph-question"></i>
|
|
<swp-drawer-item-text>Hjælp & Support</swp-drawer-item-text>
|
|
<i class="ph ph-caret-right"></i>
|
|
</swp-drawer-item>
|
|
<swp-drawer-item>
|
|
<i class="ph ph-info"></i>
|
|
<swp-drawer-item-text>Om Salon OS</swp-drawer-item-text>
|
|
<swp-drawer-item-hint>v2.1.0</swp-drawer-item-hint>
|
|
</swp-drawer-item>
|
|
</swp-drawer-section>
|
|
</swp-drawer-content>
|
|
|
|
<swp-drawer-footer>
|
|
<swp-drawer-action class="logout">
|
|
<i class="ph ph-sign-out"></i>
|
|
Log ud
|
|
</swp-drawer-action>
|
|
</swp-drawer-footer>
|
|
</swp-profile-drawer>
|
|
|
|
<!-- Notification Drawer -->
|
|
<swp-notification-drawer id="notificationDrawer">
|
|
<swp-drawer-header>
|
|
<swp-drawer-title>Notifikationer</swp-drawer-title>
|
|
<swp-drawer-header-actions>
|
|
<swp-mark-read-btn id="markAllRead">Marker alle læst</swp-mark-read-btn>
|
|
<swp-drawer-close id="notificationDrawerClose">
|
|
<i class="ph ph-x"></i>
|
|
</swp-drawer-close>
|
|
</swp-drawer-header-actions>
|
|
</swp-drawer-header>
|
|
|
|
<swp-drawer-content>
|
|
<!-- Booking -->
|
|
<swp-notification-item data-unread="true">
|
|
<swp-notification-icon class="booking">
|
|
<i class="ph ph-calendar-check"></i>
|
|
</swp-notification-icon>
|
|
<swp-notification-content>
|
|
<swp-notification-title>Ny booking</swp-notification-title>
|
|
<swp-notification-text>Maria Hansen har booket klipning kl. 14:00</swp-notification-text>
|
|
<swp-notification-time>For 5 min siden</swp-notification-time>
|
|
</swp-notification-content>
|
|
</swp-notification-item>
|
|
|
|
<!-- Smiley/Feedback -->
|
|
<swp-notification-item data-unread="true">
|
|
<swp-notification-icon class="smiley">
|
|
<i class="ph ph-smiley"></i>
|
|
</swp-notification-icon>
|
|
<swp-notification-content>
|
|
<swp-notification-title>Kunde feedback</swp-notification-title>
|
|
<swp-notification-text>5 stjerner fra Jonas Petersen</swp-notification-text>
|
|
<swp-notification-time>For 15 min siden</swp-notification-time>
|
|
</swp-notification-content>
|
|
</swp-notification-item>
|
|
|
|
<!-- Opkald -->
|
|
<swp-notification-item data-unread="true">
|
|
<swp-notification-icon class="call">
|
|
<i class="ph ph-phone"></i>
|
|
</swp-notification-icon>
|
|
<swp-notification-content>
|
|
<swp-notification-title>Misset opkald</swp-notification-title>
|
|
<swp-notification-text>+45 12 34 56 78</swp-notification-text>
|
|
<swp-notification-time>For 1 time siden</swp-notification-time>
|
|
</swp-notification-content>
|
|
</swp-notification-item>
|
|
|
|
<!-- Mail -->
|
|
<swp-notification-item>
|
|
<swp-notification-icon class="mail">
|
|
<i class="ph ph-envelope"></i>
|
|
</swp-notification-icon>
|
|
<swp-notification-content>
|
|
<swp-notification-title>Ny mail</swp-notification-title>
|
|
<swp-notification-text>Fra: leverandoer@produkt.dk - Ordrebekræftelse</swp-notification-text>
|
|
<swp-notification-time>For 2 timer siden</swp-notification-time>
|
|
</swp-notification-content>
|
|
</swp-notification-item>
|
|
|
|
<!-- Chat -->
|
|
<swp-notification-item>
|
|
<swp-notification-icon class="chat">
|
|
<i class="ph ph-chat-circle"></i>
|
|
</swp-notification-icon>
|
|
<swp-notification-content>
|
|
<swp-notification-title>Ny besked i chat</swp-notification-title>
|
|
<swp-notification-text>Kunde: "Hej, kan jeg ændre min tid?"</swp-notification-text>
|
|
<swp-notification-time>For 3 timer siden</swp-notification-time>
|
|
</swp-notification-content>
|
|
</swp-notification-item>
|
|
|
|
<!-- Reminder -->
|
|
<swp-notification-item>
|
|
<swp-notification-icon class="reminder">
|
|
<i class="ph ph-bell-ringing"></i>
|
|
</swp-notification-icon>
|
|
<swp-notification-content>
|
|
<swp-notification-title>Påmindelse</swp-notification-title>
|
|
<swp-notification-text>Bestil varer fra Wella inden fredag</swp-notification-text>
|
|
<swp-notification-time>I går</swp-notification-time>
|
|
</swp-notification-content>
|
|
</swp-notification-item>
|
|
</swp-drawer-content>
|
|
</swp-notification-drawer>
|
|
|
|
<!-- Todo Drawer -->
|
|
<swp-todo-drawer id="todoDrawer">
|
|
<swp-drawer-header>
|
|
<swp-drawer-back id="todoDrawerBack">
|
|
<i class="ph ph-caret-left"></i>
|
|
</swp-drawer-back>
|
|
<swp-drawer-title>Mine opgaver</swp-drawer-title>
|
|
<swp-drawer-header-actions>
|
|
<swp-add-todo-btn id="addTodoBtn" title="Tilføj opgave">
|
|
<i class="ph ph-plus"></i>
|
|
</swp-add-todo-btn>
|
|
</swp-drawer-header-actions>
|
|
</swp-drawer-header>
|
|
|
|
<swp-drawer-content>
|
|
<!-- I dag -->
|
|
<swp-todo-section>
|
|
<swp-todo-section-header>
|
|
<i class="ph ph-caret-down"></i>
|
|
<swp-todo-section-title>I dag</swp-todo-section-title>
|
|
<swp-todo-section-count>3</swp-todo-section-count>
|
|
</swp-todo-section-header>
|
|
<swp-todo-items>
|
|
<swp-todo-item>
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Ring til leverandør om ordre</swp-todo-title>
|
|
<swp-todo-meta>
|
|
<swp-todo-time>
|
|
<i class="ph ph-clock"></i>
|
|
10:00
|
|
</swp-todo-time>
|
|
</swp-todo-meta>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
<swp-todo-item data-completed="true">
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Bestil shampoo fra Wella</swp-todo-title>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
<swp-todo-item>
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Opdater prisliste for 2025</swp-todo-title>
|
|
<swp-todo-meta>
|
|
<swp-todo-priority class="high">
|
|
<i class="ph ph-flag"></i>
|
|
Høj
|
|
</swp-todo-priority>
|
|
</swp-todo-meta>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
</swp-todo-items>
|
|
</swp-todo-section>
|
|
|
|
<!-- Denne uge -->
|
|
<swp-todo-section>
|
|
<swp-todo-section-header>
|
|
<i class="ph ph-caret-down"></i>
|
|
<swp-todo-section-title>Denne uge</swp-todo-section-title>
|
|
<swp-todo-section-count>2</swp-todo-section-count>
|
|
</swp-todo-section-header>
|
|
<swp-todo-items>
|
|
<swp-todo-item>
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Rengør og vedligehold udstyr</swp-todo-title>
|
|
<swp-todo-meta>
|
|
<swp-todo-date>
|
|
<i class="ph ph-calendar"></i>
|
|
Onsdag
|
|
</swp-todo-date>
|
|
</swp-todo-meta>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
<swp-todo-item>
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Medarbejdersamtale med Jonas</swp-todo-title>
|
|
<swp-todo-meta>
|
|
<swp-todo-date>
|
|
<i class="ph ph-calendar"></i>
|
|
Fredag
|
|
</swp-todo-date>
|
|
<swp-todo-time>
|
|
<i class="ph ph-clock"></i>
|
|
14:00
|
|
</swp-todo-time>
|
|
</swp-todo-meta>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
</swp-todo-items>
|
|
</swp-todo-section>
|
|
|
|
<!-- Udført -->
|
|
<swp-todo-section class="collapsed">
|
|
<swp-todo-section-header>
|
|
<i class="ph ph-caret-down"></i>
|
|
<swp-todo-section-title>Udført</swp-todo-section-title>
|
|
<swp-todo-section-count>3</swp-todo-section-count>
|
|
</swp-todo-section-header>
|
|
<swp-todo-items>
|
|
<swp-todo-item data-completed="true">
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Send faktura til kunde</swp-todo-title>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
<swp-todo-item data-completed="true">
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Opdater åbningstider på Google</swp-todo-title>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
<swp-todo-item data-completed="true">
|
|
<swp-todo-checkbox>
|
|
<i class="ph ph-check"></i>
|
|
</swp-todo-checkbox>
|
|
<swp-todo-content>
|
|
<swp-todo-title>Bestil nye håndklæder</swp-todo-title>
|
|
</swp-todo-content>
|
|
</swp-todo-item>
|
|
</swp-todo-items>
|
|
</swp-todo-section>
|
|
</swp-drawer-content>
|
|
</swp-todo-drawer>
|
|
|
|
<!-- New Todo Drawer - slides from left of todo drawer -->
|
|
<swp-new-todo-drawer id="newTodoDrawer">
|
|
<swp-drawer-header>
|
|
<swp-drawer-back id="newTodoDrawerBack">
|
|
<i class="ph ph-caret-left"></i>
|
|
</swp-drawer-back>
|
|
<swp-drawer-title>Ny opgave</swp-drawer-title>
|
|
</swp-drawer-header>
|
|
|
|
<swp-drawer-content>
|
|
<!-- Titel -->
|
|
<swp-form-field>
|
|
<swp-section-label>Opgave</swp-section-label>
|
|
<input type="text" placeholder="Hvad skal du huske?" id="newTodoTitle">
|
|
</swp-form-field>
|
|
|
|
<!-- Dato & Tid -->
|
|
<swp-form-row>
|
|
<swp-form-field>
|
|
<swp-section-label>Dato</swp-section-label>
|
|
<input type="date" id="newTodoDate">
|
|
</swp-form-field>
|
|
<swp-form-field>
|
|
<swp-section-label>Tid</swp-section-label>
|
|
<input type="time" id="newTodoTime">
|
|
</swp-form-field>
|
|
</swp-form-row>
|
|
|
|
<!-- Prioritet -->
|
|
<swp-form-field>
|
|
<swp-section-label>Prioritet</swp-section-label>
|
|
<select id="newTodoPriority">
|
|
<option value="normal">Normal</option>
|
|
<option value="high">Høj prioritet</option>
|
|
<option value="low">Lav prioritet</option>
|
|
</select>
|
|
</swp-form-field>
|
|
|
|
<!-- Synlighed -->
|
|
<swp-form-field>
|
|
<swp-section-label>Synlighed</swp-section-label>
|
|
<swp-visibility-toggle>
|
|
<swp-visibility-option class="active" data-value="personal">
|
|
<i class="ph ph-user"></i>
|
|
Kun mig
|
|
</swp-visibility-option>
|
|
<swp-visibility-option data-value="shared">
|
|
<i class="ph ph-users"></i>
|
|
Alle
|
|
</swp-visibility-option>
|
|
</swp-visibility-toggle>
|
|
</swp-form-field>
|
|
|
|
<!-- Noter -->
|
|
<swp-form-field>
|
|
<swp-section-label>Noter</swp-section-label>
|
|
<textarea placeholder="Tilføj noter..." id="newTodoNotes"></textarea>
|
|
</swp-form-field>
|
|
</swp-drawer-content>
|
|
|
|
<swp-drawer-footer>
|
|
<swp-btn class="secondary" id="cancelNewTodo">Annuller</swp-btn>
|
|
<swp-btn class="primary" id="saveNewTodo">Gem opgave</swp-btn>
|
|
</swp-drawer-footer>
|
|
</swp-new-todo-drawer>
|
|
|
|
<!-- Lock Screen -->
|
|
<swp-lock-screen id="lockScreen">
|
|
<swp-lock-content>
|
|
<swp-lock-icon>
|
|
<i class="ph ph-lock"></i>
|
|
</swp-lock-icon>
|
|
<swp-lock-title>Skærm låst</swp-lock-title>
|
|
<swp-lock-subtitle>Indtast PIN for at fortsætte</swp-lock-subtitle>
|
|
|
|
<swp-lock-time id="lockTime">Låst kl. 14:32</swp-lock-time>
|
|
|
|
<swp-pin-input id="pinInput">
|
|
<swp-pin-digit></swp-pin-digit>
|
|
<swp-pin-digit></swp-pin-digit>
|
|
<swp-pin-digit></swp-pin-digit>
|
|
<swp-pin-digit></swp-pin-digit>
|
|
</swp-pin-input>
|
|
|
|
<swp-pin-keypad id="pinKeypad">
|
|
<swp-pin-key data-key="1">1</swp-pin-key>
|
|
<swp-pin-key data-key="2">2</swp-pin-key>
|
|
<swp-pin-key data-key="3">3</swp-pin-key>
|
|
<swp-pin-key data-key="4">4</swp-pin-key>
|
|
<swp-pin-key data-key="5">5</swp-pin-key>
|
|
<swp-pin-key data-key="6">6</swp-pin-key>
|
|
<swp-pin-key data-key="7">7</swp-pin-key>
|
|
<swp-pin-key data-key="8">8</swp-pin-key>
|
|
<swp-pin-key data-key="9">9</swp-pin-key>
|
|
<swp-pin-key class="empty"></swp-pin-key>
|
|
<swp-pin-key data-key="0">0</swp-pin-key>
|
|
<swp-pin-key class="backspace" data-key="backspace">
|
|
<i class="ph ph-backspace"></i>
|
|
</swp-pin-key>
|
|
</swp-pin-keypad>
|
|
|
|
<swp-lock-hint>Indtast 4 cifre for at låse op</swp-lock-hint>
|
|
</swp-lock-content>
|
|
</swp-lock-screen>
|
|
|
|
<!-- Menu Tooltip (Popover API) -->
|
|
<div id="menuTooltip" popover="manual" class="swp-menu-tooltip"></div>
|
|
|
|
<script>
|
|
// Elements
|
|
const root = document.documentElement;
|
|
const profileTrigger = document.getElementById('profileTrigger');
|
|
const profileDrawer = document.getElementById('profileDrawer');
|
|
const drawerOverlay = document.getElementById('drawerOverlay');
|
|
const drawerClose = document.getElementById('drawerClose');
|
|
|
|
// ==========================================
|
|
// SIDE MENU COLLAPSE
|
|
// ==========================================
|
|
const menuToggle = document.getElementById('menuToggle');
|
|
const appLayout = document.querySelector('swp-app-layout');
|
|
|
|
menuToggle.addEventListener('click', () => {
|
|
appLayout.classList.toggle('menu-collapsed');
|
|
});
|
|
|
|
// ==========================================
|
|
// MENU TOOLTIPS (Popover API)
|
|
// ==========================================
|
|
const menuTooltip = document.getElementById('menuTooltip');
|
|
const menuItems = document.querySelectorAll('swp-side-menu-item[data-tooltip]');
|
|
|
|
menuItems.forEach(item => {
|
|
item.addEventListener('mouseenter', () => {
|
|
if (!appLayout.classList.contains('menu-collapsed')) return;
|
|
|
|
const rect = item.getBoundingClientRect();
|
|
menuTooltip.textContent = item.dataset.tooltip;
|
|
menuTooltip.style.left = `${rect.right + 8}px`;
|
|
menuTooltip.style.top = `${rect.top + rect.height / 2}px`;
|
|
menuTooltip.style.transform = 'translateY(-50%)';
|
|
menuTooltip.showPopover();
|
|
});
|
|
|
|
item.addEventListener('mouseleave', () => {
|
|
menuTooltip.hidePopover();
|
|
});
|
|
});
|
|
|
|
// ==========================================
|
|
// DRAWERS (Profile, Notifications & Todo)
|
|
// ==========================================
|
|
const notificationDrawer = document.getElementById('notificationDrawer');
|
|
const notificationDrawerClose = document.getElementById('notificationDrawerClose');
|
|
const notificationsBtn = document.getElementById('notificationsBtn');
|
|
const markAllReadBtn = document.getElementById('markAllRead');
|
|
const notificationBadge = document.querySelector('swp-notification-badge');
|
|
|
|
const todoDrawer = document.getElementById('todoDrawer');
|
|
const todoDrawerBack = document.getElementById('todoDrawerBack');
|
|
const openTodoDrawerBtn = document.getElementById('openTodoDrawer');
|
|
const addTodoBtn = document.getElementById('addTodoBtn');
|
|
|
|
const newTodoDrawer = document.getElementById('newTodoDrawer');
|
|
const newTodoDrawerBack = document.getElementById('newTodoDrawerBack');
|
|
const cancelNewTodoBtn = document.getElementById('cancelNewTodo');
|
|
const saveNewTodoBtn = document.getElementById('saveNewTodo');
|
|
|
|
// Open profile drawer
|
|
function openProfileDrawer() {
|
|
closeTodoDrawer();
|
|
closeNotificationDrawer();
|
|
profileDrawer.classList.add('open');
|
|
drawerOverlay.classList.add('open');
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
// Close profile drawer
|
|
function closeProfileDrawer() {
|
|
profileDrawer.classList.remove('open');
|
|
drawerOverlay.classList.remove('open');
|
|
document.body.style.overflow = '';
|
|
}
|
|
|
|
// Open notification drawer
|
|
function openNotificationDrawer() {
|
|
closeTodoDrawer();
|
|
closeProfileDrawer();
|
|
notificationDrawer.classList.add('open');
|
|
drawerOverlay.classList.add('open');
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
// Close notification drawer
|
|
function closeNotificationDrawer() {
|
|
notificationDrawer.classList.remove('open');
|
|
drawerOverlay.classList.remove('open');
|
|
document.body.style.overflow = '';
|
|
}
|
|
|
|
// Open todo drawer (on top of profile drawer)
|
|
function openTodoDrawer() {
|
|
todoDrawer.classList.add('open');
|
|
}
|
|
|
|
// Close todo drawer
|
|
function closeTodoDrawer() {
|
|
todoDrawer.classList.remove('open');
|
|
closeNewTodoDrawer();
|
|
}
|
|
|
|
// Open new todo drawer (on top of todo drawer)
|
|
function openNewTodoDrawer() {
|
|
newTodoDrawer.classList.add('open');
|
|
}
|
|
|
|
// Close new todo drawer
|
|
function closeNewTodoDrawer() {
|
|
newTodoDrawer.classList.remove('open');
|
|
}
|
|
|
|
// Close all drawers
|
|
function closeAllDrawers() {
|
|
closeProfileDrawer();
|
|
closeNotificationDrawer();
|
|
closeTodoDrawer();
|
|
}
|
|
|
|
// Profile trigger opens drawer
|
|
profileTrigger.addEventListener('click', openProfileDrawer);
|
|
|
|
// Notifications button opens drawer
|
|
notificationsBtn.addEventListener('click', openNotificationDrawer);
|
|
|
|
// Todo drawer from profile
|
|
openTodoDrawerBtn.addEventListener('click', openTodoDrawer);
|
|
|
|
// Todo drawer back button (returns to profile)
|
|
todoDrawerBack.addEventListener('click', closeTodoDrawer);
|
|
|
|
// Add todo button opens new todo drawer
|
|
addTodoBtn.addEventListener('click', openNewTodoDrawer);
|
|
|
|
// New todo drawer back/cancel buttons
|
|
newTodoDrawerBack.addEventListener('click', closeNewTodoDrawer);
|
|
cancelNewTodoBtn.addEventListener('click', closeNewTodoDrawer);
|
|
|
|
// Save new todo (demo - just closes drawer)
|
|
saveNewTodoBtn.addEventListener('click', () => {
|
|
// In a real app, save the todo here
|
|
closeNewTodoDrawer();
|
|
});
|
|
|
|
// Visibility toggle
|
|
const visibilityOptions = document.querySelectorAll('swp-visibility-option');
|
|
visibilityOptions.forEach(option => {
|
|
option.addEventListener('click', () => {
|
|
visibilityOptions.forEach(o => o.classList.remove('active'));
|
|
option.classList.add('active');
|
|
});
|
|
});
|
|
|
|
// Close on overlay click
|
|
drawerOverlay.addEventListener('click', closeAllDrawers);
|
|
|
|
// Close on X buttons
|
|
drawerClose.addEventListener('click', closeProfileDrawer);
|
|
notificationDrawerClose.addEventListener('click', closeNotificationDrawer);
|
|
|
|
// Close on Escape
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape') closeAllDrawers();
|
|
});
|
|
|
|
// Mark all as read
|
|
markAllReadBtn.addEventListener('click', () => {
|
|
const unreadItems = notificationDrawer.querySelectorAll('swp-notification-item[data-unread="true"]');
|
|
unreadItems.forEach(item => {
|
|
item.removeAttribute('data-unread');
|
|
});
|
|
notificationBadge.style.display = 'none';
|
|
});
|
|
|
|
// ==========================================
|
|
// TODO FUNCTIONALITY
|
|
// ==========================================
|
|
// Toggle todo completion
|
|
todoDrawer.addEventListener('click', (e) => {
|
|
const todoItem = e.target.closest('swp-todo-item');
|
|
const checkbox = e.target.closest('swp-todo-checkbox');
|
|
|
|
if (checkbox && todoItem) {
|
|
const isCompleted = todoItem.dataset.completed === 'true';
|
|
if (isCompleted) {
|
|
todoItem.removeAttribute('data-completed');
|
|
} else {
|
|
todoItem.dataset.completed = 'true';
|
|
}
|
|
}
|
|
|
|
// Toggle section collapse
|
|
const sectionHeader = e.target.closest('swp-todo-section-header');
|
|
if (sectionHeader) {
|
|
const section = sectionHeader.closest('swp-todo-section');
|
|
section.classList.toggle('collapsed');
|
|
}
|
|
});
|
|
|
|
// Theme toggle functionality
|
|
const themeOptions = document.querySelectorAll('swp-theme-option');
|
|
|
|
function isDarkMode() {
|
|
return root.classList.contains('dark-mode') ||
|
|
(window.matchMedia('(prefers-color-scheme: dark)').matches && !root.classList.contains('light-mode'));
|
|
}
|
|
|
|
function updateThemeToggle() {
|
|
const darkActive = isDarkMode();
|
|
themeOptions.forEach(option => {
|
|
const theme = option.dataset.theme;
|
|
if ((theme === 'dark' && darkActive) || (theme === 'light' && !darkActive)) {
|
|
option.classList.add('active');
|
|
} else {
|
|
option.classList.remove('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
function setTheme(theme) {
|
|
if (theme === 'dark') {
|
|
root.classList.add('dark-mode');
|
|
root.classList.remove('light-mode');
|
|
} else {
|
|
root.classList.add('light-mode');
|
|
root.classList.remove('dark-mode');
|
|
}
|
|
updateThemeToggle();
|
|
}
|
|
|
|
// Initialize theme toggle state
|
|
updateThemeToggle();
|
|
|
|
// Theme option clicks
|
|
themeOptions.forEach(option => {
|
|
option.addEventListener('click', () => {
|
|
setTheme(option.dataset.theme);
|
|
});
|
|
});
|
|
|
|
// Keyboard shortcut for search (Cmd/Ctrl + K)
|
|
document.addEventListener('keydown', (e) => {
|
|
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
|
e.preventDefault();
|
|
document.getElementById('globalSearch').focus();
|
|
}
|
|
});
|
|
|
|
// ==========================================
|
|
// LOCK SCREEN
|
|
// ==========================================
|
|
const lockScreen = document.getElementById('lockScreen');
|
|
const pinInput = document.getElementById('pinInput');
|
|
const pinKeypad = document.getElementById('pinKeypad');
|
|
const lockBtn = document.querySelector('swp-side-menu-action.lock');
|
|
const pinDigits = pinInput.querySelectorAll('swp-pin-digit');
|
|
const lockTimeEl = document.getElementById('lockTime');
|
|
|
|
let currentPin = '';
|
|
|
|
// Show lock screen
|
|
function showLockScreen() {
|
|
closeAllDrawers();
|
|
lockScreen.classList.add('active');
|
|
document.body.style.overflow = 'hidden';
|
|
currentPin = '';
|
|
updatePinDisplay();
|
|
|
|
// Set lock time
|
|
const now = new Date();
|
|
const hours = now.getHours().toString().padStart(2, '0');
|
|
const minutes = now.getMinutes().toString().padStart(2, '0');
|
|
lockTimeEl.textContent = `Låst kl. ${hours}:${minutes}`;
|
|
}
|
|
|
|
// Hide lock screen
|
|
function hideLockScreen() {
|
|
lockScreen.classList.remove('active');
|
|
document.body.style.overflow = '';
|
|
currentPin = '';
|
|
updatePinDisplay();
|
|
}
|
|
|
|
// Update PIN display
|
|
function updatePinDisplay() {
|
|
pinDigits.forEach((digit, index) => {
|
|
digit.classList.remove('filled', 'error');
|
|
if (index < currentPin.length) {
|
|
digit.textContent = '•';
|
|
digit.classList.add('filled');
|
|
} else {
|
|
digit.textContent = '';
|
|
}
|
|
});
|
|
}
|
|
|
|
// Show error animation
|
|
function showPinError() {
|
|
pinDigits.forEach(digit => {
|
|
digit.classList.add('error');
|
|
});
|
|
setTimeout(() => {
|
|
currentPin = '';
|
|
updatePinDisplay();
|
|
}, 400);
|
|
}
|
|
|
|
const correctPin = '3911';
|
|
|
|
// Handle PIN key press
|
|
function handlePinKey(key) {
|
|
if (key === 'backspace') {
|
|
currentPin = currentPin.slice(0, -1);
|
|
updatePinDisplay();
|
|
return;
|
|
}
|
|
|
|
if (currentPin.length >= 4) return;
|
|
|
|
currentPin += key;
|
|
updatePinDisplay();
|
|
|
|
// Check if 4 digits entered
|
|
if (currentPin.length === 4) {
|
|
setTimeout(() => {
|
|
if (currentPin === correctPin) {
|
|
hideLockScreen();
|
|
} else {
|
|
showPinError();
|
|
}
|
|
}, 200);
|
|
}
|
|
}
|
|
|
|
// Lock button click
|
|
lockBtn.addEventListener('click', showLockScreen);
|
|
|
|
// Keypad clicks
|
|
pinKeypad.addEventListener('click', (e) => {
|
|
const key = e.target.closest('swp-pin-key');
|
|
if (!key || key.classList.contains('empty')) return;
|
|
handlePinKey(key.dataset.key);
|
|
});
|
|
|
|
// Keyboard support for PIN entry
|
|
document.addEventListener('keydown', (e) => {
|
|
// Alt+L to lock screen
|
|
if (e.altKey && e.key === 'x') {
|
|
e.preventDefault();
|
|
showLockScreen();
|
|
return;
|
|
}
|
|
|
|
if (!lockScreen.classList.contains('active')) return;
|
|
|
|
if (e.key >= '0' && e.key <= '9') {
|
|
handlePinKey(e.key);
|
|
} else if (e.key === 'Backspace') {
|
|
handlePinKey('backspace');
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|