0bb384e7-e18c-49c5-b7ef-fe73701ab6ab

This commit is contained in:
Z User committed 2026-10-28 17:00:06 +00:00
1 parent c4d338ee48
commit 8c34778db3
8 files changed
+121 -52

No files matched your search

+1 -1
View File
@@ -50,7 +50,7 @@ const VIEWS: { id: ViewId; label: string; icon: typeof LayoutDashboard; hint: st
{ id: 'projects', label: 'Projekte', icon: FolderKanban, hint: 'Aufgaben & Zeit' },
{ id: 'support', label: 'Support', icon: LifeBuoy, hint: 'Tickets & SLA' },
{ id: 'licenses', label: 'Lizenzen', icon: KeyRound, hint: 'Ausgestellt & Erneuerungen' },
{ id: 'agency', label: 'Bayis', icon: Users, hint: 'Reseller-Bewerbungen & Rabatte' },
{ id: 'agency', label: 'Reseller', icon: Users, hint: 'Reseller-Bewerbungen & Rabatte' },
{ id: 'instances', label: 'Instanzen', icon: Server, hint: 'Tenant-Instanzen & Provisioning' },
{ id: 'contracts', label: 'Verträge', icon: FileSignature, hint: 'Werkvertrag, AVV, NDA' },
{ id: 'expenses', label: 'Ausgaben', icon: Wallet, hint: 'Belastbar & DATEV' },
+1 -1
View File
@@ -68,7 +68,7 @@ const NAV: {
group: 'nav.operations',
items: [
{ id: 'licenses', label: 'Lizenzen', icon: KeyRound, permission: 'licenses:read' },
{ id: 'agency', label: 'Bayis', icon: Users, permission: 'admin' },
{ id: 'agency', label: 'Reseller', icon: Users, permission: 'admin' },
{ id: 'instances', label: 'Instanzen', icon: Server, permission: 'admin' },
{ id: 'contracts', label: 'Verträge', icon: FileSignature, permission: 'contracts:read' },
{ id: 'expenses', label: 'Ausgaben', icon: Wallet, permission: 'expenses:read' },
+1 -1
View File
@@ -28,7 +28,7 @@ const TITLES: Record<ViewId, { title: string; crumb: string }> = {
timesheet: { title: 'Zeiterfassung', crumb: 'Lieferung / Zeiterfassung' },
support: { title: 'Support', crumb: 'Lieferung / Tickets' },
licenses: { title: 'Lizenzen', crumb: 'Betrieb / Lizenzen' },
agency: { title: 'Bayis', crumb: 'Betrieb / Bayis' },
agency: { title: 'Reseller', crumb: 'Betrieb / Reseller' },
instances: { title: 'Instanzen', crumb: 'Betrieb / Instanzen' },
contracts: { title: 'Verträge', crumb: 'Betrieb / Verträge' },
expenses: { title: 'Ausgaben', crumb: 'Betrieb / Ausgaben' },
+17 -17
View File
@@ -135,8 +135,8 @@ export function AgencyView() {
return (
<div className="space-y-6 p-4 md:p-6">
<PageHeader
title="Bayis"
description="Reseller-Verwaltung: Bayi-Bewerbungen prüfen, Rabatt-Sätze festlegen (0–20 %) und genehmigte Bayis mit ihren Kunden einsehen."
title="Reseller"
description="Reseller-Verwaltung: Bewerbungen prüfen, Rabatt-Sätze festlegen (0–20 %) und genehmigte Reseller mit ihren Kunden einsehen."
/>
{/* Stats */}
@@ -148,7 +148,7 @@ export function AgencyView() {
hint="wartet auf Freigabe"
/>
<StatCard
label="Genehmigte Bayis"
label="Genehmigte Reseller"
value={stats.approved}
icon={Users}
hint="aktiv im System"
@@ -163,7 +163,7 @@ export function AgencyView() {
label="Ø Rabatt"
value={`${avgDiscount}%`}
icon={Percent}
hint={agencies.length ? `über ${agencies.length} Bayis` : '—'}
hint={agencies.length ? `über ${agencies.length} Reseller` : '—'}
/>
</div>
@@ -215,7 +215,7 @@ function PendingApplicationsSection({
<section className="space-y-3">
<div className="flex items-center justify-between">
<h2 className="text-sm font-semibold tracking-tight">
Bewerbende Bayis
Bewerbende Reseller
<span className="ml-2 text-xs font-normal text-muted-foreground">
{applications.length} offen
</span>
@@ -230,7 +230,7 @@ function PendingApplicationsSection({
<div className="space-y-1">
<p className="text-sm font-medium">Keine bewerbenden Anfragen</p>
<p className="max-w-sm text-xs text-muted-foreground">
Neue Bayi-Bewerbungen erscheinen hier.
Neue Reseller-Bewerbungen erscheinen hier.
</p>
</div>
</div>
@@ -393,11 +393,11 @@ function ApproveDialog({
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<CheckCircle2 className="size-4" />
Bayi-Bewerbung genehmigen
Reseller-Bewerbung genehmigen
</DialogTitle>
<DialogDescription>
<span className="font-medium text-foreground">{application.company.name}</span> wird
als Bayi freigeschaltet. Der Rabatt wird auf alle vom Bayi angelegten Kundenlizenzierungen
als Reseller freigeschaltet. Der Rabatt wird auf alle vom Reseller angelegten Kundenlizenzierungen
angewendet.
</DialogDescription>
</DialogHeader>
@@ -524,7 +524,7 @@ function RejectDialog({
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<XCircle className="size-4" />
Bayi-Bewerbung ablehnen
Reseller-Bewerbung ablehnen
</DialogTitle>
<DialogDescription>
<span className="font-medium text-foreground">{application.company.name}</span>
@@ -577,7 +577,7 @@ function ApprovedAgenciesSection({ agencies }: { agencies: ApprovedAgency[] }) {
<section className="space-y-3">
<div className="flex items-center justify-between">
<h2 className="text-sm font-semibold tracking-tight">
Genehmigte Bayis
Genehmigte Reseller
<span className="ml-2 text-xs font-normal text-muted-foreground">
{agencies.length} aktiv
</span>
@@ -590,23 +590,23 @@ function ApprovedAgenciesSection({ agencies }: { agencies: ApprovedAgency[] }) {
<Users className="size-5 text-muted-foreground" />
</div>
<div className="space-y-1">
<p className="text-sm font-medium">Noch keine Bayis genehmigt</p>
<p className="text-sm font-medium">Noch keine Reseller genehmigt</p>
<p className="max-w-sm text-xs text-muted-foreground">
Genehmigte Bayi-Bewerbungen erscheinen hier mit ihren Kunden und Lizenzen.
Genehmigte Reseller-Bewerbungen erscheinen hier mit ihren Kunden und Lizenzen.
</p>
</div>
</div>
) : (
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Bayis ({agencies.length})</CardTitle>
<CardTitle className="text-sm">Reseller ({agencies.length})</CardTitle>
</CardHeader>
<CardContent className="p-0">
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead className="border-y border-border bg-muted/40 text-left text-[11px] uppercase tracking-wide text-muted-foreground">
<tr>
<th className="px-4 py-2 font-medium">Bayi</th>
<th className="px-4 py-2 font-medium">Reseller</th>
<th className="px-4 py-2 font-medium">Rabatt</th>
<th className="px-4 py-2 font-medium text-right">Kunden</th>
<th className="px-4 py-2 font-medium text-right">Lizenzen</th>
@@ -692,7 +692,7 @@ function ClientsSheet({
{agency.name}
</SheetTitle>
<SheetDescription>
Bayi-Kundenverwaltung — {agency._count.agencyClients} Kunde(n),{' '}
Reseller-Kundenverwaltung — {agency._count.agencyClients} Kunde(n),{' '}
{agency._count.licenses} Lizenz(en).
</SheetDescription>
</SheetHeader>
@@ -702,8 +702,8 @@ function ClientsSheet({
<div className="mb-3 flex items-start gap-2 rounded-md border border-border bg-muted/40 p-3 text-[11px]">
<Mail className="mt-0.5 size-3.5 shrink-0 text-muted-foreground" />
<p className="text-muted-foreground">
Bayi kann eigene Kunden anlegen und lizenzieren. Tickets von dessen Kunden werden
an den Bayi geroutet, nicht an uns.
Reseller kann eigene Kunden anlegen und lizenzieren. Tickets von dessen Kunden werden
an den Reseller geroutet, nicht an uns.
</p>
</div>