Calendar/wwwroot/poc-layout.html

1322 lines
34 KiB
HTML
Raw Normal View History

<!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;
--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-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;
}
/* ==========================================
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 */
swp-drawer-theme-toggle {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
background: var(--color-background-alt);
border-radius: 8px;
}
swp-drawer-theme-toggle swp-drawer-item-text {
display: flex;
align-items: center;
gap: 12px;
}
swp-drawer-theme-toggle i {
font-size: 20px;
color: var(--color-text-secondary);
}
swp-theme-switch {
width: 44px;
height: 24px;
background: var(--color-border);
border-radius: 12px;
position: relative;
cursor: pointer;
transition: background 200ms ease;
}
swp-theme-switch::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
transition: transform 200ms ease;
}
swp-theme-switch.active {
background: var(--color-teal);
}
swp-theme-switch.active::after {
transform: translateX(20px);
}
/* 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;
}
/* ==========================================
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-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">
<i class="ph ph-squares-four"></i>
Dashboard
</swp-side-menu-item>
<swp-side-menu-item onclick="location.href='poc-calendar.html'">
<i class="ph ph-calendar"></i>
Kalender
</swp-side-menu-item>
<swp-side-menu-item>
<i class="ph ph-device-mobile"></i>
Kasse
</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'">
<i class="ph ph-package"></i>
Produkter & Lager
</swp-side-menu-item>
<swp-side-menu-item onclick="location.href='poc-leverandoerer.html'">
<i class="ph ph-truck"></i>
Leverandører
</swp-side-menu-item>
<swp-side-menu-item>
<i class="ph ph-users"></i>
Kunder
</swp-side-menu-item>
<swp-side-menu-item onclick="location.href='poc-employee.html'">
<i class="ph ph-user"></i>
Medarbejdere
</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>
<i class="ph ph-chart-bar"></i>
Statistik & Rapporter
</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>
<i class="ph ph-gear"></i>
Indstillinger
</swp-side-menu-item>
<swp-side-menu-item>
<i class="ph ph-credit-card"></i>
Abonnement & Konto
</swp-side-menu-item>
</swp-side-menu-group>
</swp-side-menu-nav>
<swp-side-menu-footer>
<swp-side-menu-action class="lock">
<i class="ph ph-lock"></i>
Lås skærm
</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-section>
<swp-drawer-section>
<swp-drawer-section-label>Udseende</swp-drawer-section-label>
<swp-drawer-theme-toggle id="themeToggleDrawer">
<swp-drawer-item-text>
<i class="ph ph-moon"></i>
Mørkt tema
</swp-drawer-item-text>
<swp-theme-switch id="themeSwitch"></swp-theme-switch>
</swp-drawer-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>
<!-- 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>
<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');
const themeSwitch = document.getElementById('themeSwitch');
const themeToggleDrawer = document.getElementById('themeToggleDrawer');
// Open drawer
function openDrawer() {
profileDrawer.classList.add('open');
drawerOverlay.classList.add('open');
document.body.style.overflow = 'hidden';
}
// Close drawer
function closeDrawer() {
profileDrawer.classList.remove('open');
drawerOverlay.classList.remove('open');
document.body.style.overflow = '';
}
// Profile trigger opens drawer
profileTrigger.addEventListener('click', openDrawer);
// Close on overlay click
drawerOverlay.addEventListener('click', closeDrawer);
// Close on X button
drawerClose.addEventListener('click', closeDrawer);
// Close on Escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') closeDrawer();
});
// Theme toggle functionality
function isDarkMode() {
return root.classList.contains('dark-mode') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches && !root.classList.contains('light-mode'));
}
function updateThemeSwitch() {
if (isDarkMode()) {
themeSwitch.classList.add('active');
} else {
themeSwitch.classList.remove('active');
}
}
function toggleTheme() {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (prefersDark) {
root.classList.toggle('light-mode');
root.classList.remove('dark-mode');
} else {
root.classList.toggle('dark-mode');
root.classList.remove('light-mode');
}
updateThemeSwitch();
}
// Initialize theme switch state
updateThemeSwitch();
// Theme toggle click
themeToggleDrawer.addEventListener('click', toggleTheme);
// 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() {
closeDrawer();
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>