feat: add admin settings page with toggle switch for demo banner
All checks were successful
Staging Build / build (push) Successful in 2m16s

This commit is contained in:
DanielS
2026-06-23 23:43:22 +02:00
parent a99adb88d6
commit 1b4e998cf9
3 changed files with 76 additions and 2 deletions

View File

@@ -0,0 +1,33 @@
'use client';
import { useState, useEffect } from 'react';
import { Switch } from '@/components/ui/switch';
export default function AdminSettings() {
const [demoActive, setDemoActive] = useState(true);
useEffect(() => {
const state = localStorage.getItem('demo_banner_disabled') !== 'true';
setDemoActive(state);
}, []);
const toggleDemo = (checked: boolean) => {
setDemoActive(checked);
localStorage.setItem('demo_banner_disabled', (!checked).toString());
// Event feuern, damit andere Tabs/Komponenten sofort updaten
window.dispatchEvent(new Event('storage_demo_changed'));
};
return (
<div className="p-6 max-w-xl mx-auto text-slate-900 dark:text-white">
<h1 className="text-2xl font-bold mb-6">Admin Einstellungen</h1>
<div className="flex items-center justify-between p-4 bg-slate-100 dark:bg-white/5 rounded-xl border border-slate-200 dark:border-white/10">
<div>
<p className="font-medium text-slate-900 dark:text-white">Demo-Warnmeldungen</p>
<p className="text-xs text-slate-500 dark:text-slate-400">Schaltet gelbe Banner ein oder aus.</p>
</div>
<Switch checked={demoActive} onCheckedChange={toggleDemo} />
</div>
</div>
);
}

View File

@@ -7,7 +7,7 @@ export default function Home() {
return ( return (
<div className="flex flex-col min-h-screen bg-slate-50 text-slate-900 dark:bg-[#020617] dark:text-white"> <div className="flex flex-col min-h-screen bg-slate-50 text-slate-900 dark:bg-[#020617] dark:text-white">
{/* Demo Banner */} {/* Demo Banner */}
<div className="bg-amber-500/10 border-b border-amber-500/20 py-2 px-4 text-center text-xs text-amber-600 dark:text-amber-400 font-medium tracking-wide z-50"> <div id="demo-banner" className="bg-amber-500/10 border-b border-amber-500/20 py-2 px-4 text-center text-xs text-amber-600 dark:text-amber-400 font-medium tracking-wide z-50">
Dies ist eine **Demo-Webseite (Dummy-Shop)**. Es werden keine echten Bestellungen verarbeitet oder Zahlungen abgewickelt. Dies ist eine **Demo-Webseite (Dummy-Shop)**. Es werden keine echten Bestellungen verarbeitet oder Zahlungen abgewickelt.
</div> </div>
@@ -24,7 +24,7 @@ export default function Home() {
CASPOS Lizenz-Management-Server CASPOS Lizenz-Management-Server
</div> </div>
<h1 className="text-3xl font-bold tracking-tighter sm:text-4xl md:text-5xl lg:text-7xl/none"> <h1 className="text-3xl font-bold tracking-tighter sm:text-4xl md:text-5xl lg:text-7xl/none">
POS Software <span className="text-blue-600 dark:text-blue-500">Lizenzen & Add-ons</span> POS Software <span className="text-blue-600 dark:text-blue-500">Lizenzen & Module</span>
</h1> </h1>
<p className="mx-auto max-w-[700px] text-slate-600 dark:text-slate-400 md:text-xl mt-6"> <p className="mx-auto max-w-[700px] text-slate-600 dark:text-slate-400 md:text-xl mt-6">
Erwerben und verwalten Sie digitale Lizenzen für CASPOS Kassensysteme. Sofortige Aktivierung und automatische Bereitstellung für Ihre Kunden. Erwerben und verwalten Sie digitale Lizenzen für CASPOS Kassensysteme. Sofortige Aktivierung und automatische Bereitstellung für Ihre Kunden.

View File

@@ -0,0 +1,41 @@
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
interface SwitchProps extends React.InputHTMLAttributes<HTMLInputElement> {
checked?: boolean;
onCheckedChange?: (checked: boolean) => void;
}
const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
({ className, checked, onCheckedChange, ...props }, ref) => {
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
onCheckedChange?.(e.target.checked);
};
return (
<label className="relative inline-flex items-center cursor-pointer select-none">
<input
type="checkbox"
className="sr-only peer"
checked={checked}
onChange={handleChange}
ref={ref}
{...props}
/>
<div className={cn(
"w-11 h-6 bg-slate-200 rounded-full peer dark:bg-slate-700",
"peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500/50",
"peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white",
"after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-slate-600",
"peer-checked:bg-blue-600"
)} />
</label>
);
}
);
Switch.displayName = "Switch";
export { Switch };