mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:51:18 +00:00
Merge pull request #112 from Since-3/feature/added-customer-data-to-customer-page
added real customer data to the customer page in the admin dashbaord
This commit is contained in:
commit
9231d9651c
5 changed files with 86 additions and 80 deletions
|
|
@ -1,9 +1,15 @@
|
|||
import { requireManager } from "@/src/lib/auth/getUser";
|
||||
import { getKunden } from "@/src/modules/kunden/actions/kunden-actions";
|
||||
import KundenView from "@/src/modules/kunden/ui/views/kunden-view";
|
||||
|
||||
const KundenPage = async () => {
|
||||
await requireManager();
|
||||
return <KundenView />;
|
||||
const result = await getKunden();
|
||||
if (!result.success) {
|
||||
throw new Error(result.error);
|
||||
}
|
||||
|
||||
return <KundenView initialKunden={result.kunden} />;
|
||||
};
|
||||
|
||||
export default KundenPage;
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ export async function requireGuest() {
|
|||
* Redirects to /dashboard if user is not a manager.
|
||||
* Redirects to /login if not authenticated.
|
||||
*/
|
||||
export async function requireManager() {
|
||||
export async function requireManager(): Promise<ManagerData> {
|
||||
const userData = await requireAuthWithData();
|
||||
|
||||
if (!isManager(userData)) {
|
||||
|
|
@ -264,7 +264,7 @@ export async function requireManager() {
|
|||
redirect("/dashboard");
|
||||
}
|
||||
|
||||
return userData;
|
||||
return userData as ManagerData;
|
||||
}
|
||||
|
||||
// Helper function to check if user is a manager
|
||||
|
|
|
|||
68
src/modules/kunden/actions/kunden-actions.ts
Normal file
68
src/modules/kunden/actions/kunden-actions.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
"use server";
|
||||
|
||||
import { prisma } from "@/src/lib/prisma";
|
||||
import { requireManager } from "@/src/lib/auth/getUser";
|
||||
|
||||
export type KundeRow = {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
telefon: string;
|
||||
status: "Bezahlt" | "Storniert" | "Ausstehend";
|
||||
};
|
||||
|
||||
function mapPaymentStatus(paymentStatus: string): KundeRow["status"] {
|
||||
if (paymentStatus === "paid") return "Bezahlt";
|
||||
if (paymentStatus === "refunded") return "Storniert";
|
||||
return "Ausstehend";
|
||||
}
|
||||
|
||||
export async function getKunden(): Promise<
|
||||
{ success: true; kunden: KundeRow[] } | { success: false; error: string }
|
||||
> {
|
||||
const manager = await requireManager();
|
||||
const businessIds = manager.businesses.map((b) => b.id);
|
||||
|
||||
try {
|
||||
if (businessIds.length === 0) {
|
||||
return { success: true, kunden: [] };
|
||||
}
|
||||
|
||||
// Alle Bookings für Kurse die zu diesem Manager gehören, gruppiert nach User
|
||||
const bookings = await prisma.courseBooking.findMany({
|
||||
where: {
|
||||
course: { businessId: { in: businessIds } },
|
||||
},
|
||||
select: {
|
||||
paymentStatus: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
tel: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: "desc" },
|
||||
});
|
||||
|
||||
// Pro User nur den letzten (relevantesten) Status behalten
|
||||
const seen = new Map<string, KundeRow>();
|
||||
for (const booking of bookings) {
|
||||
if (!seen.has(booking.user.id)) {
|
||||
seen.set(booking.user.id, {
|
||||
id: booking.user.id,
|
||||
name: booking.user.name ?? booking.user.email,
|
||||
email: booking.user.email,
|
||||
telefon: booking.user.tel ?? "–",
|
||||
status: mapPaymentStatus(booking.paymentStatus),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return { success: true, kunden: Array.from(seen.values()) };
|
||||
} catch {
|
||||
return { success: false, error: "Kunden konnten nicht geladen werden." };
|
||||
}
|
||||
}
|
||||
|
|
@ -14,9 +14,9 @@ import { useRouter } from "next/navigation";
|
|||
import type { Kunde } from "../views/kunden-view";
|
||||
|
||||
const STATUS_STYLES: Record<Kunde["status"], string> = {
|
||||
Teilgenommen: "bg-green-100 text-green-700",
|
||||
Bezahlt: "bg-green-100 text-green-700",
|
||||
Storniert: "bg-red-100 text-red-600",
|
||||
Bezahlt: "bg-blue-100 text-blue-700",
|
||||
Ausstehend: "bg-yellow-100 text-yellow-700",
|
||||
};
|
||||
|
||||
interface KundenTableProps {
|
||||
|
|
|
|||
|
|
@ -4,86 +4,18 @@ import { useState } from "react";
|
|||
import { Input } from "@/src/components/ui/input";
|
||||
import { Search } from "lucide-react";
|
||||
import KundenTable from "../components/kunden-table";
|
||||
import type { KundeRow } from "../../actions/kunden-actions";
|
||||
|
||||
const DUMMY_KUNDEN = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Stern Thireau",
|
||||
email: "sthireau0@prilog.org",
|
||||
telefon: "+49 160 14256244",
|
||||
status: "Teilgenommen" as const,
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Ford Mckibbin",
|
||||
email: "fmckibbin1@slate.com",
|
||||
telefon: "+49 160 84256328",
|
||||
status: "Storniert" as const,
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Foss Roglieri",
|
||||
email: "froglieri2@xing.com",
|
||||
telefon: "+49 160 78745913",
|
||||
status: "Teilgenommen" as const,
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
name: "Maurits Elgey",
|
||||
email: "melgey3@blogger.com",
|
||||
telefon: "+49 160 55834625",
|
||||
status: "Teilgenommen" as const,
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
name: "Gun Kaasmann",
|
||||
email: "gkaasmann4@economist.com",
|
||||
telefon: "+49 160 32679584",
|
||||
status: "Teilgenommen" as const,
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
name: "Edmund McCrae",
|
||||
email: "emccrae5@woothemes.com",
|
||||
telefon: "+49 160 69321457",
|
||||
status: "Bezahlt" as const,
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
name: "Samuel Totman",
|
||||
email: "stotman6@wisc.edu",
|
||||
telefon: "+49 160 96851428",
|
||||
status: "Teilgenommen" as const,
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
name: "Patsy Cuardall",
|
||||
email: "pcuardall70@barnesandnoble.com",
|
||||
telefon: "+49 160 38591426",
|
||||
status: "Bezahlt" as const,
|
||||
},
|
||||
{
|
||||
id: "9",
|
||||
name: "Barnaby Carl",
|
||||
email: "bcarl8@alexa.com",
|
||||
telefon: "+49 160 77958426",
|
||||
status: "Storniert" as const,
|
||||
},
|
||||
{
|
||||
id: "10",
|
||||
name: "Lena Bergmann",
|
||||
email: "lbergmann9@spiegel.de",
|
||||
telefon: "+49 160 12345678",
|
||||
status: "Bezahlt" as const,
|
||||
},
|
||||
];
|
||||
export type Kunde = KundeRow;
|
||||
|
||||
export type Kunde = (typeof DUMMY_KUNDEN)[number];
|
||||
interface KundenViewProps {
|
||||
initialKunden: KundeRow[];
|
||||
}
|
||||
|
||||
const KundenView = () => {
|
||||
const KundenView = ({ initialKunden }: KundenViewProps) => {
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
const filtered = DUMMY_KUNDEN.filter(
|
||||
const filtered = initialKunden.filter(
|
||||
(k) =>
|
||||
k.name.toLowerCase().includes(search.toLowerCase()) ||
|
||||
k.email.toLowerCase().includes(search.toLowerCase()) ||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue