fix more design things

This commit is contained in:
Rajpreet0 2026-06-09 19:17:07 +02:00
parent 02b28a570b
commit 2f93618eb3
7 changed files with 78 additions and 62 deletions

View file

@ -9,8 +9,14 @@ interface Props {
const Layout = ({ children }: Props) => {
return (
<SidebarProvider>
{/* Mesh-Gradient Background */}
<div className="fixed inset-0 -z-10 bg-[oklch(0.97_0_0)]">
<div className="absolute inset-0 bg-[radial-gradient(ellipse_80%_60%_at_-10%_-10%,oklch(0.82_0.06_240/_0.5)_0%,transparent_60%)]" />
<div className="absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_110%_110%,oklch(0.88_0.09_85/_0.45)_0%,transparent_55%)]" />
<div className="absolute inset-0 bg-[radial-gradient(ellipse_50%_40%_at_50%_120%,oklch(0.84_0.05_260/_0.3)_0%,transparent_60%)]" />
</div>
<DashboardSidebarWrapper />
<main className="flex flex-col h-screen w-full bg-muted px-4">
<main className="flex flex-col h-screen w-full px-4">
<DashboardNavbar />
{children}
</main>

View file

@ -129,27 +129,29 @@ const CourseListItem: React.FC<CourseListItemProps> = ({
</div>
{/* Course Name */}
<h2 className="text-xl font-semibold text-gray-900">{courseName}</h2>
<h2 className="text-xl font-black text-gray-900 leading-tight">{courseName}</h2>
<div className="flex items-center justify-between w-full">
{/* Participant Number */}
<span className={isFull ? "text-red-600 font-semibold" : "text-gray-800"}>
<span
className={`text-sm ${isFull ? "text-red-500 font-semibold" : "text-gray-400 font-light"}`}
>
{currentParticipants}/{maxParticipants} Teilnehmer
</span>
{/* Price */}
<h2 className="text-lg font-semibold">
<span className="text-lg font-black text-gray-900">
{price.toLocaleString("de-DE", {
style: "currency",
currency: "EUR",
})}
</h2>
</span>
</div>
{/* Participant Bar */}
<div className="w-full h-2 bg-white/40 rounded-full overflow-hidden">
<div className="w-full h-1.5 bg-white/40 rounded-full overflow-hidden">
<div
className={`h-full ${isFull ? "bg-red-500" : "bg-blue"}`}
className={`h-full rounded-full ${isFull ? "bg-red-400" : "bg-blue"}`}
style={{
width: `${maxParticipants > 0 ? (currentParticipants / maxParticipants) * 100 : 0}%`,
}}
@ -163,10 +165,10 @@ const CourseListItem: React.FC<CourseListItemProps> = ({
{currentLevel.label}
</span>
{/* Room */}
<p className="text-gray-500">{room}</p>
<p className="text-xs text-gray-400 font-light">{room}</p>
</div>
<hr />
<div className="h-px bg-white/50" />
<div className="flex items-center justify-between w-full">
{/* Status */}

View file

@ -564,19 +564,17 @@ const CourseListView = ({ canCreate, canEdit, canDelete }: CourseListViewProps)
)}
{filteredCourses.length === 0 ? (
<div className="text-center py-12 border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl">
<p className="text-xl text-gray-600">
{courses.length === 0
? "Sie haben noch keine Kurse erstellt"
: "Keine Kurse gefunden mit den ausgewählten Filtern"}
<div className="text-center py-16 border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl">
<p className="text-3xl font-black text-gray-800 mb-2">
{courses.length === 0 ? "Noch keine Kurse" : "Keine Treffer"}
</p>
<p className="text-gray-500 mt-2">
<p className="text-gray-400 font-light text-sm">
{courses.length === 0
? "Erstellen Sie Ihren ersten Kurs!"
: "Ändern Sie die Filter oder setzen Sie sie zurück"}
? "Erstelle deinen ersten Kurs und starte durch."
: "Andere Filter ausprobieren oder zurücksetzen."}
</p>
{courses.length === 0 && canCreate && (
<Button onClick={() => router.push("/courses/create")} className="mt-4">
<Button onClick={() => router.push("/courses/create")} className="mt-6">
Kurs anlegen
</Button>
)}
@ -589,9 +587,12 @@ const CourseListView = ({ canCreate, canEdit, canDelete }: CourseListViewProps)
return (
<div key={dateKey}>
<h2 className="text-2xl font-bold text-gray-800 mb-4">
{formatDate(firstCourse.date)}
</h2>
<div className="flex items-center gap-3 mb-4">
<h2 className="text-xs font-semibold tracking-widest text-gray-400 uppercase">
{formatDate(firstCourse.date)}
</h2>
<div className="flex-1 h-px bg-white/50" />
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{coursesForDate.map((course) => (
<CourseListItem

View file

@ -56,8 +56,8 @@ const DashboardNavbar = () => {
const pageTitle = getPageTitle(pathname);
return (
<div>
<div className="flex gap-x-4 items-center py-4 bg-muted">
<div className="sticky top-0 z-10 -mx-4 px-4 mb-8 bg-white/55 backdrop-blur-xl supports-backdrop-filter:bg-white/45 border-b border-white/30 shadow-sm">
<div className="flex gap-x-4 items-center py-4">
<Button className="size-9 cursor-pointer" variant="outline" onClick={toggleSidebar}>
{state === "collapsed" || isMobile ? (
<PanelLeftIcon className="size-4" />
@ -70,7 +70,6 @@ const DashboardNavbar = () => {
<h1 className="text-xl font-semibold mt-1">{pageTitle}</h1>
</div>
<hr className="mb-8" />
</div>
);
};

View file

@ -12,38 +12,44 @@ const DashboardView = async () => {
return (
<div className="space-y-6">
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h1 className="text-3xl font-bold text-gray-900 mb-4">Willkommen zurück!</h1>
<p className="text-gray-600">Schön, dich wiederzusehen, {displayName}</p>
{isManager(userData) && (
<span className="inline-block mt-2 px-3 py-1 bg-blue-100 text-blue-800 text-sm font-medium rounded-full">
Manager
</span>
)}
{isEmployee(userData) && (
<span className="inline-block mt-2 px-3 py-1 bg-green-100 text-green-800 text-sm font-medium rounded-full">
Mitarbeiter
</span>
)}
<div className="border border-white/60 bg-white/60 backdrop-blur-xl rounded-2xl shadow-sm p-8 relative overflow-hidden">
<div className="absolute inset-0 bg-[radial-gradient(ellipse_80%_80%_at_100%_0%,oklch(0.88_0.09_85/_0.25)_0%,transparent_70%)] pointer-events-none" />
<p className="text-xs font-semibold tracking-widest text-gray-400 uppercase mb-2">
Dashboard
</p>
<h1 className="text-4xl font-black text-gray-900 mb-1">Willkommen zurück!</h1>
<p className="text-gray-500 font-light">{displayName}</p>
<div className="mt-4 flex gap-2">
{isManager(userData) && (
<span className="inline-flex items-center px-3 py-1 bg-blue/10 text-blue text-xs font-semibold rounded-full border border-blue/10">
Manager
</span>
)}
{isEmployee(userData) && (
<span className="inline-flex items-center px-3 py-1 bg-green-500/10 text-green-700 text-xs font-semibold rounded-full border border-green-500/10">
Mitarbeiter
</span>
)}
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-lg font-semibold mb-2">Profil</h2>
<p className="text-gray-600 text-sm">Verwalte deine persönlichen Daten</p>
<h2 className="text-base font-semibold text-gray-900 mb-1">Profil</h2>
<p className="text-gray-400 text-sm font-light">Verwalte deine persönlichen Daten</p>
</div>
{isManager(userData) ? (
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-lg font-semibold mb-2">Meine Businesses</h2>
<p className="text-gray-600 text-sm">
<h2 className="text-base font-semibold text-gray-900 mb-1">Meine Businesses</h2>
<p className="text-gray-400 text-sm font-light">
{userData.businesses.length}{" "}
{userData.businesses.length === 1 ? "Business" : "Businesses"}
</p>
</div>
) : isEmployee(userData) ? (
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-lg font-semibold mb-2">Meine Berechtigungen</h2>
<h2 className="text-base font-semibold text-gray-900 mb-1">Meine Berechtigungen</h2>
{(() => {
const p = userData.permissions;
const RESOURCE_LABELS: Record<string, string> = {
@ -80,20 +86,20 @@ const DashboardView = async () => {
</div>
) : (
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-lg font-semibold mb-2">Trainings</h2>
<p className="text-gray-600 text-sm">Deine gebuchten Trainingseinheiten</p>
<h2 className="text-base font-semibold text-gray-900 mb-1">Trainings</h2>
<p className="text-gray-400 text-sm font-light">Deine gebuchten Trainingseinheiten</p>
</div>
)}
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-lg font-semibold mb-2">Einstellungen</h2>
<p className="text-gray-600 text-sm">Passe deine Einstellungen an</p>
<h2 className="text-base font-semibold text-gray-900 mb-1">Einstellungen</h2>
<p className="text-gray-400 text-sm font-light">Passe deine Einstellungen an</p>
</div>
</div>
{isUser(userData) && (
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-xl font-semibold mb-4">Benutzerdaten</h2>
<h2 className="text-base font-semibold text-gray-900 mb-4">Benutzerdaten</h2>
<dl className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<dt className="text-sm font-medium text-gray-500">Name</dt>
@ -133,7 +139,7 @@ const DashboardView = async () => {
{isManager(userData) && (
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-xl font-semibold mb-4">Manager-Daten</h2>
<h2 className="text-base font-semibold text-gray-900 mb-4">Manager-Daten</h2>
<dl className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<dt className="text-sm font-medium text-gray-500">Vorname</dt>
@ -165,10 +171,10 @@ const DashboardView = async () => {
{isManager(userData) && userData.businesses.length > 0 && (
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-xl font-semibold mb-4">Meine Businesses</h2>
<h2 className="text-base font-semibold text-gray-900 mb-4">Meine Businesses</h2>
<div className="space-y-4">
{userData.businesses.map((business) => (
<div key={business.id} className="border-l-4 border-blue-500 pl-4 py-2">
<div key={business.id} className="border-l-2 border-white/60 pl-4 py-1">
<h3 className="text-lg font-semibold text-gray-900">{business.name}</h3>
<p className="text-sm text-gray-600 mt-1">{business.address}</p>
<p className="text-sm text-gray-600">{business.email}</p>
@ -180,7 +186,7 @@ const DashboardView = async () => {
{isEmployee(userData) && (
<div className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-2xl shadow-sm p-6">
<h2 className="text-xl font-semibold mb-4">Mitarbeiter-Daten</h2>
<h2 className="text-base font-semibold text-gray-900 mb-4">Mitarbeiter-Daten</h2>
<dl className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<dt className="text-sm font-medium text-gray-500">Vorname</dt>

View file

@ -18,18 +18,20 @@ const SettingsMenuItem: React.FC<SettingsMenuItemProps> = ({
return (
<Link
href={href}
className="border border-gray-200 rounded-xl p-5 bg-white flex items-center gap-4 hover:border-gray-300 hover:shadow-sm transition-all group"
className="border border-white/60 bg-white/55 backdrop-blur-xl rounded-xl p-5 flex items-center gap-4 hover:bg-white/75 hover:shadow-sm transition-all group"
>
<div className="bg-gray-100 rounded-lg p-2.5 group-hover:bg-gray-200 transition-colors">
<Icon size={18} className="text-gray-700" />
<div className="bg-white/60 rounded-xl p-2.5 group-hover:bg-white/80 transition-colors border border-white/50">
<Icon size={18} className="text-blue" />
</div>
<div className="flex-1 min-w-0">
<p className="font-medium text-gray-900 text-sm">{name}</p>
{description && <p className="text-xs text-gray-500 mt-0.5 truncate">{description}</p>}
<p className="font-semibold text-gray-900 text-sm">{name}</p>
{description && (
<p className="text-xs text-gray-400 font-light mt-0.5 truncate">{description}</p>
)}
</div>
<ChevronRight
size={16}
className="text-gray-400 group-hover:text-gray-600 transition-colors shrink-0"
className="text-gray-300 group-hover:text-gray-500 group-hover:translate-x-0.5 transition-all shrink-0"
/>
</Link>
);

View file

@ -7,7 +7,6 @@ import {
LucideIcon,
Megaphone,
PanelTop,
Settings,
TicketPercent,
TicketX,
User,
@ -86,10 +85,11 @@ const SettingsOverviewView = async () => {
return (
<div className="space-y-4">
<div>
<h1 className="text-2xl flex gap-2 font-bold">
<Settings /> Allgemeine Einstellungen
</h1>
<p className="text-sm text-gray-500 mt-1">Verwalte deine App-Einstellungen</p>
<p className="text-xs font-semibold tracking-widest text-gray-400 uppercase mb-1">
Konfiguration
</p>
<h1 className="text-3xl font-black text-gray-900">Einstellungen</h1>
<p className="text-sm text-gray-400 font-light mt-1">Verwalte deine App-Einstellungen</p>
</div>
<div className="flex flex-col gap-4">
{settingsMenuTitles.map((item) => (