feat: make orders list clearer and put navbar globally except for admin area
All checks were successful
Staging Build / build (push) Successful in 2m14s
All checks were successful
Staging Build / build (push) Successful in 2m14s
This commit is contained in:
@@ -1,19 +1,13 @@
|
||||
import { createClient } from '@/lib/supabase/server'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { FileText, Download, ExternalLink } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { OrdersTable } from '@/components/admin/orders-table'
|
||||
import { Suspense } from 'react'
|
||||
|
||||
export default async function AdminOrdersPage() {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="p-8 space-y-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold tracking-tight text-white">Bestellungen & Rechnungen</h1>
|
||||
<h1 className="text-3xl font-bold tracking-tight text-gradient">Bestellungen & Rechnungen</h1>
|
||||
<p className="text-slate-400">Verwalten Sie alle Kundenbestellungen und greifen Sie auf generierte PDFs zu.</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -34,75 +28,8 @@ async function OrdersData() {
|
||||
.order('created_at', { ascending: false })
|
||||
|
||||
if (error) {
|
||||
return <div>Fehler beim Laden der Bestellungen: {error.message}</div>
|
||||
return <div className="text-red-500">Fehler beim Laden der Bestellungen: {error.message}</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className="glass-dark border-white/10">
|
||||
<CardContent className="p-0">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="border-white/10 hover:bg-transparent">
|
||||
<TableHead className="w-[140px] text-slate-200">Bestellnr.</TableHead>
|
||||
<TableHead className="text-slate-200">Datum</TableHead>
|
||||
<TableHead className="text-slate-200">Kunde</TableHead>
|
||||
<TableHead className="text-slate-200">Betrag</TableHead>
|
||||
<TableHead className="text-slate-200">Status</TableHead>
|
||||
<TableHead className="text-right text-slate-200">Rechnung</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{orders?.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} className="text-center py-12 text-muted-foreground">
|
||||
Noch keine Bestellungen vorhanden.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
orders?.map((order) => (
|
||||
<TableRow key={order.id} className="border-white/5 hover:bg-white/5">
|
||||
<TableCell className="font-mono text-xs text-primary font-semibold">
|
||||
{order.order_number ?? order.id.slice(0, 8) + '...'}
|
||||
</TableCell>
|
||||
<TableCell className="text-slate-300">
|
||||
{new Date(order.created_at).toLocaleDateString('de-DE')}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="font-medium text-white">{order.customer_data?.company_name || 'Privatkunde'}</div>
|
||||
<div className="text-xs text-slate-400">{order.customer_data?.first_name} {order.customer_data?.last_name}</div>
|
||||
</TableCell>
|
||||
<TableCell className="font-semibold text-white">
|
||||
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(order.total_price)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant={order.status === 'completed' ? 'default' : 'secondary'} className="capitalize">
|
||||
{order.status}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
{order.pdf_url ? (
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button variant="outline" size="sm" asChild className="h-8 border-white/10 hover:bg-primary/20">
|
||||
<a href={order.pdf_url} target="_blank" rel="noopener noreferrer">
|
||||
<ExternalLink className="w-4 h-4 mr-2" /> Ansehen
|
||||
</a>
|
||||
</Button>
|
||||
<Button variant="secondary" size="sm" asChild className="h-8">
|
||||
<a href={order.pdf_url} download>
|
||||
<Download className="w-4 h-4" />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-xs text-muted-foreground italic">Kein PDF</span>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
return <OrdersTable initialOrders={orders || []} />
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import type { Metadata } from "next";
|
||||
import { Geist } from "next/font/google";
|
||||
import { ThemeProvider } from "next-themes";
|
||||
import { InactivityTracker } from "@/components/inactivity-tracker";
|
||||
import { HeaderWrapper } from "@/components/HeaderWrapper";
|
||||
import { Navbar } from "@/components/Navbar";
|
||||
import "./globals.css";
|
||||
|
||||
const defaultUrl = process.env.VERCEL_URL
|
||||
@@ -35,7 +37,9 @@ export default function RootLayout({
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<InactivityTracker />
|
||||
{children}
|
||||
<HeaderWrapper navbar={<Navbar />}>
|
||||
{children}
|
||||
</HeaderWrapper>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,106 +5,97 @@ import { Navbar } from '@/components/Navbar'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="flex flex-col min-h-screen bg-slate-50 text-slate-900 dark:bg-[#020617] dark:text-white">
|
||||
{/* Demo Banner */}
|
||||
<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.
|
||||
</div>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className="flex-1">
|
||||
{/* Hero Section: Zielgerichtet auf Lizenzen */}
|
||||
<section className="w-full py-12 md:py-24 lg:py-32 xl:py-48 px-4 overflow-hidden relative">
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-[1000px] h-[600px] bg-blue-600/10 blur-[120px] rounded-full -z-10 opacity-30" />
|
||||
<div className="container mx-auto">
|
||||
<div className="flex flex-col items-center space-y-4 text-center">
|
||||
<div className="space-y-2">
|
||||
<div className="inline-block rounded-full bg-blue-500/10 px-3 py-1 text-sm text-blue-600 dark:text-blue-400 font-medium border border-blue-500/20 mb-4">
|
||||
CASPOS Lizenz-Management-Server
|
||||
</div>
|
||||
<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 & Module</span>
|
||||
</h1>
|
||||
<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.
|
||||
</p>
|
||||
<>
|
||||
{/* Hero Section: Zielgerichtet auf Lizenzen */}
|
||||
<section className="w-full py-12 md:py-24 lg:py-32 xl:py-48 px-4 overflow-hidden relative">
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-[1000px] h-[600px] bg-blue-600/10 blur-[120px] rounded-full -z-10 opacity-30" />
|
||||
<div className="container mx-auto">
|
||||
<div className="flex flex-col items-center space-y-4 text-center">
|
||||
<div className="space-y-2">
|
||||
<div className="inline-block rounded-full bg-blue-500/10 px-3 py-1 text-sm text-blue-600 dark:text-blue-400 font-medium border border-blue-500/20 mb-4">
|
||||
CASPOS Lizenz-Management-Server
|
||||
</div>
|
||||
<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 & Module</span>
|
||||
</h1>
|
||||
<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.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* High-Contrast Buttons (Light/Dark Ready) */}
|
||||
<div className="space-x-4 mt-8">
|
||||
<Link href="/order">
|
||||
<Button size="lg" className="h-12 px-8 text-lg font-bold transition-all hover:scale-105 bg-slate-900 text-white hover:bg-slate-800 border border-slate-200 dark:bg-white dark:text-black dark:hover:bg-slate-200 dark:border-none">
|
||||
Lizenz bestellen <ArrowRight className="ml-2 h-5 w-5" />
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href="https://caspos.de/kontakt/" target="_blank" rel="noopener noreferrer">
|
||||
<Button size="lg" variant="outline" className="h-12 px-8 text-lg font-semibold bg-transparent border-slate-400 text-slate-900 hover:bg-slate-100 dark:border-white/40 dark:text-white dark:hover:bg-white/10">
|
||||
Fragen? Kontaktieren Sie uns
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
{/* High-Contrast Buttons (Light/Dark Ready) */}
|
||||
<div className="space-x-4 mt-8">
|
||||
<Link href="/order">
|
||||
<Button size="lg" className="h-12 px-8 text-lg font-bold transition-all hover:scale-105 bg-slate-900 text-white hover:bg-slate-800 border border-slate-200 dark:bg-white dark:text-black dark:hover:bg-slate-200 dark:border-none">
|
||||
Lizenz bestellen <ArrowRight className="ml-2 h-5 w-5" />
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href="https://caspos.de/kontakt/" target="_blank" rel="noopener noreferrer">
|
||||
<Button size="lg" variant="outline" className="h-12 px-8 text-lg font-semibold bg-transparent border-slate-400 text-slate-900 hover:bg-slate-100 dark:border-white/40 dark:text-white dark:hover:bg-white/10">
|
||||
Fragen? Kontaktieren Sie uns
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Grid: Aufgeteilt nach echten POS-Modulen */}
|
||||
<section className="w-full py-12 md:py-24 lg:py-32 border-t border-slate-200 dark:border-white/5 bg-slate-50 dark:bg-white/[0.02]">
|
||||
<div className="container mx-auto px-4 md:px-6">
|
||||
<div className="grid gap-12 lg:grid-cols-3">
|
||||
{/* Feature Grid: Aufgeteilt nach echten POS-Modulen */}
|
||||
<section className="w-full py-12 md:py-24 lg:py-32 border-t border-slate-200 dark:border-white/5 bg-slate-50 dark:bg-white/[0.02]">
|
||||
<div className="container mx-auto px-4 md:px-6">
|
||||
<div className="grid gap-12 lg:grid-cols-3">
|
||||
|
||||
{/* Modul 1 */}
|
||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
||||
<Cpu className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Handel & ERP</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400">Erweiterungen für Handelskassen, Bestandsführung und vollwertige Warenwirtschaftssysteme (ERP).</p>
|
||||
{/* Modul 1 */}
|
||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
||||
<Cpu className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Handel & ERP</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400">Erweiterungen für Handelskassen, Bestandsführung und vollwertige Warenwirtschaftssysteme (ERP).</p>
|
||||
</div>
|
||||
|
||||
{/* Modul 2 */}
|
||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
||||
<Zap className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Gastronomie</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400">Lizenzen für mobiles Bestellen (Orderman), digitale Küchen-Monitore und interaktive Abhol-Boards.</p>
|
||||
{/* Modul 2 */}
|
||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
||||
<Zap className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Gastronomie</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400">Lizenzen für mobiles Bestellen (Orderman), digitale Küchen-Monitore und interaktive Abhol-Boards.</p>
|
||||
</div>
|
||||
|
||||
{/* Modul 3 */}
|
||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
||||
<Shield className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Hybride Systeme</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400">Das beste aus beiden Welten. Handel mit Gastronomie und umgekehrt. </p>
|
||||
{/* Modul 3 */}
|
||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
||||
<Shield className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">Hybride Systeme</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400">Das beste aus beiden Welten. Handel mit Gastronomie und umgekehrt. </p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Kurze Info-Sektion für Partner / Händler */}
|
||||
<section className="w-full py-12 md:py-24 border-t border-slate-200 dark:border-white/5">
|
||||
<div className="container mx-auto px-4 max-w-4xl text-center">
|
||||
<h2 className="text-2xl font-bold tracking-tight sm:text-3xl mb-6">Wie funktioniert die Bereitstellung?</h2>
|
||||
<div className="grid gap-6 sm:grid-cols-3 text-left">
|
||||
<div className="flex gap-2 items-start">
|
||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>1. Lizenz wählen:</strong> Gewünschtes POS-Modul im Shop selektieren.</p>
|
||||
</div>
|
||||
<div className="flex gap-2 items-start">
|
||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>2. Kunde zuweisen:</strong> Lizenz direkt einem Kunden-Account zuordnen.</p>
|
||||
</div>
|
||||
<div className="flex gap-2 items-start">
|
||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>3. Live gehen:</strong> Lizenz-Key (`.key`) wird sofort serverseitig aktiviert.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Kurze Info-Sektion für Partner / Händler */}
|
||||
<section className="w-full py-12 md:py-24 border-t border-slate-200 dark:border-white/5">
|
||||
<div className="container mx-auto px-4 max-w-4xl text-center">
|
||||
<h2 className="text-2xl font-bold tracking-tight sm:text-3xl mb-6">Wie funktioniert die Bereitstellung?</h2>
|
||||
<div className="grid gap-6 sm:grid-cols-3 text-left">
|
||||
<div className="flex gap-2 items-start">
|
||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>1. Lizenz wählen:</strong> Gewünschtes POS-Modul im Shop selektieren.</p>
|
||||
</div>
|
||||
<div className="flex gap-2 items-start">
|
||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>2. Kunde zuweisen:</strong> Lizenz direkt einem Kunden-Account zuordnen.</p>
|
||||
</div>
|
||||
<div className="flex gap-2 items-start">
|
||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>3. Live gehen:</strong> Lizenz-Key (`.key`) wird sofort serverseitig aktiviert.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="flex flex-col gap-2 sm:flex-row py-6 w-full shrink-0 items-center px-4 md:px-6 border-t border-slate-200 dark:border-white/5 bg-slate-50 dark:bg-[#020617]">
|
||||
@@ -114,6 +105,6 @@ export default function Home() {
|
||||
<Link className="text-xs hover:underline underline-offset-4 text-slate-500" href="https://caspos.de/datenschutz/" target="_blank" rel="noopener noreferrer">Datenschutz</Link>
|
||||
</nav>
|
||||
</footer>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user