refactor: remove yearly billing interval, keep only one_time and monthly

This commit is contained in:
DanielS
2026-05-01 02:35:22 +02:00
parent cc10352d72
commit f947798bf6
18 changed files with 390 additions and 46 deletions

View File

@@ -37,10 +37,6 @@ async function CategoryDataWrapper() {
async function CreateCategoryAction() {
return (
<CategoryDialog>
<button className="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50">
<Plus className="mr-2 h-4 w-4" /> Kategorie hinzufügen
</button>
</CategoryDialog>
<CategoryDialog />
)
}

View File

@@ -36,6 +36,10 @@ export default function AdminLayout({
<ShoppingCart className="w-5 h-5" />
Bestellungen
</Link>
<Link href="/admin/users" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Users className="w-5 h-5" />
Benutzer
</Link>
<Link href="/admin/settings" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Settings className="w-5 h-5" />
Einstellungen

View File

@@ -13,8 +13,8 @@ export default async function AdminOrdersPage() {
<div className="space-y-6">
<div className="flex justify-between items-center">
<div>
<h1 className="text-3xl font-bold tracking-tight">Bestellungen & Rechnungen</h1>
<p className="text-muted-foreground">Verwalten Sie alle Kundenbestellungen und greifen Sie auf generierte PDFs zu.</p>
<h1 className="text-3xl font-bold tracking-tight text-white">Bestellungen & Rechnungen</h1>
<p className="text-slate-400">Verwalten Sie alle Kundenbestellungen und greifen Sie auf generierte PDFs zu.</p>
</div>
</div>
@@ -43,12 +43,12 @@ async function OrdersData() {
<Table>
<TableHeader>
<TableRow className="border-white/10 hover:bg-transparent">
<TableHead className="w-[100px]">ID</TableHead>
<TableHead>Datum</TableHead>
<TableHead>Kunde</TableHead>
<TableHead>Betrag</TableHead>
<TableHead>Status</TableHead>
<TableHead className="text-right">Rechnung</TableHead>
<TableHead className="w-[100px] text-slate-200">ID</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>
@@ -61,17 +61,17 @@ async function OrdersData() {
) : (
orders?.map((order) => (
<TableRow key={order.id} className="border-white/5 hover:bg-white/5">
<TableCell className="font-mono text-xs text-muted-foreground">
<TableCell className="font-mono text-xs text-slate-500">
{order.id.slice(0, 8)}...
</TableCell>
<TableCell>
<TableCell className="text-slate-300">
{new Date(order.created_at).toLocaleDateString('de-DE')}
</TableCell>
<TableCell>
<div className="font-medium">{order.customer_data?.company_name || 'Privatkunde'}</div>
<div className="text-xs text-muted-foreground">{order.customer_data?.first_name} {order.customer_data?.last_name}</div>
<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">
<TableCell className="font-semibold text-white">
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(order.total_price)}
</TableCell>
<TableCell>

View File

@@ -9,42 +9,42 @@ export default function AdminDashboard() {
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<Card className="glass-dark border-white/5">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Umsatz gesamt</CardTitle>
<CardTitle className="text-sm font-medium text-slate-300">Umsatz gesamt</CardTitle>
<TrendingUp className="h-4 w-4 text-primary" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">12,234.56</div>
<p className="text-xs text-muted-foreground">+20.1% zum Vormonat</p>
<div className="text-2xl font-bold text-white">12,234.56</div>
<p className="text-xs text-slate-400">+20.1% zum Vormonat</p>
</CardContent>
</Card>
<Card className="glass-dark border-white/5">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Bestellungen</CardTitle>
<CardTitle className="text-sm font-medium text-slate-300">Bestellungen</CardTitle>
<ShoppingCart className="h-4 w-4 text-primary" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">+573</div>
<p className="text-xs text-muted-foreground">+12% zur Vorwoche</p>
<div className="text-2xl font-bold text-white">+573</div>
<p className="text-xs text-slate-400">+12% zur Vorwoche</p>
</CardContent>
</Card>
<Card className="glass-dark border-white/5">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Produkte</CardTitle>
<CardTitle className="text-sm font-medium text-slate-300">Produkte</CardTitle>
<Package className="h-4 w-4 text-primary" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">12</div>
<p className="text-xs text-muted-foreground">+2 neue Module</p>
<div className="text-2xl font-bold text-white">12</div>
<p className="text-xs text-slate-400">+2 neue Module</p>
</CardContent>
</Card>
<Card className="glass-dark border-white/5">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Kunden</CardTitle>
<CardTitle className="text-sm font-medium text-slate-300">Kunden</CardTitle>
<Users className="h-4 w-4 text-primary" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">2,450</div>
<p className="text-xs text-muted-foreground">+180 heute</p>
<div className="text-2xl font-bold text-white">2,450</div>
<p className="text-xs text-slate-400">+180 heute</p>
</CardContent>
</Card>
</div>
@@ -55,8 +55,8 @@ export default function AdminDashboard() {
<CardTitle>Übersicht</CardTitle>
</CardHeader>
<CardContent className="pl-2">
<div className="h-[200px] flex items-center justify-center text-muted-foreground">
[Chart Platzhalter]
<div className="h-[200px] flex items-center justify-center text-slate-400 italic">
[Umsatz-Chart wird geladen...]
</div>
</CardContent>
</Card>
@@ -72,10 +72,10 @@ export default function AdminDashboard() {
JD
</div>
<div className="flex-1 space-y-1">
<p className="text-sm font-medium">John Doe</p>
<p className="text-xs text-muted-foreground">john.doe@example.com</p>
<p className="text-sm font-medium text-white">John Doe</p>
<p className="text-xs text-slate-400">john.doe@example.com</p>
</div>
<div className="font-medium">+450.00</div>
<div className="font-medium text-white">+450.00</div>
</div>
))}
</div>

View File

@@ -14,7 +14,7 @@ export default async function AdminProductsPage() {
<Package className="w-8 h-8 text-primary" />
Produkte & Module
</h2>
<p className="text-muted-foreground">
<p className="text-slate-300">
Verwalte deine Hauptprodukte und deren zubuchbare Module.
</p>
</div>

View File

@@ -0,0 +1,42 @@
import { getUsers } from '@/lib/actions/users'
import { UserList } from '@/components/admin/user-list'
import { UserDialog } from '@/components/admin/user-dialog'
import { Users } from 'lucide-react'
import { Suspense } from 'react'
export default async function AdminUsersPage() {
return (
<div className="flex-1 space-y-8 p-8 pt-6">
<div className="flex items-center justify-between space-y-2">
<div>
<h2 className="text-3xl font-bold tracking-tight text-gradient flex items-center gap-3">
<Users className="w-8 h-8 text-primary" />
Benutzerverwaltung
</h2>
<p className="text-slate-400">
Verwalten Sie Benutzerkonten, Berechtigungen und Sicherheit.
</p>
</div>
<div className="flex items-center space-x-2">
<UserDialog />
</div>
</div>
<Suspense fallback={<div className="h-40 w-full animate-pulse bg-white/5 rounded-xl" />}>
<UserDataWrapper />
</Suspense>
</div>
)
}
async function UserDataWrapper() {
try {
const users = await getUsers()
return <UserList initialUsers={users} />
} catch (error) {
return (
<div className="p-8 border border-destructive/50 bg-destructive/10 rounded-xl text-destructive text-center">
Fehler beim Laden der Benutzer. Stellen Sie sicher, dass der SERVICE_ROLE_KEY korrekt konfiguriert ist.
</div>
)
}
}