Restyling UI

This commit is contained in:
Mark Pinkster 2026-01-16 12:43:16 +01:00
parent 9939300245
commit 5d4a591de6
10 changed files with 942 additions and 89 deletions

View File

@ -1,6 +1,6 @@
# Telvero Talpa Planning System
Een geavanceerd TV-planning systeem voor het beheren en plannen van homeshopping uitzendingen op Talpa zenders (SBS9, Net5, Veronica).
Een geavanceerd TV-planning systeem voor het beheren en plannen van homeshopping uitzendingen op Talpa zenders (SBS9, Net5, SBS6).
## 🎯 Functionaliteiten
@ -130,7 +130,7 @@ chmod 644 api/*.php
1. Ga naar **Blokken** in het menu
2. Klik op "Nieuw Template"
3. Vul de gegevens in:
- Zender (SBS9, NET5, VERONICA)
- Zender (SBS9, NET5, SBS6)
- Template naam (bijv. "SBS9 Dagblok")
- Dag van de week
- Standaard starttijd

View File

@ -88,7 +88,7 @@ function getBlockColor($channel) {
$colors = [
'SBS9' => 'rgba(52, 152, 219, 0.1)', // Light blue
'NET5' => 'rgba(231, 76, 60, 0.1)', // Light red
'VERONICA' => 'rgba(155, 89, 182, 0.1)' // Light purple
'SBS6' => 'rgba(155, 89, 182, 0.1)' // Light purple
];
return $colors[$channel] ?? 'rgba(200, 200, 200, 0.1)';

View File

@ -1,16 +1,77 @@
/**
* Custom Styles for Telvero Talpa Planning System
* Redesigned for uniform UI and typography
*/
:root {
--text-color: #404040;
/* Legacy support */
--text-color: #212529;
--brand-color: #32327D;
--accent-color: #32B4AA;
--primary-color: #32327D;
--secondary-color: #32327D;
--success-color: #2ecc71;
--warning-color: #f39c12;
--danger-color: #e74c3c;
--success-color: #28A745;
--warning-color: #FFC107;
--danger-color: #DC3545;
/* Brand Colors */
--brand-primary: #32327D;
--brand-accent: #32B4AA;
/* UI Colors - Rustig Palet */
--ui-bg-primary: #FFFFFF;
--ui-bg-secondary: #F8F9FA;
--ui-bg-tertiary: #E9ECEF;
--ui-border: #DEE2E6;
--ui-border-light: #E9ECEF;
/* Text Colors */
--text-primary: #212529;
--text-secondary: #6C757D;
--text-muted: #ADB5BD;
/* Status Colors - Gedempter */
--status-success: #28A745;
--status-success-light: #D4EDDA;
--status-warning: #FFC107;
--status-warning-light: #FFF3CD;
--status-danger: #DC3545;
--status-danger-light: #F8D7DA;
--status-info: #17A2B8;
--status-info-light: #D1ECF1;
/* Interaction States */
--hover-bg: #F1F3F5;
--active-bg: #E9ECEF;
--focus-ring: rgba(50, 50, 125, 0.25);
/* Typography */
--font-h1: 2rem;
--font-h2: 1.5rem;
--font-h3: 1.25rem;
--font-h4: 1.125rem;
--font-h5: 1rem;
--font-h6: 0.875rem;
--font-base: 0.9375rem;
--font-small: 0.875rem;
--font-tiny: 0.8125rem;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
/* Spacing System */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2rem;
--space-2xl: 3rem;
}
body {
@ -54,11 +115,23 @@ body {
background-color: var(--brand-color) !important;
}
/* Buttons */
/* ============================================
BUTTON SYSTEM - Uniform & Icon-Based
============================================ */
/* Base Button Styles */
.btn {
border-radius: 6px;
font-weight: 500;
transition: all 0.2s;
border-radius: 0.5rem;
font-weight: var(--font-weight-medium);
font-size: var(--font-base);
transition: all 0.15s ease;
padding: 0.5rem 1rem;
min-width: 40px;
height: 38px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.btn:hover {
@ -66,9 +139,172 @@ body {
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.btn:active {
transform: translateY(0);
}
.btn:focus {
outline: none;
box-shadow: 0 0 0 3px var(--focus-ring);
}
/* Button Sizes */
.btn-xs {
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
border-radius: 0.25rem;
min-width: 32px;
height: 28px;
}
.btn-sm {
padding: 0.375rem 0.75rem;
font-size: var(--font-small);
border-radius: 0.375rem;
min-width: 36px;
height: 32px;
}
.btn-lg {
padding: 0.75rem 1.5rem;
font-size: 1rem;
border-radius: 0.5rem;
min-width: 48px;
height: 44px;
}
/* Icon-Only Buttons */
.btn-icon {
background: transparent;
border: 1px solid var(--ui-border);
color: var(--text-secondary);
padding: 0.5rem;
min-width: 38px;
width: 38px;
height: 38px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 0.375rem;
transition: all 0.15s ease;
}
.btn-icon:hover {
background: var(--hover-bg);
border-color: var(--ui-border);
color: var(--text-primary);
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.btn-icon:active {
background: var(--active-bg);
transform: translateY(0);
}
.btn-icon:focus {
outline: none;
box-shadow: 0 0 0 3px var(--focus-ring);
}
/* Icon Button Sizes */
.btn-icon-xs {
min-width: 28px;
width: 28px;
height: 28px;
padding: 0.25rem;
border-radius: 0.25rem;
}
.btn-icon-sm {
min-width: 32px;
width: 32px;
height: 32px;
padding: 0.375rem;
border-radius: 0.375rem;
}
.btn-icon-lg {
min-width: 44px;
width: 44px;
height: 44px;
padding: 0.75rem;
border-radius: 0.5rem;
}
/* Icon Button Color Variants */
.btn-icon-primary {
border-color: var(--brand-primary);
color: var(--brand-primary);
}
.btn-icon-primary:hover {
background: var(--brand-primary);
color: white;
}
.btn-icon-secondary {
border-color: var(--ui-border);
color: var(--text-secondary);
}
.btn-icon-secondary:hover {
background: var(--hover-bg);
color: var(--text-primary);
}
.btn-icon-success {
border-color: var(--status-success);
color: var(--status-success);
}
.btn-icon-success:hover {
background: var(--status-success);
color: white;
}
.btn-icon-danger {
border-color: var(--status-danger);
color: var(--status-danger);
}
.btn-icon-danger:hover {
background: var(--status-danger);
color: white;
}
.btn-icon-warning {
border-color: var(--status-warning);
color: #856404;
}
.btn-icon-warning:hover {
background: var(--status-warning);
color: #000;
}
.btn-icon-info {
border-color: var(--status-info);
color: var(--status-info);
}
.btn-icon-info:hover {
background: var(--status-info);
color: white;
}
/* Action Button Groups */
.action-buttons {
display: inline-flex;
gap: 0.25rem;
align-items: center;
}
/* Standard Button Colors */
.btn-primary {
background-color: var(--brand-color);
border-color: var(--brand-color);
background-color: var(--brand-primary);
border-color: var(--brand-primary);
color: white;
}
.btn-primary:hover,
@ -76,21 +312,78 @@ body {
.btn-primary:active {
background-color: #28286a;
border-color: #28286a;
color: white;
}
.btn-outline-primary {
color: var(--brand-color);
border-color: var(--brand-color);
color: var(--brand-primary);
border-color: var(--brand-primary);
background: transparent;
}
.btn-outline-primary:hover,
.btn-outline-primary:focus,
.btn-outline-primary:active {
background-color: var(--brand-color);
border-color: var(--brand-color);
background-color: var(--brand-primary);
border-color: var(--brand-primary);
color: #ffffff;
}
.btn-success {
background-color: var(--status-success);
border-color: var(--status-success);
color: white;
}
.btn-success:hover {
background-color: #218838;
border-color: #218838;
}
.btn-danger {
background-color: var(--status-danger);
border-color: var(--status-danger);
color: white;
}
.btn-danger:hover {
background-color: #c82333;
border-color: #c82333;
}
.btn-info {
background-color: var(--status-info);
border-color: var(--status-info);
color: white;
}
.btn-info:hover {
background-color: #138496;
border-color: #138496;
}
.btn-warning {
background-color: var(--status-warning);
border-color: var(--status-warning);
color: #000;
}
.btn-warning:hover {
background-color: #e0a800;
border-color: #e0a800;
}
.btn-secondary {
background-color: var(--text-secondary);
border-color: var(--text-secondary);
color: white;
}
.btn-secondary:hover {
background-color: #5a6268;
border-color: #5a6268;
}
/* Tables */
.table {
border-radius: 8px;
@ -512,6 +805,41 @@ body {
padding: 8px 12px;
}
/* ============================================
BADGE SYSTEM - Status & Sync Indicators
============================================ */
/* Sync Status Badges */
.badge-sync {
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
font-weight: 600;
border-radius: 0.25rem;
display: inline-flex;
align-items: center;
gap: 0.25rem;
}
.badge-sync-complete {
background: var(--status-success-light);
color: var(--status-success);
}
.badge-sync-partial {
background: var(--status-warning-light);
color: #856404;
}
.badge-sync-none {
background: var(--status-danger-light);
color: var(--status-danger);
}
.badge-sync-empty {
background: var(--ui-bg-tertiary);
color: var(--text-secondary);
}
/* Sync Status Indicators */
.sync-indicator {
font-size: 1.2rem;
@ -521,50 +849,91 @@ body {
}
.sync-indicator.sync-success {
color: #28a745;
color: var(--status-success);
}
.sync-indicator.sync-pending {
color: #dc3545;
color: var(--status-danger);
}
.sync-indicator.sync-error {
color: #ffc107;
color: var(--status-warning);
}
.sync-indicator:hover {
transform: scale(1.2);
}
/* Block Sync Status Badges */
/* Block Sync Status Badges (Legacy Support) */
.block-sync-status {
font-size: 0.85rem;
padding: 0.35em 0.65em;
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
font-weight: 600;
border-radius: 4px;
border-radius: 0.25rem;
display: inline-flex;
align-items: center;
gap: 4px;
gap: 0.25rem;
}
.block-sync-status.block-sync-complete {
background-color: #28a745;
color: white;
background-color: var(--status-success-light);
color: var(--status-success);
}
.block-sync-status.block-sync-partial {
background-color: #ffc107;
color: #000;
background-color: var(--status-warning-light);
color: #856404;
}
.block-sync-status.block-sync-none {
background-color: #dc3545;
color: white;
background-color: var(--status-danger-light);
color: var(--status-danger);
}
.block-sync-status.block-sync-empty {
background-color: #6c757d;
color: white;
background-color: var(--ui-bg-tertiary);
color: var(--text-secondary);
}
/* ============================================
PLANNER SPECIFIC STYLES
============================================ */
/* Block Header Redesign */
.block-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--space-sm) var(--space-md);
background: var(--ui-bg-secondary);
border-bottom: 1px solid var(--ui-border);
gap: var(--space-md);
}
.block-header-left {
display: flex;
align-items: center;
gap: var(--space-sm);
flex: 1;
}
.block-title {
margin: 0;
font-size: var(--font-h6);
font-weight: var(--font-weight-semibold);
color: var(--text-primary);
}
.block-header-actions {
display: flex;
gap: 0.25rem;
align-items: center;
}
.block-header-time {
font-size: var(--font-small);
color: var(--text-secondary);
white-space: nowrap;
}
/* Print Styles */

View File

@ -532,7 +532,7 @@ function updateBlockInfo(blocks) {
const channelColors = {
'SBS9': 'primary',
'NET5': 'danger',
'VERONICA': 'secondary'
'SBS6': 'secondary'
};
const color = channelColors[channel] || 'secondary';

View File

@ -162,7 +162,7 @@ $dayNames = [
<option value="">Selecteer zender...</option>
<option value="SBS9" <?= ($editTemplate && $editTemplate['channel'] == 'SBS9') ? 'selected' : '' ?>>SBS9</option>
<option value="NET5" <?= ($editTemplate && $editTemplate['channel'] == 'NET5') ? 'selected' : '' ?>>NET5</option>
<option value="VERONICA" <?= ($editTemplate && $editTemplate['channel'] == 'VERONICA') ? 'selected' : '' ?>>VERONICA</option>
<option value="SBS6" <?= ($editTemplate && $editTemplate['channel'] == 'SBS6') ? 'selected' : '' ?>>SBS6</option>
</select>
</div>
@ -256,16 +256,15 @@ $dayNames = [
<?php endif; ?>
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<div class="action-buttons">
<a href="?edit=<?= $template['id'] ?>"
class="btn btn-outline-primary" title="Bewerken">
class="btn-icon btn-icon-xs btn-icon-primary">
<i class="bi bi-pencil"></i>
</a>
<form method="POST" style="display:inline;">
<input type="hidden" name="template_id" value="<?= $template['id'] ?>">
<button type="submit" name="toggle_active"
class="btn btn-outline-<?= $template['is_active'] ? 'warning' : 'success' ?>"
title="<?= $template['is_active'] ? 'Deactiveren' : 'Activeren' ?>">
class="btn-icon btn-icon-xs btn-icon-<?= $template['is_active'] ? 'warning' : 'success' ?>">
<i class="bi bi-<?= $template['is_active'] ? 'pause' : 'play' ?>-circle"></i>
</button>
</form>
@ -273,7 +272,7 @@ $dayNames = [
onsubmit="return confirm('Weet je zeker dat je dit template wilt verwijderen?');">
<input type="hidden" name="template_id" value="<?= $template['id'] ?>">
<button type="submit" name="delete_template"
class="btn btn-outline-danger" title="Verwijderen">
class="btn-icon btn-icon-xs btn-icon-danger">
<i class="bi bi-trash"></i>
</button>
</form>

View File

@ -91,8 +91,8 @@ $infomercials = $db->query("
<h6 class="mb-0">
<i class="bi bi-calendar3"></i> Actieve Blokken voor Vandaag
</h6>
<button type="button" class="btn btn-sm btn-light" onclick="showSyncBlockModal()">
<i class="bi bi-cloud-upload"></i> Sync Blok naar Talpa
<button type="button" class="btn-icon btn-icon-sm btn-icon-success" onclick="showSyncBlockModal()">
<i class="bi bi-cloud-upload"></i>
</button>
</div>
<div class="card-body p-2" id="blockInfoContainer">
@ -108,15 +108,15 @@ $infomercials = $db->query("
</h6>
</div>
<div class="card-body p-2">
<div class="btn-group w-100" role="group">
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="adjustZoom(0.8)">
<i class="bi bi-dash-circle"></i> -
<div class="action-buttons w-100 justify-content-center">
<button type="button" class="btn-icon btn-icon-sm btn-icon-secondary" onclick="adjustZoom(0.8)">
<i class="bi bi-dash-circle"></i>
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="adjustZoom(1.0)" title="Reset">
<button type="button" class="btn-icon btn-icon-sm btn-icon-secondary" onclick="adjustZoom(1.0)">
<i class="bi bi-arrow-clockwise"></i>
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="adjustZoom(1.2)">
<i class="bi bi-plus-circle"></i> +
<button type="button" class="btn-icon btn-icon-sm btn-icon-secondary" onclick="adjustZoom(1.2)">
<i class="bi bi-plus-circle"></i>
</button>
</div>
<div class="mt-2 text-center">
@ -253,7 +253,7 @@ $infomercials = $db->query("
<i class="bi bi-trash"></i> Verwijderen
</button>
<button type="button" class="btn btn-success" id="syncEventBtn">
<i class="bi bi-cloud-upload"></i> Sync naar Talpa
<i class="bi bi-cloud-upload"></i> Sync
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Sluiten</button>
</div>
@ -319,7 +319,7 @@ $infomercials = $db->query("
<select class="form-select" id="syncBlockChannel">
<option value="SBS9">SBS9</option>
<option value="NET5">NET5</option>
<option value="VERONICA">VERONICA</option>
<option value="SBS6">SBS6</option>
</select>
</div>

View File

@ -316,14 +316,20 @@ if (isset($_GET['edit'])) {
<?= ucfirst($tx['api_status']) ?>
</span>
</td>
<td class="d-flex justify-content-center gap-2">
<a href="?edit=<?= $tx['id'] ?>&view_date=<?= $selectedDate ?>" class="btn btn-sm btn-outline-primary">Bewerk</a>
<td>
<div class="action-buttons justify-content-center">
<a href="?edit=<?= $tx['id'] ?>&view_date=<?= $selectedDate ?>" class="btn-icon btn-icon-xs btn-icon-primary">
<i class="bi bi-pencil"></i>
</a>
<?php if($tx['api_status'] !== 'synced'): ?>
<form method="POST" style="display:inline;">
<input type="hidden" name="sync_id" value="<?= $tx['id'] ?>">
<button type="submit" name="sync_item" class="btn btn-sm btn-success">Sync naar Talpa</button>
<button type="submit" name="sync_item" class="btn-icon btn-icon-xs btn-icon-success">
<i class="bi bi-cloud-upload"></i>
</button>
</form>
<?php endif; ?>
</div>
</td>
</tr>
<?php endforeach; ?>

View File

@ -469,38 +469,36 @@ function calculateNextStartTimeForBlock($db, $date, $channel, $blockId) {
}
?>
<div class="block-section" style="border-left-color: <?= $channel == 'SBS9' ? '#3498db' : '#e74c3c' ?>;">
<div class="block-header d-flex justify-content-between align-items-center">
<div>
<?= htmlspecialchars($block['template_name'] ?? 'Blok') ?>
<div class="block-header">
<div class="block-header-left">
<h6 class="block-title"><?= htmlspecialchars($block['template_name'] ?? 'Blok') ?></h6>
<!-- Block Sync Status Badge -->
<span class="badge block-sync-status <?= $blockSyncClass ?> ms-2"
title="<?= $syncedTransmissions ?> van <?= $totalTransmissions ?> transmissions gesynchroniseerd"
data-bs-toggle="tooltip">
<i class="bi <?= $blockSyncIcon ?>"></i> <?= $blockSyncLabel ?>
<span class="badge-sync <?= str_replace('block-sync-', 'badge-sync-', $blockSyncClass) ?>">
<i class="bi <?= $blockSyncIcon ?>"></i>
<?= $blockSyncLabel ?>
</span>
</div>
<button type="button" class="btn btn-sm btn-outline-dark ms-2"
<div class="block-header-actions">
<button type="button" class="btn-icon btn-icon-sm btn-icon-secondary"
data-bs-toggle="modal"
data-bs-target="#blockTimeModal<?= $block['id'] ?>"
title="Starttijd aanpassen">
data-bs-target="#blockTimeModal<?= $block['id'] ?>">
<i class="bi bi-clock"></i>
</button>
<button type="button" class="btn btn-sm btn-info ms-2"
<button type="button" class="btn-icon btn-icon-sm btn-icon-info"
data-bs-toggle="modal"
data-bs-target="#copyBlockModal<?= $block['id'] ?>"
title="Kopieer blok van andere dag">
<i class="bi bi-files"></i> Kopieer Blok
data-bs-target="#copyBlockModal<?= $block['id'] ?>">
<i class="bi bi-files"></i>
</button>
<button type="button" class="btn btn-sm btn-success ms-2"
onclick="syncBlockPlanner('<?= $selectedDate ?>', '<?= $channel ?>')"
title="Sync blok naar Talpa">
<i class="bi bi-cloud-upload"></i> Sync naar Talpa
<button type="button" class="btn-icon btn-icon-sm btn-icon-success"
onclick="syncBlockPlanner('<?= $selectedDate ?>', '<?= $channel ?>')">
<i class="bi bi-cloud-upload"></i>
</button>
</div>
<div>
<?= substr($blockStart, 0, 5) ?> - <?= substr($blockEnd, 0, 5) ?>
| Resterend: <strong><?= round($remainingMinutes) ?> min</strong>
<div class="block-header-time">
<?= substr($blockStart, 0, 5) ?> - <?= substr($blockEnd, 0, 5) ?> | <strong><?= round($remainingMinutes) ?> min</strong>
</div>
</div>
@ -580,7 +578,7 @@ function calculateNextStartTimeForBlock($db, $date, $channel, $blockId) {
</span>
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<div class="action-buttons">
<?php if ($index > 0): ?>
<form method="POST" style="display:inline;">
<input type="hidden" name="transmission_id" value="<?= $tx['id'] ?>">
@ -588,7 +586,7 @@ function calculateNextStartTimeForBlock($db, $date, $channel, $blockId) {
<input type="hidden" name="date" value="<?= $selectedDate ?>">
<input type="hidden" name="channel" value="<?= $channel ?>">
<input type="hidden" name="block_id" value="<?= $block['id'] ?>">
<button type="submit" name="reorder" class="btn btn-outline-secondary" title="Omhoog">
<button type="submit" name="reorder" class="btn-icon btn-icon-xs btn-icon-secondary">
<i class="bi bi-arrow-up"></i>
</button>
</form>
@ -601,7 +599,7 @@ function calculateNextStartTimeForBlock($db, $date, $channel, $blockId) {
<input type="hidden" name="date" value="<?= $selectedDate ?>">
<input type="hidden" name="channel" value="<?= $channel ?>">
<input type="hidden" name="block_id" value="<?= $block['id'] ?>">
<button type="submit" name="reorder" class="btn btn-outline-secondary" title="Omlaag">
<button type="submit" name="reorder" class="btn-icon btn-icon-xs btn-icon-secondary">
<i class="bi bi-arrow-down"></i>
</button>
</form>
@ -610,7 +608,7 @@ function calculateNextStartTimeForBlock($db, $date, $channel, $blockId) {
<form method="POST" style="display:inline;" onsubmit="return confirm('Verwijderen?');">
<input type="hidden" name="transmission_id" value="<?= $tx['id'] ?>">
<input type="hidden" name="date" value="<?= $selectedDate ?>">
<button type="submit" name="remove_transmission" class="btn btn-outline-danger" title="Verwijderen">
<button type="submit" name="remove_transmission" class="btn-icon btn-icon-xs btn-icon-danger">
<i class="bi bi-trash"></i>
</button>
</form>

View File

@ -302,7 +302,7 @@ document.querySelectorAll('[id^="copyBlockForm"]').forEach(form => {
**Input (GET parameters)**:
- `date` (required): Brondag in Y-m-d formaat
- `channel` (required): Zender naam (SBS9, NET5, VERONICA)
- `channel` (required): Zender naam (SBS9, NET5, SBS6)
- `template_id` (required): Template ID
**Output (JSON)**:

View File

@ -0,0 +1,481 @@
# Planner Redesign Plan - Uniforme UI & Typografie
## Overzicht
Redesign van de planner interface om een cleane, uniforme uitstraling te creëren met consistente knoppen, typografie en kleurgebruik. Focus op het verminderen van visuele ruis en het verbeteren van de gebruiksvriendelijkheid.
## Huidige Problemen
### Planner Interface ([`planner.php`](planner.php))
1. **Inconsistente knoppen**: Mix van verschillende button stijlen en groottes
- "Gepland" badge, "Leeg" badge, "Niet Gepland" badge (verschillende kleuren)
- "Starttijd aanpassen" knop met tekst + icoon
- "Kopieer Blok" knop met tekst + icoon
- "Sync naar Talpa" knop met tekst + icoon
- Omhoog/omlaag/verwijder knoppen in tabel (klein formaat)
- "Toevoegen" knop in dropdown rij
2. **Drukke header van blokken**: Te veel informatie en knoppen naast elkaar
3. **Inconsistente spacing**: Verschillende marges en paddings
4. **Te veel tekst op knoppen**: Kan compacter met alleen iconen waar duidelijk
### Andere Schermen
- [`calendar.php`](calendar.php): Sidebar met infomercials, zoom controls, block info
- [`blocks.php`](blocks.php): Template management met formulieren
- [`index.php`](index.php): Dashboard met statistieken en snelle acties
- [`infomercials.php`](infomercials.php): Lijst met infomercials en upload status
## Design System
### 1. Kleurenpalet (Rustig & Consistent)
#### Brand Colors (Behouden)
```css
--brand-primary: #32327D; /* Paars - hoofdkleur */
--brand-accent: #32B4AA; /* Turquoise - accent */
```
#### UI Kleuren (Nieuw - Rustig Palet)
```css
/* Neutrale basis */
--ui-bg-primary: #FFFFFF;
--ui-bg-secondary: #F8F9FA;
--ui-bg-tertiary: #E9ECEF;
--ui-border: #DEE2E6;
--ui-border-light: #E9ECEF;
/* Tekst */
--text-primary: #212529;
--text-secondary: #6C757D;
--text-muted: #ADB5BD;
/* Status kleuren (gedempter) */
--status-success: #28A745;
--status-success-light: #D4EDDA;
--status-warning: #FFC107;
--status-warning-light: #FFF3CD;
--status-danger: #DC3545;
--status-danger-light: #F8D7DA;
--status-info: #17A2B8;
--status-info-light: #D1ECF1;
/* Interactie */
--hover-bg: #F1F3F5;
--active-bg: #E9ECEF;
--focus-ring: rgba(50, 50, 125, 0.25);
```
#### Infomercial Kleuren
Blijven zoals ze zijn - dynamisch toegewezen per infomercial
### 2. Typografie Hiërarchie
```css
/* Headings */
--font-h1: 2rem; /* 32px - Page titles */
--font-h2: 1.5rem; /* 24px - Section titles */
--font-h3: 1.25rem; /* 20px - Card headers */
--font-h4: 1.125rem; /* 18px - Subsections */
--font-h5: 1rem; /* 16px - Small headers */
--font-h6: 0.875rem; /* 14px - Tiny headers */
/* Body */
--font-base: 0.9375rem; /* 15px - Base text */
--font-small: 0.875rem; /* 14px - Small text */
--font-tiny: 0.8125rem; /* 13px - Tiny text */
/* Weights */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
/* Line heights */
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
```
### 3. Button System
#### Button Sizes
```css
/* Extra Small - Voor tabel acties */
.btn-xs {
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
border-radius: 0.25rem;
min-width: 32px;
height: 28px;
}
/* Small - Voor compacte UI */
.btn-sm {
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
border-radius: 0.375rem;
min-width: 36px;
height: 32px;
}
/* Medium (default) - Standaard knoppen */
.btn {
padding: 0.5rem 1rem;
font-size: 0.9375rem;
border-radius: 0.5rem;
min-width: 40px;
height: 38px;
}
/* Large - Call-to-action knoppen */
.btn-lg {
padding: 0.75rem 1.5rem;
font-size: 1rem;
border-radius: 0.5rem;
min-width: 48px;
height: 44px;
}
```
#### Button Variants
**Icon-Only Buttons** (Geen tekst, alleen icoon)
- Verwijderen: `<button class="btn-icon btn-icon-danger"><i class="bi bi-trash"></i></button>`
- Bewerken: `<button class="btn-icon btn-icon-primary"><i class="bi bi-pencil"></i></button>`
- Omhoog: `<button class="btn-icon btn-icon-secondary"><i class="bi bi-arrow-up"></i></button>`
- Omlaag: `<button class="btn-icon btn-icon-secondary"><i class="bi bi-arrow-down"></i></button>`
- Kopiëren: `<button class="btn-icon btn-icon-info"><i class="bi bi-files"></i></button>`
- Sync: `<button class="btn-icon btn-icon-success"><i class="bi bi-cloud-upload"></i></button>`
- Tijd aanpassen: `<button class="btn-icon btn-icon-secondary"><i class="bi bi-clock"></i></button>`
**Text + Icon Buttons** (Voor belangrijke acties)
- Primaire acties: "Toevoegen", "Opslaan", "Synchroniseren"
- Gebruik alleen waar context nodig is
**Ghost Buttons** (Subtiele acties)
- Transparante achtergrond, alleen border
- Voor secundaire acties
#### Button States
```css
/* Default state */
.btn-icon {
background: transparent;
border: 1px solid var(--ui-border);
color: var(--text-secondary);
transition: all 0.15s ease;
}
/* Hover state */
.btn-icon:hover {
background: var(--hover-bg);
border-color: var(--ui-border);
color: var(--text-primary);
transform: translateY(-1px);
}
/* Active state */
.btn-icon:active {
background: var(--active-bg);
transform: translateY(0);
}
/* Focus state */
.btn-icon:focus {
outline: none;
box-shadow: 0 0 0 3px var(--focus-ring);
}
```
### 4. Spacing System
```css
/* Consistent spacing scale */
--space-xs: 0.25rem; /* 4px */
--space-sm: 0.5rem; /* 8px */
--space-md: 1rem; /* 16px */
--space-lg: 1.5rem; /* 24px */
--space-xl: 2rem; /* 32px */
--space-2xl: 3rem; /* 48px */
```
### 5. Badges & Status Indicators
```css
/* Sync status badges */
.badge-sync {
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
font-weight: 600;
border-radius: 0.25rem;
display: inline-flex;
align-items: center;
gap: 0.25rem;
}
.badge-sync-complete {
background: var(--status-success-light);
color: var(--status-success);
}
.badge-sync-partial {
background: var(--status-warning-light);
color: #856404;
}
.badge-sync-none {
background: var(--status-danger-light);
color: var(--status-danger);
}
.badge-sync-empty {
background: var(--ui-bg-tertiary);
color: var(--text-secondary);
}
```
## Implementatie Plan
### Fase 1: Core Design System ([`assets/css/custom.css`](assets/css/custom.css))
1. **Voeg CSS variabelen toe**
- Kleurenpalet
- Typografie schaal
- Spacing systeem
2. **Creëer button system**
- `.btn-icon` classes
- Size variants (xs, sm, md, lg)
- Color variants (primary, secondary, success, danger, info, warning)
- States (hover, active, focus, disabled)
3. **Creëer badge system**
- Status badges
- Sync indicators
- Count badges
4. **Typography utilities**
- Heading classes
- Text size utilities
- Weight utilities
### Fase 2: Planner Redesign ([`planner.php`](planner.php))
#### Block Header Redesign
**Voor:**
```html
<div class="block-header">
<span class="badge">Gepland</span>
<button class="btn btn-sm">Starttijd aanpassen</button>
<button class="btn btn-sm">Kopieer Blok</button>
<button class="btn btn-sm">Sync naar Talpa</button>
</div>
```
**Na:**
```html
<div class="block-header">
<div class="block-header-left">
<h6 class="block-title">SBS9 Nachtblok</h6>
<span class="badge-sync badge-sync-complete">
<i class="bi bi-check-circle-fill"></i>
Gepland
</span>
</div>
<div class="block-header-actions">
<button class="btn-icon btn-icon-sm btn-icon-secondary" title="Starttijd">
<i class="bi bi-clock"></i>
</button>
<button class="btn-icon btn-icon-sm btn-icon-info" title="Kopieer">
<i class="bi bi-files"></i>
</button>
<button class="btn-icon btn-icon-sm btn-icon-success" title="Sync">
<i class="bi bi-cloud-upload"></i>
</button>
</div>
<div class="block-header-time">
02:00 - 04:30 | <strong>24 min</strong> resterend
</div>
</div>
```
#### Table Actions Redesign
**Voor:**
```html
<div class="btn-group btn-group-sm">
<button class="btn btn-outline-secondary"><i class="bi bi-arrow-up"></i></button>
<button class="btn btn-outline-secondary"><i class="bi bi-arrow-down"></i></button>
<button class="btn btn-outline-danger"><i class="bi bi-trash"></i></button>
</div>
```
**Na:**
```html
<div class="action-buttons">
<button class="btn-icon btn-icon-xs btn-icon-secondary">
<i class="bi bi-arrow-up"></i>
</button>
<button class="btn-icon btn-icon-xs btn-icon-secondary">
<i class="bi bi-arrow-down"></i>
</button>
<button class="btn-icon btn-icon-xs btn-icon-danger">
<i class="bi bi-trash"></i>
</button>
</div>
```
#### Infomercial Sidebar Cleanup
- Compactere items
- Betere spacing
- Duidelijkere hover states
### Fase 3: Calendar View ([`calendar.php`](calendar.php))
1. **Block info cards**: Compacter design met icon-only buttons
2. **Zoom controls**: Icon-only buttons
3. **Sidebar**: Consistente styling met planner
4. **Modals**: Uniforme button styling
### Fase 4: Blocks Management ([`blocks.php`](blocks.php))
1. **Form styling**: Consistente input styling
2. **Table actions**: Icon-only buttons
3. **Status badges**: Nieuwe badge system
### Fase 5: Dashboard ([`index.php`](index.php))
1. **Stat cards**: Cleaner design met betere typografie
2. **Quick actions**: Consistente card styling
3. **Tables**: Uniforme button styling
### Fase 6: Infomercials ([`infomercials.php`](infomercials.php))
1. **List view**: Compacter met icon-only actions
2. **Upload status**: Nieuwe badge system
3. **Forms**: Consistente styling
## Visuele Voorbeelden
### Button Groepen
```
┌─────────────────────────────────────────┐
│ Block Header │
├─────────────────────────────────────────┤
│ SBS9 Nachtblok [✓ Gepland] │
│ │
│ [🕐] [📋] [☁️] 02:00-04:30 | 24 min │
└─────────────────────────────────────────┘
```
### Table Actions
```
┌──────────────────────────────────────────┐
│ Product | Duur | Acties │
├──────────────────────────────────────────┤
│ Clever Cane | 30m | [↑] [↓] [🗑️] │
│ Sani Skin | 15m | [↑] [↓] [🗑️] │
└──────────────────────────────────────────┘
```
### Status Badges
```
[✓ Gepland] - Groen (alle items gesynchroniseerd)
[⚠ Deels (2/5)] - Geel (sommige items gesynchroniseerd)
[✗ Niet Gepland] - Rood (geen items gesynchroniseerd)
[○ Leeg] - Grijs (geen items in blok)
```
## Implementatie Volgorde
1. ✅ **Design System Documentatie** (dit document)
2. **CSS Updates** ([`assets/css/custom.css`](assets/css/custom.css))
- Voeg CSS variabelen toe
- Creëer button system
- Creëer badge system
- Typography utilities
3. **Planner Redesign** ([`planner.php`](planner.php))
- Block headers
- Table actions
- Sidebar
4. **Calendar View** ([`calendar.php`](calendar.php))
5. **Blocks Management** ([`blocks.php`](blocks.php))
6. **Dashboard** ([`index.php`](index.php))
7. **Infomercials** (nog niet in codebase, maar voorbereiden)
## Mermaid Diagram: Component Hiërarchie
```mermaid
graph TD
A[Design System] --> B[Colors]
A --> C[Typography]
A --> D[Spacing]
A --> E[Components]
E --> F[Buttons]
E --> G[Badges]
E --> H[Cards]
E --> I[Tables]
F --> F1[Icon-Only]
F --> F2[Text + Icon]
F --> F3[Ghost]
G --> G1[Status]
G --> G2[Sync]
G --> G3[Count]
B --> B1[Brand Colors]
B --> B2[UI Colors]
B --> B3[Status Colors]
C --> C1[Headings]
C --> C2[Body Text]
C --> C3[Weights]
```
## Mermaid Diagram: Implementatie Flow
```mermaid
graph LR
A[CSS Variables] --> B[Button System]
B --> C[Badge System]
C --> D[Typography]
D --> E[Planner PHP]
E --> F[Calendar PHP]
F --> G[Blocks PHP]
G --> H[Index PHP]
H --> I[Testing]
I --> J[Refinement]
```
## Belangrijke Overwegingen
### Toegankelijkheid
- Voldoende contrast ratios (WCAG AA)
- Focus states voor keyboard navigatie
- Duidelijke hover states
- Geen tooltips nodig (iconen zijn duidelijk genoeg)
### Performance
- Gebruik CSS variabelen voor snelle theming
- Minimale JavaScript voor interacties
- Hergebruik van classes
### Consistentie
- Alle knoppen gebruiken hetzelfde systeem
- Alle badges gebruiken hetzelfde systeem
- Alle spacing gebruikt de spacing scale
- Alle kleuren komen uit het palet
### Responsive Design
- Buttons blijven bruikbaar op kleine schermen
- Stack buttons verticaal op mobiel indien nodig
- Behoud touch-friendly sizes (min 44x44px)
## Volgende Stappen
1. Review dit plan met het team
2. Goedkeuring voor implementatie
3. Start met CSS updates
4. Implementeer per scherm
5. Test en verfijn
6. Documenteer voor toekomstig gebruik