Refactors design system documentation and layout

Updates design system documentation with comprehensive component overview
Enhances UI layout across multiple pages with consistent styling and new components
Adds support for charts, pagination, and responsive design elements

Improves overall system documentation and visual consistency
This commit is contained in:
Janus C. H. Knudsen 2026-01-07 22:12:25 +01:00
parent 35b15294e3
commit fac7754d7a
14 changed files with 3492 additions and 281 deletions

View file

@ -2266,6 +2266,152 @@
background: color-mix(in srgb, var(--color-teal) 15%, white);
color: var(--color-teal);
}
/* ==========================================
RATES DRAWER
========================================== */
swp-drawer-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.3);
z-index: 999;
}
swp-drawer-overlay.open {
display: block;
}
swp-rates-drawer {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: 420px;
background: var(--color-surface);
box-shadow: -4px 0 20px rgba(0,0,0,0.15);
z-index: 1000;
flex-direction: column;
}
swp-rates-drawer.open {
display: flex;
}
swp-drawer-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border);
}
swp-drawer-title {
font-size: 16px;
font-weight: 600;
}
swp-drawer-close {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
cursor: pointer;
color: var(--color-text-secondary);
transition: all 150ms ease;
}
swp-drawer-close:hover {
background: var(--color-background);
color: var(--color-text);
}
swp-drawer-body {
flex: 1;
overflow-y: auto;
padding: 16px 20px;
}
swp-rate-row {
display: grid;
grid-template-columns: 28px 1fr 100px;
align-items: center;
gap: 12px;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
}
swp-rate-row:last-child {
border-bottom: none;
}
swp-rate-row input[type="checkbox"] {
width: 18px;
height: 18px;
accent-color: var(--color-teal);
}
swp-rate-label {
font-size: 14px;
}
swp-rate-label.disabled {
opacity: 0.4;
}
swp-rate-input {
display: flex;
align-items: center;
gap: 4px;
font-size: 13px;
color: var(--color-text-secondary);
}
swp-rate-input input {
width: 70px;
padding: 6px 8px;
border: 1px solid var(--color-border);
border-radius: 4px;
font-size: 13px;
font-family: var(--font-mono);
text-align: right;
}
swp-rate-input.disabled input {
opacity: 0.4;
background: var(--color-background);
}
.btn-link {
background: none;
border: none;
color: var(--color-teal);
font-size: 13px;
cursor: pointer;
padding: 0;
}
.btn-link:hover {
text-decoration: underline;
}
swp-card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
swp-card-header swp-section-label {
margin-bottom: 0;
}
.mono {
font-family: var(--font-mono);
}
</style>
</head>
<body>
@ -2650,35 +2796,24 @@
<div class="grid-2">
<div>
<swp-card>
<swp-section-label>Grundløn</swp-section-label>
<swp-card-header>
<swp-section-label>Satser</swp-section-label>
<button class="btn-link" onclick="openRatesDrawer()">Rediger</button>
</swp-card-header>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Timeløn</swp-edit-label>
<swp-edit-value contenteditable="true">185 kr/time</swp-edit-value>
<swp-edit-label>Normal (timeløn)</swp-edit-label>
<swp-edit-value class="mono">131,49 kr</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Overarbejde</swp-edit-label>
<swp-edit-value contenteditable="true">150%</swp-edit-value>
<swp-edit-label>Overarbejde (100%)</swp-edit-label>
<swp-edit-value class="mono">280,50 kr</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Weekendtillæg</swp-edit-label>
<swp-edit-value contenteditable="true">25%</swp-edit-value>
<swp-edit-label>Ferie m. løn</swp-edit-label>
<swp-edit-value class="mono">140,25 kr</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<swp-toggle-row style="margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--color-border);">
<swp-toggle-label>ATP-bidrag</swp-toggle-label>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-label>Pension (arbejdsgiver)</swp-toggle-label>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
</swp-card>
<swp-card>
@ -2686,56 +2821,74 @@
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Minimum pr. time</swp-edit-label>
<swp-edit-value contenteditable="true">220 kr</swp-edit-value>
<swp-edit-value class="mono" contenteditable="true">220 kr</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>På services</swp-edit-label>
<swp-edit-value contenteditable="true">15%</swp-edit-value>
<swp-edit-value class="mono" contenteditable="true">15%</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>På produktsalg</swp-edit-label>
<swp-edit-value contenteditable="true">15%</swp-edit-value>
<swp-edit-value class="mono" contenteditable="true">15%</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
</swp-card>
<swp-card>
<swp-section-label>Tillæg</swp-section-label>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>8-21 Hverdage</swp-edit-label>
<swp-edit-value class="mono">28,03 kr</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>8-21 Lørdage</swp-edit-label>
<swp-edit-value class="mono">56,02 kr</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Søndag</swp-edit-label>
<swp-edit-value class="mono">112,07 kr</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
</swp-card>
</div>
<swp-card>
<swp-section-label>Lønhistorik</swp-section-label>
<swp-section-label>Lønspecifikationer</swp-section-label>
<swp-salary-history>
<table>
<thead>
<tr>
<th>Dato</th>
<th>Ændring</th>
<th>Ny værdi</th>
<th>Periode</th>
<th>Bruttoløn</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="mono">01.01.2025</td>
<td>Lønforhøjelse</td>
<td class="mono">185 kr/time</td>
<td>Januar 2026</td>
<td class="mono">34.063,50 kr</td>
<td><a href="poc-loenspecifikation.html" class="link">Vis</a></td>
</tr>
<tr>
<td class="mono">01.01.2024</td>
<td>Lønforhøjelse</td>
<td class="mono">175 kr/time</td>
<td>December 2025</td>
<td class="mono">31.845,00 kr</td>
<td><a href="poc-loenspecifikation.html" class="link">Vis</a></td>
</tr>
<tr>
<td class="mono">01.07.2023</td>
<td>Provision ændret</td>
<td class="mono">12%</td>
<td>November 2025</td>
<td class="mono">33.290,25 kr</td>
<td><a href="poc-loenspecifikation.html" class="link">Vis</a></td>
</tr>
<tr>
<td class="mono">01.01.2023</td>
<td>Lønforhøjelse</td>
<td class="mono">165 kr/time</td>
<td>Oktober 2025</td>
<td class="mono">32.156,75 kr</td>
<td><a href="poc-loenspecifikation.html" class="link">Vis</a></td>
</tr>
<tr>
<td class="mono">01.08.2019</td>
<td>Ansættelse</td>
<td class="mono">145 kr/time</td>
<td>September 2025</td>
<td class="mono">34.520,00 kr</td>
<td><a href="poc-loenspecifikation.html" class="link">Vis</a></td>
</tr>
</tbody>
</table>
@ -3884,5 +4037,114 @@
});
</script>
<!-- Rates Drawer -->
<swp-drawer-overlay id="rates-overlay" onclick="closeRatesDrawer()"></swp-drawer-overlay>
<swp-rates-drawer id="rates-drawer">
<swp-drawer-header>
<swp-drawer-title>Lønsatser</swp-drawer-title>
<swp-drawer-close onclick="closeRatesDrawer()">
<i class="ph ph-x"></i>
</swp-drawer-close>
</swp-drawer-header>
<swp-drawer-body>
<swp-section-label style="margin-bottom: 12px;">Grundsatser</swp-section-label>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>Normal (timeløn)</swp-rate-label>
<swp-rate-input><input type="text" value="131,49"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>Overarbejde (100%)</swp-rate-label>
<swp-rate-input><input type="text" value="280,50"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox">
<swp-rate-label class="disabled">Kursus/skole</swp-rate-label>
<swp-rate-input class="disabled"><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox">
<swp-rate-label class="disabled">Afspadsering</swp-rate-label>
<swp-rate-input class="disabled"><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox">
<swp-rate-label class="disabled">Fri m. løn</swp-rate-label>
<swp-rate-input class="disabled"><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>Ferie m. løn</swp-rate-label>
<swp-rate-input><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox">
<swp-rate-label class="disabled">Kontor</swp-rate-label>
<swp-rate-input class="disabled"><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox">
<swp-rate-label class="disabled">Barns 1. sygedag</swp-rate-label>
<swp-rate-input class="disabled"><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox">
<swp-rate-label class="disabled">Barns hospitalsindlæggelse</swp-rate-label>
<swp-rate-input class="disabled"><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox">
<swp-rate-label class="disabled">Barsel</swp-rate-label>
<swp-rate-input class="disabled"><input type="text" value="140,25"> kr</swp-rate-input>
</swp-rate-row>
<div style="margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--color-border);">
<swp-section-label style="margin-bottom: 12px;">Tillæg</swp-section-label>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>8-21 Hverdage (udenfor arbejdstid)</swp-rate-label>
<swp-rate-input><input type="text" value="28,03"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>8-21 Lørdage (udenfor arbejdstid)</swp-rate-label>
<swp-rate-input><input type="text" value="56,02"> kr</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>Søndag</swp-rate-label>
<swp-rate-input><input type="text" value="112,07"> kr</swp-rate-input>
</swp-rate-row>
</div>
<div style="margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--color-border);">
<swp-section-label style="margin-bottom: 12px;">Provisionsberegning</swp-section-label>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>Provision på produktsalg</swp-rate-label>
<swp-rate-input><input type="text" value="15"> %</swp-rate-input>
</swp-rate-row>
<swp-rate-row>
<input type="checkbox" checked>
<swp-rate-label>Provision på servicesalg</swp-rate-label>
<swp-rate-input><input type="text" value="15"> %</swp-rate-input>
</swp-rate-row>
</div>
</swp-drawer-body>
</swp-rates-drawer>
<script>
function openRatesDrawer() {
document.getElementById('rates-overlay').classList.add('open');
document.getElementById('rates-drawer').classList.add('open');
}
function closeRatesDrawer() {
document.getElementById('rates-overlay').classList.remove('open');
document.getElementById('rates-drawer').classList.remove('open');
}
</script>
</body>
</html>

View file

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gavekort GC-A7X2-9KM4 - Salon OS</title>
<title>Fordelskort FK-A7X2-9KM4 - Salon OS</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<script src="https://unpkg.com/@phosphor-icons/web@2.1.1"></script>
<style>
@ -1084,9 +1084,9 @@
<swp-topbar-left>
<swp-back-link onclick="location.href='poc-gavekort.html'">
<i class="ph ph-caret-left"></i>
Gavekort
Fordelskort
</swp-back-link>
<swp-page-title>GC-A7X2-9KM4</swp-page-title>
<swp-page-title>FK-A7X2-9KM4</swp-page-title>
</swp-topbar-left>
<swp-topbar-right>
</swp-topbar-right>
@ -1130,12 +1130,12 @@
<!-- Gift Card Details -->
<swp-card>
<swp-section-label>Gavekort info</swp-section-label>
<swp-section-label>Kortinfo</swp-section-label>
<swp-kv-list>
<swp-kv-row>
<swp-kv-label>Kode</swp-kv-label>
<swp-kv-value class="mono with-action">
GC-A7X2-9KM4
FK-A7X2-9KM4
<swp-copy-btn onclick="copyCode()">
<i class="ph ph-copy"></i>
</swp-copy-btn>
@ -1194,7 +1194,7 @@
<swp-td class="muted">15/1-24</swp-td>
<swp-td>
<swp-transaction-details>
<swp-transaction-type>Gavekort oprettet</swp-transaction-type>
<swp-transaction-type>Kort oprettet</swp-transaction-type>
<swp-transaction-meta>
<a href="#">Faktura #1652</a> · <a href="#">Signe Larsen</a>
</swp-transaction-meta>
@ -1226,7 +1226,7 @@
</swp-recipient-row>
<swp-send-btn id="openEmailDrawerAlt">
<i class="ph ph-paper-plane-tilt"></i>
Send gavekort på email
Send fordelskort på email
</swp-send-btn>
</swp-card>
@ -1254,10 +1254,10 @@
<swp-email-icon>
<i class="ph ph-gift"></i>
</swp-email-icon>
<swp-email-title>Du har modtaget et gavekort!</swp-email-title>
<swp-email-title>Du har modtaget et fordelskort!</swp-email-title>
<swp-giftcard-visual>
<swp-giftcard-amount>500 DKK</swp-giftcard-amount>
<swp-giftcard-code-display>GC-A7X2-9KM4</swp-giftcard-code-display>
<swp-giftcard-code-display>FK-A7X2-9KM4</swp-giftcard-code-display>
</swp-giftcard-visual>
<swp-email-message id="previewMessage">Din besked vises her...</swp-email-message>
<swp-email-sender>
@ -1276,7 +1276,7 @@
<!-- Send Email Drawer -->
<swp-drawer id="emailDrawer">
<swp-drawer-header>
<swp-drawer-title>Send gavekort</swp-drawer-title>
<swp-drawer-title>Send fordelskort</swp-drawer-title>
<swp-drawer-close id="closeEmailDrawer">
<i class="ph ph-x"></i>
</swp-drawer-close>
@ -1311,7 +1311,7 @@
<!-- Add Value Drawer -->
<swp-drawer id="addValueDrawer">
<swp-drawer-header>
<swp-drawer-title>Juster gavekort</swp-drawer-title>
<swp-drawer-title>Juster fordelskort</swp-drawer-title>
<swp-drawer-close id="closeAddValueDrawer">
<i class="ph ph-x"></i>
</swp-drawer-close>
@ -1417,7 +1417,7 @@
// Copy code to clipboard
function copyCode() {
navigator.clipboard.writeText('GC-A7X2-9KM4').then(() => {
navigator.clipboard.writeText('FK-A7X2-9KM4').then(() => {
alert('Kode kopieret!');
});
}

View file

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gavekort - Salon OS</title>
<title>Fordelskort - Salon OS</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<script src="https://unpkg.com/@phosphor-icons/web@2.1.1"></script>
<style>
@ -802,12 +802,12 @@
<!-- Topbar -->
<swp-topbar>
<swp-topbar-left>
<swp-page-title>Gavekort</swp-page-title>
<swp-page-title>Fordelskort</swp-page-title>
</swp-topbar-left>
<swp-topbar-right>
<swp-btn class="primary" id="openCreateDrawer">
<i class="ph ph-plus"></i>
Opret gavekort
Opret fordelskort
</swp-btn>
</swp-topbar-right>
</swp-topbar>
@ -817,7 +817,7 @@
<swp-stats-bar>
<swp-stat-card class="highlight">
<swp-stat-value>47</swp-stat-value>
<swp-stat-label>Aktive gavekort</swp-stat-label>
<swp-stat-label>Aktive fordelskort</swp-stat-label>
</swp-stat-card>
<swp-stat-card>
<swp-stat-value>23.500 DKK</swp-stat-value>
@ -863,7 +863,7 @@
<!-- Table -->
<swp-table>
<swp-table-header>
<swp-th>Gavekort</swp-th>
<swp-th>Fordelskort</swp-th>
<swp-th>Modtager</swp-th>
<swp-th class="right">Original</swp-th>
<swp-th>Saldo</swp-th>
@ -875,7 +875,7 @@
<swp-table-row onclick="location.href='poc-gavekort-detail.html'">
<swp-td>
<swp-giftcard-cell>
<swp-giftcard-code>GC-A7X2-9KM4</swp-giftcard-code>
<swp-giftcard-code>FK-A7X2-9KM4</swp-giftcard-code>
<swp-giftcard-date>Oprettet 15. jan 2024</swp-giftcard-date>
</swp-giftcard-cell>
</swp-td>
@ -902,7 +902,7 @@
<swp-table-row>
<swp-td>
<swp-giftcard-cell>
<swp-giftcard-code>GC-B3K9-2LM7</swp-giftcard-code>
<swp-giftcard-code>FK-B3K9-2LM7</swp-giftcard-code>
<swp-giftcard-date>Oprettet 20. dec 2024</swp-giftcard-date>
</swp-giftcard-cell>
</swp-td>
@ -928,7 +928,7 @@
<swp-table-row>
<swp-td>
<swp-giftcard-cell>
<swp-giftcard-code>GC-C5P1-8NQ3</swp-giftcard-code>
<swp-giftcard-code>FK-C5P1-8NQ3</swp-giftcard-code>
<swp-giftcard-date>Oprettet 10. nov 2024</swp-giftcard-date>
</swp-giftcard-cell>
</swp-td>
@ -955,7 +955,7 @@
<swp-table-row>
<swp-td>
<swp-giftcard-cell>
<swp-giftcard-code>GC-D2R4-6TY9</swp-giftcard-code>
<swp-giftcard-code>FK-D2R4-6TY9</swp-giftcard-code>
<swp-giftcard-date>Oprettet 5. sep 2024</swp-giftcard-date>
</swp-giftcard-cell>
</swp-td>
@ -982,7 +982,7 @@
<swp-table-row>
<swp-td>
<swp-giftcard-cell>
<swp-giftcard-code>GC-E8W3-4VX1</swp-giftcard-code>
<swp-giftcard-code>FK-E8W3-4VX1</swp-giftcard-code>
<swp-giftcard-date>Oprettet 1. jun 2024</swp-giftcard-date>
</swp-giftcard-cell>
</swp-td>
@ -1008,7 +1008,7 @@
<swp-table-row>
<swp-td>
<swp-giftcard-cell>
<swp-giftcard-code>GC-F9Q7-3WK5</swp-giftcard-code>
<swp-giftcard-code>FK-F9Q7-3WK5</swp-giftcard-code>
<swp-giftcard-date>Oprettet 28. dec 2024</swp-giftcard-date>
</swp-giftcard-cell>
</swp-td>
@ -1033,7 +1033,7 @@
</swp-table-row>
</swp-table-body>
<swp-table-footer>
<span>Viser 6 af 47 gavekort</span>
<span>Viser 6 af 47 fordelskort</span>
<span>Side 1 af 8</span>
</swp-table-footer>
</swp-table>
@ -1045,7 +1045,7 @@
<!-- Create Gift Card Drawer -->
<swp-drawer id="createDrawer">
<swp-drawer-header>
<swp-drawer-title>Opret gavekort</swp-drawer-title>
<swp-drawer-title>Opret fordelskort</swp-drawer-title>
<swp-drawer-close id="closeDrawer">
<i class="ph ph-x"></i>
</swp-drawer-close>
@ -1053,9 +1053,9 @@
<swp-drawer-content>
<swp-form-field>
<swp-form-label>Gavekortkode</swp-form-label>
<swp-form-label>Kortkode</swp-form-label>
<swp-input-group>
<input type="text" id="giftcardCode" class="mono" value="GC-K8M2-5NP7" readonly />
<input type="text" id="giftcardCode" class="mono" value="FK-K8M2-5NP7" readonly />
<button type="button" id="generateCode">
<i class="ph ph-arrows-clockwise"></i>
Ny kode
@ -1116,7 +1116,7 @@
<swp-drawer-footer>
<swp-btn class="secondary" id="cancelCreate">Annuller</swp-btn>
<swp-btn class="primary" id="saveGiftcard">Opret gavekort</swp-btn>
<swp-btn class="primary" id="saveGiftcard">Opret fordelskort</swp-btn>
</swp-drawer-footer>
</swp-drawer>
@ -1156,7 +1156,7 @@
// Generate random code
function generateCode() {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
let code = 'GC-';
let code = 'FK-';
for (let i = 0; i < 4; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}

View file

@ -3370,6 +3370,118 @@ Tak for din handel!</swp-edit-textarea>
</swp-module-card>
</swp-modules-grid>
</swp-modules-section>
<!-- Integrationer sektion -->
<swp-modules-section>
<swp-modules-header>
<swp-modules-title>
<i class="ph ph-plugs-connected"></i>
Integrationer
</swp-modules-title>
</swp-modules-header>
<swp-modules-grid>
<!-- Sygeforsikring "danmark" -->
<swp-module-card class="featured">
<swp-module-header>
<swp-module-icon class="green">
<i class="ph ph-heart-half"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Sygeforsikring "danmark"</swp-module-title>
<swp-module-desc>Gør det nemt for dine kunder at få tilskud. Send automatisk kvitteringer til "danmark" så kunderne får deres penge tilbage uden selv at løfte en finger.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-features>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Automatisk indsendelse af kvitteringer</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Direkte integration via API</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Kunden får tilskud uden besvær</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Øget kundetilfredshed</span>
</swp-module-feature>
</swp-module-features>
<swp-module-stats>
<swp-module-stat>
<swp-module-stat-value>2.1M</swp-module-stat-value>
<swp-module-stat-label>Medlemmer i DK</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>100%</swp-module-stat-value>
<swp-module-stat-label>Automatiseret</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>0 kr</swp-module-stat-value>
<swp-module-stat-label>Ekstra gebyr</swp-module-stat-label>
</swp-module-stat>
</swp-module-stats>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small primary">Opsæt integration</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Kalenderintegration -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="blue">
<i class="ph ph-calendar-check"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Kalenderintegration</swp-module-title>
<swp-module-desc>Få dine bookinger synkroniseret til din private kalender automatisk. Se alle aftaler samlet ét sted - også når du er offline.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-features>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Google Kalender</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Apple iCloud Kalender</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Microsoft Outlook</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Tovejs-synkronisering</span>
</swp-module-feature>
</swp-module-features>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
</swp-modules-grid>
</swp-modules-section>
</swp-tab-content>
<!-- ==========================================

View file

@ -123,7 +123,7 @@
<swp-page-header>
<swp-page-title>
<h1>Abonnement & Konto</h1>
<p>Administrer dit abonnement, brugere og betalingsinfo</p>
<p>Administrer dit abonnement og betalingsinfo</p>
</swp-page-title>
</swp-page-header>
@ -261,208 +261,6 @@
</swp-plan-grid>
</swp-section>
<!-- ==========================================
USERS SECTION
========================================== -->
<swp-section>
<swp-section-header>
<swp-section-title>
<i class="ph ph-users"></i>
Brugere
</swp-section-title>
</swp-section-header>
<swp-users-header>
<swp-users-count>
<strong>5 af 8</strong> brugere
<swp-users-progress>
<swp-users-progress-bar style="width: 62.5%"></swp-users-progress-bar>
</swp-users-progress>
</swp-users-count>
<swp-btn class="primary">
<i class="ph ph-user-plus"></i>
Inviter bruger
</swp-btn>
</swp-users-header>
<swp-table-card>
<swp-table>
<swp-table-header>
<swp-table-row>
<swp-table-cell>Bruger</swp-table-cell>
<swp-table-cell>Rolle</swp-table-cell>
<swp-table-cell>Status</swp-table-cell>
<swp-table-cell>Sidst aktiv</swp-table-cell>
<swp-table-cell></swp-table-cell>
</swp-table-row>
</swp-table-header>
<swp-table-body>
<!-- User 1 - Owner -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar>MJ</swp-user-avatar>
<swp-user-details>
<swp-user-name>Maria Jensen</swp-user-name>
<swp-user-email>maria@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge class="owner">Ejer</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>I dag, 14:32</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 2 - Admin -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="purple">AS</swp-user-avatar>
<swp-user-details>
<swp-user-name>Anna Sørensen</swp-user-name>
<swp-user-email>anna@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge class="admin">Admin</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>I dag, 12:15</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Fjern bruger">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 3 -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="blue">LP</swp-user-avatar>
<swp-user-details>
<swp-user-name>Louise Pedersen</swp-user-name>
<swp-user-email>louise@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge>Medarbejder</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>I går, 17:45</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Fjern bruger">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 4 -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="amber">KN</swp-user-avatar>
<swp-user-details>
<swp-user-name>Katrine Nielsen</swp-user-name>
<swp-user-email>katrine@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge>Medarbejder</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>27. dec, 09:30</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Fjern bruger">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 5 - Invited -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="purple">SH</swp-user-avatar>
<swp-user-details>
<swp-user-name>Sofie Hansen</swp-user-name>
<swp-user-email>sofie@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge>Medarbejder</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="invited">
<swp-status-dot></swp-status-dot>
Invitation sendt
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>-</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Send invitation igen">
<i class="ph ph-paper-plane-tilt"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Annuller invitation">
<i class="ph ph-x"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
</swp-table-body>
</swp-table>
</swp-table-card>
</swp-section>
<!-- ==========================================
BILLING SECTION
========================================== -->

View file

@ -1650,7 +1650,7 @@
<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">
<swp-side-menu-item onclick="location.href='poc-medarbejdere.html'" data-tooltip="Medarbejdere">
<i class="ph ph-user"></i>
<span>Medarbejdere</span>
</swp-side-menu-item>

View file

@ -0,0 +1,533 @@
<!doctype html>
<html lang="da">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lønspecifikation Januar 2026</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
/* ===== Print setup ===== */
@page { size: A4; margin: 14mm; }
@media print {
.no-print { display: none !important; }
.page-break { break-after: page; page-break-after: always; }
a { color: inherit; text-decoration: none; }
}
/* ===== Base ===== */
:root {
--ink: #0f172a;
--muted: #475569;
--line: #e2e8f0;
--soft: #f8fafc;
--accent: #0ea5e9;
--accent-2: #22c55e;
--font-mono: 'JetBrains Mono', monospace;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
color: var(--ink);
background: #fff;
}
.sheet {
max-width: 210mm;
margin: 0 auto;
}
/* ===== Header ===== */
.hdr {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 14px 0 10px;
border-bottom: 2px solid var(--line);
margin-bottom: 12px;
}
.brand {
display: flex;
flex-direction: column;
gap: 6px;
}
.title {
font-size: 20px;
font-weight: 800;
letter-spacing: .2px;
margin: 0;
line-height: 1.1;
}
.subtitle {
margin: 0;
color: var(--muted);
font-size: 12px;
}
.meta {
text-align: right;
min-width: 260px;
}
.meta .pill {
display: inline-block;
font-size: 12px;
padding: 6px 10px;
border: 1px solid var(--line);
border-radius: 999px;
background: var(--soft);
margin-bottom: 8px;
}
.meta .kv {
display: grid;
grid-template-columns: auto auto;
gap: 4px 12px;
justify-content: end;
font-size: 12px;
color: var(--muted);
}
.meta .kv b { color: var(--ink); font-weight: 600; }
/* ===== Blocks ===== */
.card {
border: 1px solid var(--line);
border-radius: 14px;
overflow: hidden;
background: #fff;
margin-bottom: 12px;
}
.card .hd {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 12px;
background: linear-gradient(0deg, var(--soft), #fff);
border-bottom: 1px solid var(--line);
}
.card .hd h2 {
font-size: 13px;
margin: 0;
letter-spacing: .2px;
text-transform: uppercase;
color: var(--muted);
}
.card .bd { padding: 12px; }
.grid {
display: grid;
grid-template-columns: 1.2fr .8fr;
gap: 12px;
}
/* ===== Total ===== */
.total {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
padding: 14px 14px;
border-radius: 14px;
border: 1px solid var(--line);
background: var(--soft);
margin-bottom: 12px;
}
.total .label {
color: var(--muted);
font-size: 12px;
text-transform: uppercase;
letter-spacing: .25px;
margin-bottom: 6px;
}
.total .big {
font-size: 28px;
font-weight: 900;
font-family: var(--font-mono);
margin: 0;
line-height: 1.05;
}
.total .big small {
font-size: 14px;
font-weight: 700;
color: var(--muted);
}
.badge {
display: inline-block;
font-size: 11px;
padding: 4px 8px;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--soft);
color: var(--muted);
}
/* ===== Tables ===== */
table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
}
th, td {
padding: 8px 8px;
border-bottom: 1px solid var(--line);
vertical-align: top;
}
th {
text-align: left;
color: var(--muted);
font-weight: 700;
font-size: 11px;
text-transform: uppercase;
letter-spacing: .2px;
background: var(--soft);
}
td.num, th.num { text-align: right; }
td.num { font-family: var(--font-mono); }
tr:last-child td { border-bottom: none; }
.note {
margin: 8px 0 0;
color: var(--muted);
font-size: 11px;
line-height: 1.35;
}
/* ===== Footer ===== */
.ftr {
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid var(--line);
display: flex;
justify-content: space-between;
gap: 12px;
font-size: 10.5px;
color: var(--muted);
}
/* ===== Ensure content doesn't get split awkwardly ===== */
.avoid-break { break-inside: avoid; page-break-inside: avoid; }
</style>
</head>
<body>
<!-- ===================== PAGE 1: OVERBLIK ===================== -->
<div class="sheet">
<div class="hdr">
<div class="brand">
<p class="title">Lønspecifikation</p>
<p class="subtitle">Periode: <b>Januar 2026</b></p>
</div>
<div class="meta">
<div class="pill">Medarbejdernr.: <b>EMP-001</b></div>
<div class="kv">
<span>Medarbejder:</span><b>Emma Larsen</b>
<span>Afdeling:</span><b>Frisør</b>
<span>Ansættelse:</span><b>Fuldtid (37 t/uge)</b>
</div>
</div>
</div>
<section class="total avoid-break">
<div>
<div class="label">Bruttoløn (Januar 2026)</div>
<p class="big">34.063,50 <small>kr</small></p>
</div>
</section>
<section class="grid">
<div class="card avoid-break">
<div class="hd">
<h2>Samlet lønopgørelse</h2>
</div>
<div class="bd">
<table>
<thead>
<tr>
<th>Løndel</th>
<th class="num">Beløb</th>
</tr>
</thead>
<tbody>
<tr>
<td>Grundløn inkl. overarbejde</td>
<td class="num">29.322,50 kr</td>
</tr>
<tr>
<td>Provision i alt</td>
<td class="num">3.685,00 kr</td>
</tr>
<tr>
<td>Tillæg i alt</td>
<td class="num">1.056,00 kr</td>
</tr>
<tr>
<td><b>Bruttoløn</b></td>
<td class="num"><b>34.063,50 kr</b></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card avoid-break">
<div class="hd">
<h2>Saldi</h2>
</div>
<div class="bd">
<table>
<thead>
<tr>
<th>Type</th>
<th class="num">Optjent</th>
<th class="num">Afholdt</th>
<th class="num">Rest</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ferie (dage)</td>
<td class="num">18,5</td>
<td class="num">6,0</td>
<td class="num">12,5</td>
</tr>
<tr>
<td>Afspadsering (timer)</td>
<td class="num">12,0</td>
<td class="num">4,0</td>
<td class="num">8,0</td>
</tr>
</tbody>
</table>
<p class="note">Saldi er opgjort som angivet på lønspecifikationen.</p>
</div>
</div>
</section>
<section class="card avoid-break">
<div class="hd">
<h2>Hurtigt resumé</h2>
</div>
<div class="bd">
<table>
<thead>
<tr>
<th>Nøglepunkt</th>
<th class="num">Værdi</th>
</tr>
</thead>
<tbody>
<tr>
<td>Normaltimer</td>
<td class="num">148,0 t</td>
</tr>
<tr>
<td>Overarbejde</td>
<td class="num">7,0 t</td>
</tr>
<tr>
<td>Provision (services + produkter)</td>
<td class="num">3.685,00 kr</td>
</tr>
<tr>
<td>Tillæg (aften + lørdag + søndag)</td>
<td class="num">1.056,00 kr</td>
</tr>
</tbody>
</table>
</div>
</section>
<div class="ftr">
<div>Overblik</div>
<div style="text-align:right">Lønspecifikation · Januar 2026</div>
</div>
<div class="page-break"></div>
<!-- ===================== PAGE 2: DETALJER ===================== -->
<section class="card">
<div class="hd">
<h2>Arbejdstid pr. uge</h2>
</div>
<div class="bd">
<table>
<thead>
<tr>
<th>Uge</th>
<th class="num">Normaltimer</th>
<th class="num">Overtid</th>
<th class="num">Beløb</th>
</tr>
</thead>
<tbody>
<tr>
<td>Uge 1 (30. dec 5. jan)</td>
<td class="num">37,0 t</td>
<td class="num">2,0 t</td>
<td class="num">7.400,00 kr</td>
</tr>
<tr>
<td>Uge 2 (6. 12. jan)</td>
<td class="num">37,0 t</td>
<td class="num">3,5 t</td>
<td class="num">7.816,25 kr</td>
</tr>
<tr>
<td>Uge 3 (13. 19. jan)</td>
<td class="num">37,0 t</td>
<td class="num">0,0 t</td>
<td class="num">6.845,00 kr</td>
</tr>
<tr>
<td>Uge 4 (20. 26. jan)</td>
<td class="num">37,0 t</td>
<td class="num">1,5 t</td>
<td class="num">7.261,25 kr</td>
</tr>
<tr>
<td><b>I alt</b></td>
<td class="num"><b>148,0 t</b></td>
<td class="num"><b>7,0 t</b></td>
<td class="num"><b>29.322,50 kr</b></td>
</tr>
</tbody>
</table>
<p class="note">
Satser: Normal 185,00 kr/time. Overtid (50%) 277,50 kr/time.
</p>
</div>
</section>
<section class="card">
<div class="hd">
<h2>Provision</h2>
</div>
<div class="bd">
<p class="note" style="margin-top:0">
<b>Services:</b> 15% af omsætning over minimum (220 kr/time).<br/>
<b>Produkter:</b> 10% af salg.
</p>
<table>
<thead>
<tr>
<th>Uge</th>
<th class="num">Service prov.</th>
<th class="num">Produkt prov.</th>
<th class="num">I alt</th>
</tr>
</thead>
<tbody>
<tr>
<td>Uge 1</td>
<td class="num">573,00 kr</td>
<td class="num">210,00 kr</td>
<td class="num">783,00 kr</td>
</tr>
<tr>
<td>Uge 2</td>
<td class="num">883,50 kr</td>
<td class="num">320,00 kr</td>
<td class="num">1.203,50 kr</td>
</tr>
<tr>
<td>Uge 3</td>
<td class="num">459,00 kr</td>
<td class="num">180,00 kr</td>
<td class="num">639,00 kr</td>
</tr>
<tr>
<td>Uge 4</td>
<td class="num">769,50 kr</td>
<td class="num">290,00 kr</td>
<td class="num">1.059,50 kr</td>
</tr>
<tr>
<td><b>I alt</b></td>
<td class="num"><b>2.685,00 kr</b></td>
<td class="num"><b>1.000,00 kr</b></td>
<td class="num"><b>3.685,00 kr</b></td>
</tr>
</tbody>
</table>
</div>
</section>
<section class="card">
<div class="hd">
<h2>Tillæg & fravær</h2>
</div>
<div class="bd">
<div class="grid" style="grid-template-columns: 1fr 1fr;">
<div>
<table>
<thead>
<tr>
<th>Tillæg</th>
<th class="num">Timer</th>
<th class="num">Beløb</th>
</tr>
</thead>
<tbody>
<tr>
<td>Aftentillæg (hverdage 1821)</td>
<td class="num">12,0</td>
<td class="num">336,00 kr</td>
</tr>
<tr>
<td>Lørdagstillæg (før kl. 14)</td>
<td class="num">16,0</td>
<td class="num">720,00 kr</td>
</tr>
<tr>
<td>Søndagstillæg</td>
<td class="num">0,0</td>
<td class="num">0,00 kr</td>
</tr>
<tr>
<td><b>Tillæg i alt</b></td>
<td class="num"></td>
<td class="num"><b>1.056,00 kr</b></td>
</tr>
</tbody>
</table>
</div>
<div>
<table>
<thead>
<tr>
<th>Fravær</th>
<th class="num">Dage</th>
<th class="num">Beløb</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ferie med løn</td>
<td class="num">0</td>
<td class="num">0,00 kr</td>
</tr>
<tr>
<td>Sygdom</td>
<td class="num">0</td>
<td class="num">0,00 kr</td>
</tr>
<tr>
<td>Barns sygedag</td>
<td class="num">0</td>
<td class="num">0,00 kr</td>
</tr>
</tbody>
</table>
<p class="note">Ingen fravær registreret i perioden.</p>
</div>
</div>
</div>
</section>
<div class="ftr">
<div>Detaljer</div>
<div style="text-align:right">Lønspecifikation · Januar 2026</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,588 @@
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Medarbejdere - 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" />
<link rel="stylesheet" href="css/konto.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;
}
/* 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;
}
body {
font-family: var(--font-family);
font-size: 14px;
color: var(--color-text);
background: var(--color-background);
line-height: 1.5;
}
/* ==========================================
ROLE BADGES
========================================== */
swp-role-badge.leader {
background: color-mix(in srgb, var(--color-blue) 15%, transparent);
color: var(--color-blue);
}
/* ==========================================
STATS CARDS
========================================== */
swp-stats-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin-bottom: 24px;
}
swp-stat-card {
display: flex;
flex-direction: column;
gap: 4px;
padding: 20px;
background: var(--color-surface);
border-radius: 12px;
border: 1px solid var(--color-border);
}
swp-stat-value {
font-size: 28px;
font-weight: 600;
color: var(--color-text);
}
swp-stat-label {
font-size: 13px;
color: var(--color-text-secondary);
}
swp-stat-card.teal swp-stat-value {
color: var(--color-teal);
}
swp-stat-card.amber swp-stat-value {
color: var(--color-amber);
}
swp-stat-card.purple swp-stat-value {
color: var(--color-purple);
}
/* ==========================================
TABS
========================================== */
swp-tabs {
display: flex;
gap: 4px;
border-bottom: 1px solid var(--color-border);
margin-bottom: 24px;
}
swp-tab {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 20px;
font-size: 14px;
font-weight: 500;
color: var(--color-text-secondary);
cursor: pointer;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
transition: all 150ms ease;
}
swp-tab:hover {
color: var(--color-text);
background: var(--color-background-hover);
}
swp-tab[data-active="true"] {
color: var(--color-teal);
border-bottom-color: var(--color-teal);
}
swp-tab i {
font-size: 18px;
}
swp-tab-content {
display: none;
}
swp-tab-content[data-active="true"] {
display: block;
}
/* ==========================================
PERMISSIONS MATRIX
========================================== */
swp-permissions-matrix {
display: block;
background: var(--color-surface);
border-radius: 12px;
overflow: hidden;
}
swp-permissions-matrix table {
width: 100%;
border-collapse: collapse;
}
swp-permissions-matrix th,
swp-permissions-matrix td {
padding: 14px 16px;
text-align: center;
border-bottom: 1px solid var(--color-border);
}
swp-permissions-matrix th:first-child,
swp-permissions-matrix td:first-child {
text-align: left;
font-weight: 500;
}
swp-permissions-matrix thead th {
background: var(--color-background-alt);
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--color-text-secondary);
}
swp-permissions-matrix tbody tr:last-child td {
border-bottom: none;
}
swp-permissions-matrix .permission-name {
display: flex;
align-items: center;
gap: 10px;
}
swp-permissions-matrix .permission-name i {
font-size: 18px;
color: var(--color-text-secondary);
}
swp-permissions-matrix .check {
color: var(--color-teal);
font-size: 20px;
}
swp-permissions-matrix .no-access {
color: var(--color-border);
font-size: 16px;
}
</style>
</head>
<body>
<swp-page-container>
<!-- Page Header -->
<swp-page-header>
<swp-page-title>
<h1>Medarbejdere</h1>
<p>Administrer brugere, roller og rettigheder</p>
</swp-page-title>
</swp-page-header>
<!-- Stats Cards -->
<swp-stats-row>
<swp-stat-card class="teal">
<swp-stat-value>4</swp-stat-value>
<swp-stat-label>Aktive medarbejdere</swp-stat-label>
</swp-stat-card>
<swp-stat-card class="amber">
<swp-stat-value>1</swp-stat-value>
<swp-stat-label>Afventer invitation</swp-stat-label>
</swp-stat-card>
<swp-stat-card class="purple">
<swp-stat-value>4</swp-stat-value>
<swp-stat-label>Roller defineret</swp-stat-label>
</swp-stat-card>
</swp-stats-row>
<!-- Tabs -->
<swp-tabs>
<swp-tab data-tab="brugere" data-active="true">
<i class="ph ph-users"></i>
Brugere
</swp-tab>
<swp-tab data-tab="roller">
<i class="ph ph-shield-check"></i>
Roller
</swp-tab>
</swp-tabs>
<!-- Tab: Brugere -->
<swp-tab-content data-tab="brugere" data-active="true">
<swp-users-header>
<swp-users-count>
<strong>5 af 8</strong> brugere
<swp-users-progress>
<swp-users-progress-bar style="width: 62.5%"></swp-users-progress-bar>
</swp-users-progress>
</swp-users-count>
<swp-btn class="primary">
<i class="ph ph-user-plus"></i>
Inviter bruger
</swp-btn>
</swp-users-header>
<swp-table-card>
<swp-table>
<swp-table-header>
<swp-table-row>
<swp-table-cell>Bruger</swp-table-cell>
<swp-table-cell>Rolle</swp-table-cell>
<swp-table-cell>Status</swp-table-cell>
<swp-table-cell>Sidst aktiv</swp-table-cell>
<swp-table-cell></swp-table-cell>
</swp-table-row>
</swp-table-header>
<swp-table-body>
<!-- User 1 - Owner -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar>MJ</swp-user-avatar>
<swp-user-details>
<swp-user-name>Maria Jensen</swp-user-name>
<swp-user-email>maria@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge class="owner">Ejer</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>I dag, 14:32</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 2 - Admin -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="purple">AS</swp-user-avatar>
<swp-user-details>
<swp-user-name>Anna Sørensen</swp-user-name>
<swp-user-email>anna@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge class="admin">Admin</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>I dag, 12:15</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Fjern bruger">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 3 - Leder -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="blue">LP</swp-user-avatar>
<swp-user-details>
<swp-user-name>Louise Pedersen</swp-user-name>
<swp-user-email>louise@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge class="leader">Leder</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>I går, 17:45</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Fjern bruger">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 4 -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="amber">KN</swp-user-avatar>
<swp-user-details>
<swp-user-name>Katrine Nielsen</swp-user-name>
<swp-user-email>katrine@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge>Medarbejder</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="active">
<swp-status-dot></swp-status-dot>
Aktiv
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>27. dec, 09:30</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Rediger">
<i class="ph ph-pencil"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Fjern bruger">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
<!-- User 5 - Invited -->
<swp-table-row>
<swp-table-cell>
<swp-user-info>
<swp-user-avatar class="purple">SH</swp-user-avatar>
<swp-user-details>
<swp-user-name>Sofie Hansen</swp-user-name>
<swp-user-email>sofie@salonbeauty.dk</swp-user-email>
</swp-user-details>
</swp-user-info>
</swp-table-cell>
<swp-table-cell>
<swp-role-badge>Medarbejder</swp-role-badge>
</swp-table-cell>
<swp-table-cell>
<swp-status-badge class="invited">
<swp-status-dot></swp-status-dot>
Invitation sendt
</swp-status-badge>
</swp-table-cell>
<swp-table-cell>-</swp-table-cell>
<swp-table-cell>
<swp-table-actions>
<swp-icon-btn title="Send invitation igen">
<i class="ph ph-paper-plane-tilt"></i>
</swp-icon-btn>
<swp-icon-btn class="danger" title="Annuller invitation">
<i class="ph ph-x"></i>
</swp-icon-btn>
</swp-table-actions>
</swp-table-cell>
</swp-table-row>
</swp-table-body>
</swp-table>
</swp-table-card>
</swp-tab-content>
<!-- Tab: Roller -->
<swp-tab-content data-tab="roller">
<swp-permissions-matrix>
<table>
<thead>
<tr>
<th>Rettighed</th>
<th>Ejer</th>
<th>Admin</th>
<th>Leder</th>
<th>Medarbejder</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span class="permission-name">
<i class="ph ph-calendar"></i>
Kalender
</span>
</td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
</tr>
<tr>
<td>
<span class="permission-name">
<i class="ph ph-users"></i>
Medarbejdere
</span>
</td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-minus no-access"></i></td>
</tr>
<tr>
<td>
<span class="permission-name">
<i class="ph ph-address-book"></i>
Kunder
</span>
</td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
</tr>
<tr>
<td>
<span class="permission-name">
<i class="ph ph-chart-bar"></i>
Rapporter & Økonomi
</span>
</td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-check-circle check"></i></td>
<td><i class="ph ph-minus no-access"></i></td>
<td><i class="ph ph-minus no-access"></i></td>
</tr>
</tbody>
</table>
</swp-permissions-matrix>
</swp-tab-content>
</swp-page-container>
<script>
// Simple tab switching
document.querySelectorAll('swp-tab').forEach(tab => {
tab.addEventListener('click', () => {
const tabName = tab.dataset.tab;
// Update tab active states
document.querySelectorAll('swp-tab').forEach(t => t.removeAttribute('data-active'));
tab.setAttribute('data-active', 'true');
// Update content active states
document.querySelectorAll('swp-tab-content').forEach(c => c.removeAttribute('data-active'));
document.querySelector(`swp-tab-content[data-tab="${tabName}"]`).setAttribute('data-active', 'true');
});
});
</script>
</body>
</html>

1133
wwwroot/poc-salg.html Normal file

File diff suppressed because it is too large Load diff