Calendar/wwwroot/poc-gavekort-detail.html
Janus C. H. Knudsen fac7754d7a 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
2026-01-07 22:12:25 +01:00

1533 lines
40 KiB
HTML

<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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>
/* ==========================================
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
========================================== */
: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 */
@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;
}
}
: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;
}
/* ==========================================
TOPBAR
========================================== */
swp-topbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 24px;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
position: sticky;
top: 0;
z-index: 100;
}
swp-topbar-left {
display: flex;
align-items: center;
gap: 16px;
}
swp-back-link {
display: flex;
align-items: center;
gap: 8px;
color: var(--color-text-secondary);
text-decoration: none;
font-size: 14px;
cursor: pointer;
transition: color 150ms ease;
}
swp-back-link:hover {
color: var(--color-teal);
}
swp-back-link i {
font-size: 18px;
}
swp-page-title {
font-size: 16px;
font-weight: 600;
font-family: var(--font-mono);
}
swp-topbar-right {
display: flex;
align-items: center;
gap: 12px;
}
/* ==========================================
LAYOUT
========================================== */
swp-page-container {
display: block;
max-width: 1200px;
margin: 0 auto;
padding: 24px;
}
swp-two-columns {
display: grid;
grid-template-columns: 1fr 400px;
gap: 24px;
}
/* ==========================================
BUTTONS
========================================== */
swp-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 18px;
font-size: 13px;
font-weight: 500;
font-family: var(--font-family);
border-radius: 6px;
cursor: pointer;
transition: all 150ms ease;
border: none;
}
swp-btn i {
font-size: 18px;
}
swp-btn.primary {
background: var(--color-teal);
color: white;
}
swp-btn.primary:hover {
background: #00796b;
}
swp-btn.secondary {
background: var(--color-surface);
border: 1px solid var(--color-border);
color: var(--color-text);
}
swp-btn.secondary:hover {
background: var(--color-background-hover);
}
swp-btn.danger {
background: transparent;
border: 1px solid var(--color-red);
color: var(--color-red);
}
swp-btn.danger:hover {
background: color-mix(in srgb, var(--color-red) 10%, transparent);
}
/* ==========================================
CARDS
========================================== */
swp-card {
display: block;
background: var(--color-surface);
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
padding: 20px;
margin-bottom: 20px;
}
swp-card:last-child {
margin-bottom: 0;
}
swp-section-label {
display: block;
font-size: 11px;
font-weight: 600;
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 12px;
}
/* ==========================================
BALANCE DISPLAY
========================================== */
swp-balance-display {
display: flex;
align-items: baseline;
gap: 12px;
margin-bottom: 16px;
}
swp-balance-amount {
font-size: 36px;
font-weight: 700;
font-family: var(--font-mono);
color: var(--color-text);
}
swp-balance-original {
font-size: 14px;
color: var(--color-text-secondary);
}
swp-balance-bar {
width: 100%;
height: 8px;
background: var(--color-border);
border-radius: 4px;
overflow: hidden;
margin-bottom: 8px;
}
swp-balance-bar-fill {
display: block;
height: 100%;
background: var(--color-green);
border-radius: 4px;
transition: width 300ms ease;
}
swp-balance-text {
font-size: 13px;
color: var(--color-text-secondary);
}
/* ==========================================
EXPIRY WARNING
========================================== */
swp-expiry-box {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 16px;
background: var(--color-background-alt);
border-radius: 6px;
margin-top: 20px;
}
swp-expiry-box i {
font-size: 24px;
color: var(--color-text-secondary);
}
swp-expiry-box.warning {
background: color-mix(in srgb, var(--color-amber) 12%, transparent);
}
swp-expiry-box.warning i {
color: var(--color-amber);
}
swp-expiry-info {
flex: 1;
}
swp-expiry-label {
display: block;
font-size: 12px;
color: var(--color-text-secondary);
}
swp-expiry-date {
display: block;
font-size: 15px;
font-weight: 600;
color: var(--color-text);
}
swp-expiry-box.warning swp-expiry-date {
color: var(--color-amber);
}
/* ==========================================
KEY-VALUE ROWS
========================================== */
swp-kv-list {
display: flex;
flex-direction: column;
}
swp-kv-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
}
swp-kv-row:last-child {
border-bottom: none;
padding-bottom: 0;
}
swp-kv-row:first-child {
padding-top: 0;
}
swp-kv-label {
font-size: 13px;
color: var(--color-text-secondary);
}
swp-kv-value {
font-size: 14px;
font-weight: 500;
color: var(--color-text);
}
swp-kv-value.mono {
font-family: var(--font-mono);
}
swp-kv-value.with-action {
display: flex;
align-items: center;
gap: 8px;
}
swp-copy-btn {
background: none;
border: none;
color: var(--color-text-secondary);
cursor: pointer;
padding: 4px;
border-radius: 4px;
transition: all 150ms ease;
display: flex;
}
swp-copy-btn:hover {
background: var(--color-background-hover);
color: var(--color-teal);
}
/* Status badge */
swp-status-badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-size: 11px;
font-weight: 500;
border-radius: 12px;
}
swp-status-badge.active {
background: color-mix(in srgb, var(--color-green) 15%, transparent);
color: var(--color-green);
}
swp-status-badge.partial {
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
color: var(--color-amber);
}
swp-status-badge.depleted {
background: color-mix(in srgb, var(--color-text-secondary) 15%, transparent);
color: var(--color-text-secondary);
}
swp-status-badge.expired {
background: color-mix(in srgb, var(--color-red) 15%, transparent);
color: var(--color-red);
}
/* ==========================================
ACTIONS ROW
========================================== */
swp-actions-row {
display: flex;
gap: 8px;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid var(--color-border);
}
swp-actions-row swp-btn {
flex: 1;
justify-content: center;
}
/* ==========================================
RECIPIENT CARD
========================================== */
swp-recipient-row {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 0;
}
swp-recipient-row:first-child {
padding-top: 0;
}
swp-recipient-row i {
font-size: 18px;
color: var(--color-text-secondary);
width: 20px;
}
swp-recipient-row span {
font-size: 14px;
color: var(--color-text);
}
swp-recipient-row a {
color: var(--color-teal);
text-decoration: none;
}
swp-recipient-row a:hover {
text-decoration: underline;
}
swp-send-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 12px;
margin-top: 16px;
background: color-mix(in srgb, var(--color-teal) 10%, transparent);
border: 1px solid color-mix(in srgb, var(--color-teal) 30%, transparent);
border-radius: 6px;
color: var(--color-teal);
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 150ms ease;
}
swp-send-btn:hover {
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
}
swp-send-btn i {
font-size: 18px;
}
/* ==========================================
TRANSACTION TABLE
========================================== */
swp-table {
display: block;
width: 100%;
}
swp-table-header {
display: grid;
grid-template-columns: 90px 1fr 100px 90px;
padding: 0 0 10px 0;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--color-text-secondary);
border-bottom: 1px solid var(--color-border);
}
swp-table-row {
display: grid;
grid-template-columns: 90px 1fr 100px 90px;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
align-items: center;
}
swp-table-row:last-child {
border-bottom: none;
}
swp-td {
font-size: 13px;
color: var(--color-text);
}
swp-td.muted {
color: var(--color-text-secondary);
}
swp-td.mono {
font-family: var(--font-mono);
}
swp-td.right {
text-align: right;
}
swp-td.positive {
color: var(--color-green);
}
swp-td.negative {
color: var(--color-red);
}
swp-td a {
color: var(--color-teal);
text-decoration: none;
}
swp-td a:hover {
text-decoration: underline;
}
swp-transaction-details {
display: flex;
flex-direction: column;
gap: 2px;
}
swp-transaction-type {
font-size: 13px;
color: var(--color-text);
}
swp-transaction-meta {
font-size: 12px;
color: var(--color-text-secondary);
}
swp-transaction-meta a {
color: var(--color-teal);
text-decoration: none;
}
swp-transaction-meta a:hover {
text-decoration: underline;
}
/* ==========================================
NOTES
========================================== */
swp-card textarea {
width: 100%;
padding: 12px;
border: 1px solid var(--color-border);
border-radius: 6px;
font-size: 14px;
font-family: var(--font-family);
background: var(--color-background-alt);
color: var(--color-text);
resize: none;
min-height: 80px;
}
swp-card textarea:focus {
outline: none;
border-color: var(--color-teal);
}
/* ==========================================
OVERLAY & DRAWERS
========================================== */
swp-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.3);
opacity: 0;
visibility: hidden;
transition: opacity 200ms ease, visibility 0ms 200ms;
z-index: 500;
}
swp-overlay.open {
opacity: 1;
visibility: visible;
transition-delay: 0ms;
}
swp-drawer {
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: 400px;
background: var(--color-surface);
border-left: 1px solid var(--color-border);
transform: translateX(100%);
transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
flex-direction: column;
z-index: 700;
}
swp-drawer.open {
transform: translateX(0);
}
swp-email-preview {
position: fixed;
top: 0;
right: 400px;
bottom: 0;
width: 480px;
background: var(--color-background);
border-left: 1px solid var(--color-border);
transform: translateX(100%);
opacity: 0;
transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1), opacity 250ms ease;
display: flex;
flex-direction: column;
z-index: 600;
pointer-events: none;
}
swp-email-preview.open {
transform: translateX(0);
opacity: 1;
pointer-events: auto;
}
swp-preview-header {
display: flex;
align-items: center;
gap: 8px;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border);
background: var(--color-surface);
font-size: 13px;
font-weight: 500;
color: var(--color-text-secondary);
}
swp-preview-header i {
font-size: 18px;
}
swp-preview-content {
flex: 1;
overflow-y: auto;
padding: 24px;
display: flex;
justify-content: center;
}
swp-email-template {
display: block;
width: 100%;
max-width: 380px;
background: var(--color-surface);
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
swp-email-body {
display: block;
padding: 24px;
}
swp-email-icon {
display: flex;
justify-content: center;
margin-bottom: 16px;
}
swp-email-icon i {
font-size: 48px;
color: var(--color-teal);
}
swp-email-title {
display: block;
text-align: center;
font-size: 18px;
font-weight: 600;
color: var(--color-text);
margin-bottom: 20px;
}
swp-giftcard-visual {
display: block;
background: var(--color-background-alt);
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 24px;
margin-bottom: 20px;
text-align: center;
}
swp-giftcard-amount {
display: block;
font-size: 32px;
font-weight: 700;
font-family: var(--font-mono);
color: var(--color-teal);
margin-bottom: 8px;
}
swp-giftcard-code-display {
display: block;
font-family: var(--font-mono);
font-size: 14px;
letter-spacing: 2px;
color: var(--color-text-secondary);
}
swp-email-message {
display: block;
padding: 14px 16px;
background: var(--color-background-alt);
border-radius: 6px;
margin-bottom: 20px;
font-style: italic;
font-size: 14px;
color: var(--color-text);
min-height: 50px;
line-height: 1.5;
}
swp-email-sender {
display: block;
text-align: center;
color: var(--color-text-secondary);
font-size: 13px;
}
swp-email-sender strong {
display: block;
color: var(--color-text);
margin-top: 4px;
}
swp-email-footer {
display: block;
padding: 16px 24px;
border-top: 1px solid var(--color-border);
text-align: center;
font-size: 12px;
color: var(--color-text-secondary);
}
swp-email-footer p {
margin: 2px 0;
}
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 {
background: none;
border: none;
font-size: 20px;
color: var(--color-text-secondary);
cursor: pointer;
padding: 4px;
border-radius: 4px;
transition: background 150ms ease;
display: flex;
}
swp-drawer-close:hover {
background: var(--color-background-hover);
}
swp-drawer-content {
flex: 1;
overflow-y: auto;
padding: 20px;
display: flex;
flex-direction: column;
gap: 20px;
}
swp-drawer-footer {
display: flex;
gap: 12px;
padding: 16px 20px;
border-top: 1px solid var(--color-border);
}
swp-drawer-footer swp-btn {
flex: 1;
}
swp-form-field {
display: flex;
flex-direction: column;
gap: 6px;
}
swp-form-label {
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--color-text-secondary);
}
swp-form-field input,
swp-form-field textarea {
padding: 10px 12px;
border: 1px solid var(--color-border);
border-radius: 6px;
font-size: 14px;
font-family: var(--font-family);
background: var(--color-surface);
color: var(--color-text);
transition: border-color 150ms ease;
}
swp-form-field input:focus,
swp-form-field textarea:focus {
outline: none;
border-color: var(--color-teal);
}
swp-form-field textarea {
resize: none;
min-height: 100px;
}
/* ==========================================
ADD VALUE DRAWER
========================================== */
swp-balance-info-box {
display: block;
padding: 16px;
background: var(--color-background-alt);
border-radius: 6px;
}
swp-balance-info-box swp-current-amount {
display: block;
font-size: 24px;
font-weight: 700;
font-family: var(--font-mono);
color: var(--color-text);
}
swp-balance-info-box swp-original-amount {
display: block;
font-size: 13px;
color: var(--color-text-secondary);
margin-top: 4px;
}
swp-new-balance-box {
display: block;
padding: 16px;
background: color-mix(in srgb, var(--color-green) 10%, transparent);
border: 1px solid color-mix(in srgb, var(--color-green) 30%, transparent);
border-radius: 6px;
}
swp-new-balance-box swp-new-amount {
display: block;
font-size: 24px;
font-weight: 700;
font-family: var(--font-mono);
color: var(--color-green);
}
swp-new-balance-box swp-new-label {
display: block;
font-size: 13px;
color: var(--color-text-secondary);
margin-top: 4px;
}
swp-quick-amounts {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 8px;
}
swp-quick-amount {
padding: 8px 16px;
border: 1px solid var(--color-border);
border-radius: 6px;
font-size: 13px;
font-family: var(--font-mono);
background: var(--color-surface);
color: var(--color-text);
cursor: pointer;
transition: all 150ms ease;
}
swp-quick-amount:hover {
background: var(--color-background-hover);
border-color: var(--color-teal);
}
swp-quick-amount.selected {
background: color-mix(in srgb, var(--color-teal) 10%, transparent);
border-color: var(--color-teal);
color: var(--color-teal);
}
/* Toggle Slider (Ja/Nej) */
swp-toggle-slider {
display: inline-flex;
width: fit-content;
background: var(--color-background);
border-radius: 6px;
border: 1px solid var(--color-border);
overflow: hidden;
position: relative;
}
swp-toggle-slider::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: calc(50% - 4px);
height: calc(100% - 4px);
background: color-mix(in srgb, var(--color-green) 18%, white);
border-radius: 4px;
transition: transform 200ms ease, background 200ms ease;
}
swp-toggle-slider[data-value="no"]::before {
transform: translateX(100%);
background: color-mix(in srgb, var(--color-red) 18%, white);
}
swp-toggle-option {
position: relative;
z-index: 1;
padding: 5px 16px;
font-size: 12px;
font-weight: 500;
color: var(--color-text-secondary);
cursor: pointer;
transition: color 150ms ease;
user-select: none;
}
swp-toggle-slider[data-value="yes"] swp-toggle-option:first-child {
color: var(--color-green);
font-weight: 600;
}
swp-toggle-slider[data-value="no"] swp-toggle-option:last-child {
color: var(--color-red);
font-weight: 600;
}
swp-date-extend {
display: flex;
flex-direction: column;
gap: 10px;
}
swp-current-expiry {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
color: var(--color-text-secondary);
}
swp-current-expiry i {
font-size: 16px;
}
swp-current-expiry strong {
color: var(--color-text);
}
swp-date-extend input[type="date"] {
padding: 10px 12px;
border: 1px solid var(--color-border);
border-radius: 6px;
font-size: 14px;
font-family: var(--font-family);
background: var(--color-surface);
color: var(--color-text);
transition: border-color 150ms ease;
}
swp-date-extend input[type="date"]:focus {
outline: none;
border-color: var(--color-teal);
}
/* ==========================================
RESPONSIVE
========================================== */
@media (max-width: 1000px) {
swp-two-columns {
grid-template-columns: 1fr;
}
swp-email-preview {
display: none;
}
}
</style>
</head>
<body>
<!-- Topbar -->
<swp-topbar>
<swp-topbar-left>
<swp-back-link onclick="location.href='poc-gavekort.html'">
<i class="ph ph-caret-left"></i>
Fordelskort
</swp-back-link>
<swp-page-title>FK-A7X2-9KM4</swp-page-title>
</swp-topbar-left>
<swp-topbar-right>
</swp-topbar-right>
</swp-topbar>
<swp-page-container>
<swp-two-columns>
<!-- Left Column -->
<div>
<!-- Balance & Info Card -->
<swp-card>
<swp-section-label>Saldo</swp-section-label>
<swp-balance-display>
<swp-balance-amount>350 DKK</swp-balance-amount>
<swp-balance-original>af 500 DKK</swp-balance-original>
</swp-balance-display>
<swp-balance-bar>
<swp-balance-bar-fill style="width: 70%"></swp-balance-bar-fill>
</swp-balance-bar>
<swp-balance-text>70% tilbage</swp-balance-text>
<swp-expiry-box>
<i class="ph ph-calendar"></i>
<swp-expiry-info>
<swp-expiry-label>Udløbsdato</swp-expiry-label>
<swp-expiry-date>31. december 2025</swp-expiry-date>
</swp-expiry-info>
</swp-expiry-box>
<swp-actions-row>
<swp-btn class="secondary" id="openAddValueDrawer">
<i class="ph ph-sliders-horizontal"></i>
Juster
</swp-btn>
<swp-btn class="secondary" id="openEmailDrawer">
<i class="ph ph-envelope"></i>
Send på email
</swp-btn>
</swp-actions-row>
</swp-card>
<!-- Gift Card Details -->
<swp-card>
<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">
FK-A7X2-9KM4
<swp-copy-btn onclick="copyCode()">
<i class="ph ph-copy"></i>
</swp-copy-btn>
</swp-kv-value>
</swp-kv-row>
<swp-kv-row>
<swp-kv-label>Status</swp-kv-label>
<swp-kv-value>
<swp-status-badge class="partial">Delvist brugt</swp-status-badge>
</swp-kv-value>
</swp-kv-row>
<swp-kv-row>
<swp-kv-label>Oprettet</swp-kv-label>
<swp-kv-value>15. januar 2024</swp-kv-value>
</swp-kv-row>
<swp-kv-row>
<swp-kv-label>Original værdi</swp-kv-label>
<swp-kv-value class="mono">500 DKK</swp-kv-value>
</swp-kv-row>
<swp-kv-row>
<swp-kv-label>Aktiv</swp-kv-label>
<swp-kv-value>
<swp-toggle-slider data-value="yes" id="activeToggle">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-kv-value>
</swp-kv-row>
</swp-kv-list>
</swp-card>
<!-- Transactions -->
<swp-card>
<swp-section-label>Transaktioner</swp-section-label>
<swp-table>
<swp-table-header>
<span>Dato</span>
<span>Beskrivelse</span>
<span style="text-align: right">Beløb</span>
<span style="text-align: right">Saldo</span>
</swp-table-header>
<swp-table-row>
<swp-td class="muted">22/2-24</swp-td>
<swp-td>
<swp-transaction-details>
<swp-transaction-type>Indløst ved booking</swp-transaction-type>
<swp-transaction-meta>
<a href="#">Faktura #1847</a> · <a href="#">Maria Hansen</a>
</swp-transaction-meta>
</swp-transaction-details>
</swp-td>
<swp-td class="mono right negative">-150 DKK</swp-td>
<swp-td class="mono right">350 DKK</swp-td>
</swp-table-row>
<swp-table-row>
<swp-td class="muted">15/1-24</swp-td>
<swp-td>
<swp-transaction-details>
<swp-transaction-type>Kort oprettet</swp-transaction-type>
<swp-transaction-meta>
<a href="#">Faktura #1652</a> · <a href="#">Signe Larsen</a>
</swp-transaction-meta>
</swp-transaction-details>
</swp-td>
<swp-td class="mono right positive">+500 DKK</swp-td>
<swp-td class="mono right">500 DKK</swp-td>
</swp-table-row>
</swp-table>
</swp-card>
</div>
<!-- Right Column -->
<div>
<!-- Recipient -->
<swp-card>
<swp-section-label>Modtager</swp-section-label>
<swp-recipient-row>
<i class="ph ph-user"></i>
<span><a href="#">Maria Hansen</a></span>
</swp-recipient-row>
<swp-recipient-row>
<i class="ph ph-envelope"></i>
<span>maria@example.com</span>
</swp-recipient-row>
<swp-recipient-row>
<i class="ph ph-phone"></i>
<span>+45 12 34 56 78</span>
</swp-recipient-row>
<swp-send-btn id="openEmailDrawerAlt">
<i class="ph ph-paper-plane-tilt"></i>
Send fordelskort på email
</swp-send-btn>
</swp-card>
<!-- Notes -->
<swp-card>
<swp-section-label>Intern note</swp-section-label>
<textarea placeholder="Tilføj intern note...">Fødselsdagsgave fra Signe.</textarea>
</swp-card>
</div>
</swp-two-columns>
</swp-page-container>
<!-- Overlay -->
<swp-overlay id="overlay"></swp-overlay>
<!-- Email Preview Panel -->
<swp-email-preview id="emailPreview">
<swp-preview-header>
<i class="ph ph-eye"></i>
Email preview
</swp-preview-header>
<swp-preview-content>
<swp-email-template>
<swp-email-body>
<swp-email-icon>
<i class="ph ph-gift"></i>
</swp-email-icon>
<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>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>
Med venlig hilsen
<strong id="previewSender">Salon Glamour</strong>
</swp-email-sender>
</swp-email-body>
<swp-email-footer>
<p>Gyldig til: 31. december 2025</p>
<p>Kan bruges hos: Salon Glamour</p>
</swp-email-footer>
</swp-email-template>
</swp-preview-content>
</swp-email-preview>
<!-- Send Email Drawer -->
<swp-drawer id="emailDrawer">
<swp-drawer-header>
<swp-drawer-title>Send fordelskort</swp-drawer-title>
<swp-drawer-close id="closeEmailDrawer">
<i class="ph ph-x"></i>
</swp-drawer-close>
</swp-drawer-header>
<swp-drawer-content>
<swp-form-field>
<swp-form-label>Modtager email</swp-form-label>
<input type="email" id="recipientEmail" value="maria@example.com" />
</swp-form-field>
<swp-form-field>
<swp-form-label>Personlig besked</swp-form-label>
<textarea id="personalMessage" placeholder="Skriv en personlig besked til modtageren..."></textarea>
</swp-form-field>
<swp-form-field>
<swp-form-label>Afsender navn</swp-form-label>
<input type="text" id="senderName" value="Salon Glamour" />
</swp-form-field>
</swp-drawer-content>
<swp-drawer-footer>
<swp-btn class="secondary" id="cancelEmail">Annuller</swp-btn>
<swp-btn class="primary" id="sendEmail">
<i class="ph ph-paper-plane-tilt"></i>
Send email
</swp-btn>
</swp-drawer-footer>
</swp-drawer>
<!-- Add Value Drawer -->
<swp-drawer id="addValueDrawer">
<swp-drawer-header>
<swp-drawer-title>Juster fordelskort</swp-drawer-title>
<swp-drawer-close id="closeAddValueDrawer">
<i class="ph ph-x"></i>
</swp-drawer-close>
</swp-drawer-header>
<swp-drawer-content>
<swp-form-field>
<swp-form-label>Nuværende saldo</swp-form-label>
<swp-balance-info-box>
<swp-current-amount>350 DKK</swp-current-amount>
<swp-original-amount>af 500 DKK original værdi</swp-original-amount>
</swp-balance-info-box>
</swp-form-field>
<swp-form-field>
<swp-form-label>Beløb at tilføje</swp-form-label>
<input type="text" id="addValueAmount" class="mono" placeholder="Indtast beløb" value="100 DKK" />
<swp-quick-amounts>
<swp-quick-amount data-value="50">50 DKK</swp-quick-amount>
<swp-quick-amount data-value="100" class="selected">100 DKK</swp-quick-amount>
<swp-quick-amount data-value="200">200 DKK</swp-quick-amount>
<swp-quick-amount data-value="500">500 DKK</swp-quick-amount>
</swp-quick-amounts>
</swp-form-field>
<swp-form-field>
<swp-form-label>Ny saldo</swp-form-label>
<swp-new-balance-box>
<swp-new-amount id="newBalanceAmount">450 DKK</swp-new-amount>
<swp-new-label>Efter tilføjelse</swp-new-label>
</swp-new-balance-box>
</swp-form-field>
<swp-form-field>
<swp-form-label>Forlæng udløbsdato (valgfri)</swp-form-label>
<swp-date-extend>
<swp-current-expiry>
<i class="ph ph-calendar"></i>
<span>Nuværende: <strong>31. december 2025</strong></span>
</swp-current-expiry>
<input type="date" id="newExpiryDate" value="2026-12-31" />
</swp-date-extend>
</swp-form-field>
<swp-form-field>
<swp-form-label>Intern note</swp-form-label>
<textarea id="addValueNote" placeholder="Beskriv hvorfor værdi tilføjes..."></textarea>
</swp-form-field>
</swp-drawer-content>
<swp-drawer-footer>
<swp-btn class="secondary" id="cancelAddValue">Annuller</swp-btn>
<swp-btn class="primary" id="confirmAddValue">
<i class="ph ph-check"></i>
Gem ændringer
</swp-btn>
</swp-drawer-footer>
</swp-drawer>
<script>
// Elements
const overlay = document.getElementById('overlay');
const emailDrawer = document.getElementById('emailDrawer');
const emailPreview = document.getElementById('emailPreview');
const openEmailBtn = document.getElementById('openEmailDrawer');
const openEmailBtnAlt = document.getElementById('openEmailDrawerAlt');
const closeEmailBtn = document.getElementById('closeEmailDrawer');
const cancelEmailBtn = document.getElementById('cancelEmail');
const sendEmailBtn = document.getElementById('sendEmail');
// Preview elements
const previewMessage = document.getElementById('previewMessage');
const previewSender = document.getElementById('previewSender');
const personalMessageInput = document.getElementById('personalMessage');
const senderNameInput = document.getElementById('senderName');
// Open email drawer
function openEmailDrawerFn() {
overlay.classList.add('open');
emailDrawer.classList.add('open');
emailPreview.classList.add('open');
document.body.style.overflow = 'hidden';
}
// Close email drawer
function closeEmailDrawerFn() {
overlay.classList.remove('open');
emailDrawer.classList.remove('open');
emailPreview.classList.remove('open');
document.body.style.overflow = '';
}
// Update preview in real-time
function updatePreview() {
const message = personalMessageInput.value.trim();
const sender = senderNameInput.value.trim();
previewMessage.textContent = message || 'Din besked vises her...';
previewMessage.style.opacity = message ? '1' : '0.5';
previewSender.textContent = sender || 'Salon Glamour';
}
// Copy code to clipboard
function copyCode() {
navigator.clipboard.writeText('FK-A7X2-9KM4').then(() => {
alert('Kode kopieret!');
});
}
// Event listeners
openEmailBtn.addEventListener('click', openEmailDrawerFn);
openEmailBtnAlt.addEventListener('click', openEmailDrawerFn);
closeEmailBtn.addEventListener('click', closeEmailDrawerFn);
cancelEmailBtn.addEventListener('click', closeEmailDrawerFn);
// Real-time preview updates
personalMessageInput.addEventListener('input', updatePreview);
senderNameInput.addEventListener('input', updatePreview);
// Send email (demo)
sendEmailBtn.addEventListener('click', () => {
alert('Email sendt! (Demo)');
closeEmailDrawerFn();
});
// Initialize preview
updatePreview();
// ==========================================
// ADD VALUE DRAWER
// ==========================================
const addValueDrawer = document.getElementById('addValueDrawer');
const openAddValueBtn = document.getElementById('openAddValueDrawer');
const closeAddValueBtn = document.getElementById('closeAddValueDrawer');
const cancelAddValueBtn = document.getElementById('cancelAddValue');
const confirmAddValueBtn = document.getElementById('confirmAddValue');
const addValueAmountInput = document.getElementById('addValueAmount');
const newBalanceAmount = document.getElementById('newBalanceAmount');
const addValueQuickAmounts = document.querySelectorAll('#addValueDrawer swp-quick-amount');
const currentBalance = 350; // Demo value
// Open add value drawer
function openAddValueDrawerFn() {
overlay.classList.add('open');
addValueDrawer.classList.add('open');
document.body.style.overflow = 'hidden';
updateNewBalance();
}
// Close add value drawer
function closeAddValueDrawerFn() {
overlay.classList.remove('open');
addValueDrawer.classList.remove('open');
document.body.style.overflow = '';
}
// Parse amount from string
function parseAmount(str) {
const num = parseInt(str.replace(/[^\d]/g, ''), 10);
return isNaN(num) ? 0 : num;
}
// Update new balance calculation
function updateNewBalance() {
const addAmount = parseAmount(addValueAmountInput.value);
const newBalance = currentBalance + addAmount;
newBalanceAmount.textContent = newBalance.toLocaleString('da-DK') + ' DKK';
}
// Event listeners
openAddValueBtn.addEventListener('click', openAddValueDrawerFn);
closeAddValueBtn.addEventListener('click', closeAddValueDrawerFn);
cancelAddValueBtn.addEventListener('click', closeAddValueDrawerFn);
// Quick amount selection
addValueQuickAmounts.forEach(btn => {
btn.addEventListener('click', () => {
addValueQuickAmounts.forEach(b => b.classList.remove('selected'));
btn.classList.add('selected');
const value = btn.dataset.value;
addValueAmountInput.value = Number(value).toLocaleString('da-DK') + ' DKK';
updateNewBalance();
});
});
// Live update on input
addValueAmountInput.addEventListener('input', updateNewBalance);
// Confirm add value (demo)
confirmAddValueBtn.addEventListener('click', () => {
alert('Værdi tilføjet! (Demo)');
closeAddValueDrawerFn();
});
// Update overlay click to close any open drawer
overlay.addEventListener('click', () => {
closeEmailDrawerFn();
closeAddValueDrawerFn();
});
// Update Escape to close any drawer
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
closeEmailDrawerFn();
closeAddValueDrawerFn();
}
});
// Toggle sliders (Ja/Nej)
document.querySelectorAll('swp-toggle-slider').forEach(slider => {
slider.addEventListener('click', () => {
slider.dataset.value = slider.dataset.value === 'yes' ? 'no' : 'yes';
});
});
</script>
</body>
</html>