WIP: dark mode Modale

This commit is contained in:
ISA
2025-09-08 15:33:26 +02:00
parent fefff9419d
commit af21b180f1
23 changed files with 209 additions and 95 deletions

View File

@@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
NEXT_PUBLIC_EXPORT_STATIC=false NEXT_PUBLIC_EXPORT_STATIC=false
NEXT_PUBLIC_USE_CGI=false NEXT_PUBLIC_USE_CGI=false
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.877 NEXT_PUBLIC_APP_VERSION=1.6.878
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)

View File

@@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL
NEXT_PUBLIC_EXPORT_STATIC=true NEXT_PUBLIC_EXPORT_STATIC=true
NEXT_PUBLIC_USE_CGI=true NEXT_PUBLIC_USE_CGI=true
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.877 NEXT_PUBLIC_APP_VERSION=1.6.878
NEXT_PUBLIC_CPL_MODE=production NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,8 @@
## [1.6.878] 2025-09-08
- WIP: dark mode Berichte
---
## [1.6.877] 2025-09-08 ## [1.6.877] 2025-09-08
- WIP: dark mode Modale - WIP: dark mode Modale

View File

@@ -62,7 +62,9 @@ function Footer() {
icon="material-symbols:factory-outline" icon="material-symbols:factory-outline"
className="text-xl text-accent" className="text-xl text-accent"
/> />
<p className="text-sm text-fg-muted">Littwin Systemtechnik GmbH & Co. KG</p> <p className="text-sm text-fg-muted">
Littwin Systemtechnik GmbH & Co. KG
</p>
</div> </div>
<div className="flex flex-row space-x-2 items-center"> <div className="flex flex-row space-x-2 items-center">
<Icon icon="charm:phone" className="text-xl text-accent" /> <Icon icon="charm:phone" className="text-xl text-accent" />
@@ -70,14 +72,21 @@ function Footer() {
</div> </div>
<div className="flex flex-row space-x-2 items-center"> <div className="flex flex-row space-x-2 items-center">
<Icon icon="mdi:email-outline" className="text-xl text-accent" /> <Icon icon="mdi:email-outline" className="text-xl text-accent" />
<p className="text-sm text-fg-muted">kontakt@littwin-systemtechnik.de</p> <p className="text-sm text-fg-muted">
kontakt@littwin-systemtechnik.de
</p>
</div> </div>
<div <div
className="flex flex-row space-x-2 cursor-pointer items-center group" className="flex flex-row space-x-2 cursor-pointer items-center group"
onClick={() => setShowSlider(true)} onClick={() => setShowSlider(true)}
> >
<Icon icon="bi:book" className="text-xl text-accent group-hover:brightness-110 transition" /> <Icon
<p className="text-sm text-fg-muted group-hover:text-[var(--color-fg)] transition">Handbücher</p> icon="bi:book"
className="text-xl text-accent group-hover:brightness-110 transition"
/>
<p className="text-sm text-fg-muted group-hover:text-[var(--color-fg)] transition">
Handbücher
</p>
</div> </div>
</div> </div>
@@ -88,7 +97,9 @@ function Footer() {
}`} }`}
> >
<div className="p-4 flex justify-between items-center border-b border-base"> <div className="p-4 flex justify-between items-center border-b border-base">
<h3 className="text-base font-semibold text-[var(--color-fg)]">PDF Handbücher</h3> <h3 className="text-base font-semibold text-[var(--color-fg)]">
PDF Handbücher
</h3>
<button <button
className="text-[var(--color-muted)] hover:text-[var(--color-fg)] transition" className="text-[var(--color-muted)] hover:text-[var(--color-fg)] transition"
onClick={() => setShowSlider(false)} onClick={() => setShowSlider(false)}

View File

@@ -195,9 +195,15 @@ function Header() {
title={isDark ? "Light Mode" : "Dark Mode"} title={isDark ? "Light Mode" : "Dark Mode"}
> >
{isDark ? ( {isDark ? (
<Icon icon="mdi:weather-night" className="text-xl text-yellow-300" /> <Icon
icon="mdi:weather-night"
className="text-xl text-yellow-300"
/>
) : ( ) : (
<Icon icon="mdi:white-balance-sunny" className="text-xl text-yellow-500" /> <Icon
icon="mdi:white-balance-sunny"
className="text-xl text-yellow-500"
/>
)} )}
</button> </button>
</div> </div>

View File

@@ -49,12 +49,8 @@ const NetworkInfo: React.FC = () => {
priority priority
/> />
<div> <div>
<p className="text-xs text-[var(--color-fg-muted)]"> <p className="text-xs text-[var(--color-fg-muted)]">IP-Adresse</p>
IP-Adresse <p className="text-sm font-medium text-[var(--color-fg)]">{ip}</p>
</p>
<p className="text-sm font-medium text-[var(--color-fg)]">
{ip}
</p>
</div> </div>
</div> </div>
@@ -68,9 +64,7 @@ const NetworkInfo: React.FC = () => {
priority priority
/> />
<div> <div>
<p className="text-xs text-[var(--color-fg-muted)]"> <p className="text-xs text-[var(--color-fg-muted)]">Subnet-Maske</p>
Subnet-Maske
</p>
<p className="text-sm font-medium text-[var(--color-fg)]"> <p className="text-sm font-medium text-[var(--color-fg)]">
{subnet} {subnet}
</p> </p>

View File

@@ -17,11 +17,21 @@ export default function MeldungenTabelle({
<table className="min-w-full border border-base table-surface text-fg"> <table className="min-w-full border border-base table-surface text-fg">
<thead className="text-left sticky top-0 z-10 bg-surface-alt/90 backdrop-blur supports-[backdrop-filter]:bg-surface-alt/70"> <thead className="text-left sticky top-0 z-10 bg-surface-alt/90 backdrop-blur supports-[backdrop-filter]:bg-surface-alt/70">
<tr> <tr>
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">Prio</th> <th className="p-2 border border-base bg-surface-alt text-fg font-medium">
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">Zeitstempel</th> Prio
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">Quelle</th> </th>
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">Meldung</th> <th className="p-2 border border-base bg-surface-alt text-fg font-medium">
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">Status</th> Zeitstempel
</th>
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">
Quelle
</th>
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">
Meldung
</th>
<th className="p-2 border border-base bg-surface-alt text-fg font-medium">
Status
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -46,9 +56,15 @@ export default function MeldungenTabelle({
second: "2-digit", second: "2-digit",
})} })}
</td> </td>
<td className="border border-base p-2 bg-surface text-fg">{msg.i}</td> <td className="border border-base p-2 bg-surface text-fg">
<td className="border border-base p-2 bg-surface text-fg">{msg.m}</td> {msg.i}
<td className="border border-base p-2 bg-surface text-fg">{msg.v}</td> </td>
<td className="border border-base p-2 bg-surface text-fg">
{msg.m}
</td>
<td className="border border-base p-2 bg-surface text-fg">
{msg.v}
</td>
</tr> </tr>
))} ))}
</tbody> </tbody>

View File

@@ -63,7 +63,8 @@ const GeneralSettings: React.FC = () => {
setMac1(systemSettings.mac1 || ""); setMac1(systemSettings.mac1 || "");
}, [systemSettings]); }, [systemSettings]);
const inputCls = "border border-base focus:border-accent rounded h-8 p-1 w-full text-xs bg-[var(--color-surface)] text-[var(--color-fg)] placeholder-[var(--color-muted)] transition-colors duration-150 focus:outline-none"; const inputCls =
"border border-base focus:border-accent rounded h-8 p-1 w-full text-xs bg-[var(--color-surface)] text-[var(--color-fg)] placeholder-[var(--color-muted)] transition-colors duration-150 focus:outline-none";
return ( return (
<div className="p-6 md:p-3 bg-[var(--color-surface-alt)] max-w-5xl mr-auto overflow-y-auto max-h-[calc(100vh-200px)] text-[var(--color-fg)]"> <div className="p-6 md:p-3 bg-[var(--color-surface-alt)] max-w-5xl mr-auto overflow-y-auto max-h-[calc(100vh-200px)] text-[var(--color-fg)]">
@@ -86,12 +87,7 @@ const GeneralSettings: React.FC = () => {
<label className="block text-xs md:text-sm font-medium"> <label className="block text-xs md:text-sm font-medium">
MAC Adresse 1: MAC Adresse 1:
</label> </label>
<input <input type="text" className={inputCls} value={mac1} disabled />
type="text"
className={inputCls}
value={mac1}
disabled
/>
</div> </div>
{/* Systemzeit */} {/* Systemzeit */}
<div className="col-span-2"> <div className="col-span-2">

View File

@@ -50,9 +50,11 @@ const Navigation: React.FC<NavigationProps> = ({ className }) => {
prefetch={false} prefetch={false}
onClick={() => setActiveLink(item.path)} onClick={() => setActiveLink(item.path)}
className={`block px-4 py-2 mb-4 font-semibold whitespace-nowrap transition duration-200 rounded-r-full pr-6 relative text-[1rem] sm:text-[1rem] md:text-[1rem] lg:text-[1rem] xl:text-sm 2xl:text-lg className={`block px-4 py-2 mb-4 font-semibold whitespace-nowrap transition duration-200 rounded-r-full pr-6 relative text-[1rem] sm:text-[1rem] md:text-[1rem] lg:text-[1rem] xl:text-sm 2xl:text-lg
${activeLink.startsWith(item.path) ${
? 'bg-[var(--color-accent)] text-white shadow-sm xl:mr-4 xl:w-full' activeLink.startsWith(item.path)
: 'text-[var(--color-fg-muted)] hover:text-[var(--color-fg)] hover:bg-[var(--color-surface-alt)]/80 dark:hover:bg-[var(--color-surface-alt)]/40'} ? "bg-[var(--color-accent)] text-white shadow-sm xl:mr-4 xl:w-full"
: "text-[var(--color-fg-muted)] hover:text-[var(--color-fg)] hover:bg-[var(--color-surface-alt)]/80 dark:hover:bg-[var(--color-surface-alt)]/40"
}
`} `}
> >
{item.name} {item.name}

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.877", "version": "1.6.878",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.877", "version": "1.6.878",
"dependencies": { "dependencies": {
"@fontsource/roboto": "^5.1.0", "@fontsource/roboto": "^5.1.0",
"@headlessui/react": "^2.2.4", "@headlessui/react": "^2.2.4",

View File

@@ -1,6 +1,6 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.877", "version": "1.6.878",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev -p 3000", "dev": "next dev -p 3000",

View File

@@ -58,11 +58,13 @@ body {
/* Smooth theme transitions (respect reduced motion) */ /* Smooth theme transitions (respect reduced motion) */
@media (prefers-reduced-motion: no-preference) { @media (prefers-reduced-motion: no-preference) {
html, body { html,
transition: background-color .25s ease, color .25s ease; body {
transition: background-color 0.25s ease, color 0.25s ease;
} }
.theme-transition { .theme-transition {
transition: background-color .25s ease, color .25s ease, border-color .25s ease, box-shadow .25s ease; transition: background-color 0.25s ease, color 0.25s ease,
border-color 0.25s ease, box-shadow 0.25s ease;
} }
} }
@@ -71,18 +73,42 @@ body {
text-wrap: balance; text-wrap: balance;
} }
/* Semantic shortcut utilities */ /* Semantic shortcut utilities */
.bg-background { background-color: var(--color-background); } .bg-background {
.bg-surface { background-color: var(--color-surface); } background-color: var(--color-background);
.bg-surface-alt { background-color: var(--color-surface-alt); } }
.text-fg { color: var(--color-fg); } .bg-surface {
.text-fg-muted { color: var(--color-fg-muted); } background-color: var(--color-surface);
.text-muted { color: var(--color-muted); } }
.border-base { border-color: var(--color-border); } .bg-surface-alt {
.ring-accent { --tw-ring-color: var(--color-ring); } background-color: var(--color-surface-alt);
.bg-accent { background-color: var(--color-accent); } }
.bg-accent-soft { background-color: var(--color-accent-soft); } .text-fg {
.text-success { color: var(--color-success); } color: var(--color-fg);
.text-danger { color: var(--color-danger); } }
.text-fg-muted {
color: var(--color-fg-muted);
}
.text-muted {
color: var(--color-muted);
}
.border-base {
border-color: var(--color-border);
}
.ring-accent {
--tw-ring-color: var(--color-ring);
}
.bg-accent {
background-color: var(--color-accent);
}
.bg-accent-soft {
background-color: var(--color-accent-soft);
}
.text-success {
color: var(--color-success);
}
.text-danger {
color: var(--color-danger);
}
/* Component abstractions (no @apply to avoid processing issues in global layer) */ /* Component abstractions (no @apply to avoid processing issues in global layer) */
.card { .card {
@@ -97,7 +123,8 @@ body {
color: var(--color-fg); color: var(--color-fg);
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
border-radius: 0.375rem; border-radius: 0.375rem;
box-shadow: 0 4px 10px -2px rgba(0,0,0,0.25), 0 2px 4px rgba(0,0,0,0.15); box-shadow: 0 4px 10px -2px rgba(0, 0, 0, 0.25),
0 2px 4px rgba(0, 0, 0, 0.15);
} }
.table-surface { .table-surface {
background: var(--color-surface); background: var(--color-surface);
@@ -113,7 +140,11 @@ body {
border-bottom: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border);
} }
.table-row-hover:hover { .table-row-hover:hover {
background-color: color-mix(in srgb,var(--color-surface-alt) 85%,transparent); background-color: color-mix(
in srgb,
var(--color-surface-alt) 85%,
transparent
);
} }
.btn-accent { .btn-accent {
background: var(--color-accent); background: var(--color-accent);
@@ -122,20 +153,65 @@ body {
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
font-weight: 500; font-weight: 500;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
transition: filter .2s ease, box-shadow .2s ease; transition: filter 0.2s ease, box-shadow 0.2s ease;
}
.btn-accent:hover {
filter: brightness(1.1);
}
.btn-accent:focus {
outline: 2px solid var(--color-ring);
outline-offset: 2px;
} }
.btn-accent:hover { filter: brightness(1.1); }
.btn-accent:focus { outline: 2px solid var(--color-ring); outline-offset: 2px; }
/* Button Variants */ /* Button Variants */
.btn-primary { @media (prefers-reduced-motion: no-preference) { transition: background-color .2s ease, filter .2s ease; } background: var(--color-accent); color:#fff; border-radius:.375rem; font-weight:500; padding:.5rem 1rem; } .btn-primary {
.btn-primary:hover { filter:brightness(1.1); } @media (prefers-reduced-motion: no-preference) {
.btn-primary:focus { outline:2px solid var(--color-ring); outline-offset:2px; } transition: background-color 0.2s ease, filter 0.2s ease;
.btn-muted { background: var(--color-muted); color: var(--color-fg); border-radius:.375rem; font-weight:500; padding:.5rem 1rem; } }
.btn-muted:hover { background: var(--color-fg); color: var(--color-background); } background: var(--color-accent);
.btn-outline { background: transparent; color: var(--color-fg); border:1px solid var(--color-border); border-radius:.375rem; font-weight:500; padding:.5rem 1rem; } color: #fff;
.btn-outline:hover { background: var(--color-surface-alt); } border-radius: 0.375rem;
.btn-danger { background: var(--color-danger); color:#fff; border-radius:.375rem; font-weight:500; padding:.5rem 1rem; } font-weight: 500;
.btn-danger:hover { filter:brightness(1.1); } padding: 0.5rem 1rem;
}
.btn-primary:hover {
filter: brightness(1.1);
}
.btn-primary:focus {
outline: 2px solid var(--color-ring);
outline-offset: 2px;
}
.btn-muted {
background: var(--color-muted);
color: var(--color-fg);
border-radius: 0.375rem;
font-weight: 500;
padding: 0.5rem 1rem;
}
.btn-muted:hover {
background: var(--color-fg);
color: var(--color-background);
}
.btn-outline {
background: transparent;
color: var(--color-fg);
border: 1px solid var(--color-border);
border-radius: 0.375rem;
font-weight: 500;
padding: 0.5rem 1rem;
}
.btn-outline:hover {
background: var(--color-surface-alt);
}
.btn-danger {
background: var(--color-danger);
color: #fff;
border-radius: 0.375rem;
font-weight: 500;
padding: 0.5rem 1rem;
}
.btn-danger:hover {
filter: brightness(1.1);
}
.input-base { .input-base {
background: var(--color-input-bg); background: var(--color-input-bg);
color: var(--color-fg); color: var(--color-fg);
@@ -149,22 +225,30 @@ body {
outline: 1px solid var(--color-ring); outline: 1px solid var(--color-ring);
outline-offset: 2px; outline-offset: 2px;
} }
.input-base:disabled { opacity: 0.6; cursor: not-allowed; } .input-base:disabled {
opacity: 0.6;
cursor: not-allowed;
}
} }
/* Form elements use tokens */ /* Form elements use tokens */
input, select, textarea { input,
select,
textarea {
background-color: var(--color-input-bg) !important; background-color: var(--color-input-bg) !important;
color: var(--color-fg) !important; color: var(--color-fg) !important;
border: 1px solid var(--color-input-border); border: 1px solid var(--color-input-border);
} }
input::placeholder, textarea::placeholder { input::placeholder,
textarea::placeholder {
color: var(--color-muted); color: var(--color-muted);
opacity: 1; /* ensure consistent visibility */ opacity: 1; /* ensure consistent visibility */
} }
input:focus, select:focus, textarea:focus { input:focus,
select:focus,
textarea:focus {
outline: 2px solid var(--color-ring); outline: 2px solid var(--color-ring);
outline-offset: 2px; outline-offset: 2px;
border-color: var(--color-ring); border-color: var(--color-ring);