MBO-Tech-IT-Webseite/app/kunden/dashboard/page.tsx

167 lines
6.0 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { createBrowserSupabaseClient } from "@/lib/supabase";
import type { User } from "@supabase/supabase-js";
interface Anfrage {
id: string;
created_at: string;
status: string;
name: string;
betreff: string;
nachricht: string | null;
email: string;
}
function formatDatum(iso: string) {
return new Date(iso).toLocaleDateString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
}
function StatusBadge({ status }: { status: string }) {
const styles: Record<string, string> = {
offen: "bg-amber-500/10 text-amber-400 border border-amber-500/20",
in_bearbeitung: "bg-blue-500/10 text-blue-400 border border-blue-500/20",
abgeschlossen: "bg-green-500/10 text-green-400 border border-green-500/20",
};
const labels: Record<string, string> = {
offen: "Offen",
in_bearbeitung: "In Bearbeitung",
abgeschlossen: "Abgeschlossen",
};
return (
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${styles[status] ?? styles.offen}`}>
{labels[status] ?? status}
</span>
);
}
export default function KundenDashboardPage() {
const router = useRouter();
const [user, setUser] = useState<User | null>(null);
const [anfragen, setAnfragen] = useState<Anfrage[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const supabase = createBrowserSupabaseClient();
async function init() {
const {
data: { session },
} = await supabase.auth.getSession();
if (!session) {
router.push("/kunden/login");
return;
}
setUser(session.user);
const res = await fetch("/api/kunden/anfragen", {
headers: { Authorization: `Bearer ${session.access_token}` },
});
if (res.ok) {
const json = await res.json();
setAnfragen(json.anfragen ?? []);
}
setLoading(false);
}
init();
}, [router]);
async function handleLogout() {
const supabase = createBrowserSupabaseClient();
await supabase.auth.signOut();
router.push("/kunden/login");
}
if (loading) {
return (
<div className="min-h-screen bg-[#111925] flex items-center justify-center">
<p className="text-slate-500">Wird geladen</p>
</div>
);
}
return (
<div className="min-h-screen bg-[#111925]">
<div className="max-w-4xl mx-auto px-4 py-10">
<div className="flex items-start justify-between gap-4 mb-8">
<div>
<h1 className="text-2xl font-bold text-white tracking-tight">Mein Bereich</h1>
<p className="text-slate-500 text-sm mt-1">{user?.email}</p>
</div>
<button
onClick={handleLogout}
className="inline-flex items-center gap-1.5 text-sm border border-gray-700 rounded-lg px-3 py-1.5 text-slate-400 hover:text-white hover:border-gray-600 transition-colors"
>
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
Abmelden
</button>
</div>
<hr className="border-gray-800 mb-8" />
<div>
<div className="flex items-center justify-between mb-5">
<h2 className="font-semibold text-white">Meine IT-Anfragen</h2>
<Link
href="/#contact"
className="text-sm text-orange-400 hover:text-orange-300 font-medium transition-colors"
>
+ Neue Anfrage
</Link>
</div>
{anfragen.length === 0 ? (
<div className="border border-dashed border-gray-700 py-12 text-center rounded-xl">
<svg className="w-8 h-8 text-slate-600 mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<p className="text-slate-500 mb-1">Noch keine Anfragen vorhanden</p>
<p className="text-sm text-slate-600 mb-4">
Kontaktieren Sie uns über das Kontaktformular auf der Startseite.
</p>
<Link
href="/#contact"
className="inline-flex items-center justify-center bg-orange-500 hover:bg-orange-600 text-white rounded-xl font-semibold px-5 py-2 text-sm transition-colors"
>
Zum Kontaktformular
</Link>
</div>
) : (
<div className="space-y-4">
{anfragen.map((anfrage) => (
<div key={anfrage.id} className="bg-[#18212f] border border-gray-800 rounded-xl overflow-hidden">
<div className="flex items-center justify-between gap-3 px-5 py-4 border-b border-gray-800">
<div className="flex items-center gap-3">
<StatusBadge status={anfrage.status} />
<span className="text-xs text-slate-500">{formatDatum(anfrage.created_at)}</span>
</div>
<span className="text-xs text-slate-600 font-mono hidden sm:block">
#{anfrage.id.slice(0, 8)}
</span>
</div>
<div className="px-5 py-4">
<p className="font-semibold text-white text-sm mb-1">{anfrage.betreff}</p>
{anfrage.nachricht && (
<p className="text-sm text-slate-400 line-clamp-2">{anfrage.nachricht}</p>
)}
</div>
</div>
))}
</div>
)}
</div>
</div>
</div>
);
}