mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:51:18 +00:00
redsigned the settins page
This commit is contained in:
parent
a6e36e499b
commit
f1ae1d1160
7 changed files with 148 additions and 32 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import SettingsView from "@/src/modules/settings/ui/views/settings-view";
|
||||
import SettingsOverviewView from "@/src/modules/settings/ui/views/settings-overview-view";
|
||||
|
||||
export default function SettingsPage() {
|
||||
return <SettingsView />;
|
||||
return <SettingsOverviewView />;
|
||||
}
|
||||
|
|
|
|||
5
src/app/(main)/settings/public-page/page.tsx
Normal file
5
src/app/(main)/settings/public-page/page.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import SettingsPublicPageView from "@/src/modules/settings/ui/views/settings-public-page-view";
|
||||
|
||||
export default function SettingsPublicPage() {
|
||||
return <SettingsPublicPageView />;
|
||||
}
|
||||
|
|
@ -309,6 +309,25 @@ const PublicCourseCard = ({ course, business }: PublicCourseCardProps) => {
|
|||
</p>
|
||||
</div>
|
||||
|
||||
{course.trainerProfiles && course.trainerProfiles.length > 0 && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
{course.trainerProfiles.map((trainer) => {
|
||||
const fullName =
|
||||
[trainer.firstName, trainer.lastName].filter(Boolean).join(" ") || "Trainer";
|
||||
return (
|
||||
<Tooltip key={trainer.id}>
|
||||
<TooltipTrigger asChild>
|
||||
<div>
|
||||
<TrainerAvatar trainer={trainer} size="sm" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">{fullName}</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h2 className="text-xl font-semibold text-gray-900">{course.name}</h2>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
|
|
@ -333,25 +352,6 @@ const PublicCourseCard = ({ course, business }: PublicCourseCardProps) => {
|
|||
/>
|
||||
</div>
|
||||
|
||||
{course.trainerProfiles && course.trainerProfiles.length > 0 && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
{course.trainerProfiles.map((trainer) => {
|
||||
const fullName =
|
||||
[trainer.firstName, trainer.lastName].filter(Boolean).join(" ") || "Trainer";
|
||||
return (
|
||||
<Tooltip key={trainer.id}>
|
||||
<TooltipTrigger asChild>
|
||||
<div>
|
||||
<TrainerAvatar trainer={trainer} size="sm" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">{fullName}</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isFull ? (
|
||||
<Button disabled variant="outline" className="w-full">
|
||||
Ausgebucht
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ const menuTitles: Record<string, string> = {
|
|||
"/employee": "Mitarbeiter Übersicht",
|
||||
"/employee/create": "Mitarbeiter erstellen",
|
||||
"/settings": "Einstellungen",
|
||||
"/settings/public-page": "Einstellungen",
|
||||
};
|
||||
|
||||
const dynamicRoutes: Array<{
|
||||
|
|
|
|||
38
src/modules/settings/ui/components/SettingsMenuItem.tsx
Normal file
38
src/modules/settings/ui/components/SettingsMenuItem.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import Link from "next/link";
|
||||
import { LucideIcon } from "lucide-react";
|
||||
import { ChevronRight } from "lucide-react";
|
||||
|
||||
interface SettingsMenuItemProps {
|
||||
name: string;
|
||||
description?: string;
|
||||
icon: LucideIcon;
|
||||
href: string;
|
||||
}
|
||||
|
||||
const SettingsMenuItem: React.FC<SettingsMenuItemProps> = ({
|
||||
name,
|
||||
description,
|
||||
icon: Icon,
|
||||
href,
|
||||
}) => {
|
||||
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"
|
||||
>
|
||||
<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>
|
||||
<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>}
|
||||
</div>
|
||||
<ChevronRight
|
||||
size={16}
|
||||
className="text-gray-400 group-hover:text-gray-600 transition-colors shrink-0"
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsMenuItem;
|
||||
62
src/modules/settings/ui/views/settings-overview-view.tsx
Normal file
62
src/modules/settings/ui/views/settings-overview-view.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { requireAuthWithData, isManager } from "@/src/lib/auth/getUser";
|
||||
import SettingsMenuItem from "../components/SettingsMenuItem";
|
||||
import { LucideIcon, PanelTop, Settings, User } from "lucide-react";
|
||||
|
||||
type SettingsMenuItem = {
|
||||
icon: LucideIcon;
|
||||
name: string;
|
||||
href: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
const settingsMenuTitles: SettingsMenuItem[] = [
|
||||
{
|
||||
icon: User,
|
||||
name: "Persöhnliche Einstellungen",
|
||||
href: "/settings/personal",
|
||||
description: "Verwalte deine persöhnlichen Daten",
|
||||
},
|
||||
{
|
||||
icon: PanelTop,
|
||||
name: "Öffentliche Seite",
|
||||
href: "/settings/public-page",
|
||||
description: "Verwalte deine öffentliche Kursseite",
|
||||
},
|
||||
];
|
||||
|
||||
const SettingsOverviewView = async () => {
|
||||
const userData = await requireAuthWithData();
|
||||
|
||||
if (!isManager(userData)) {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold mb-1">Einstellungen</h1>
|
||||
<p className="text-gray-500 text-sm">Keine weiteren Einstellungen verfügbar.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
{settingsMenuTitles.map((item) => (
|
||||
<SettingsMenuItem
|
||||
key={item.href}
|
||||
name={item.name}
|
||||
description={item.description}
|
||||
icon={item.icon}
|
||||
href={item.href}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsOverviewView;
|
||||
|
|
@ -1,15 +1,17 @@
|
|||
import Link from "next/link";
|
||||
import { ChevronLeft } from "lucide-react";
|
||||
import { requireAuthWithData, isManager } from "@/src/lib/auth/getUser";
|
||||
import { prisma } from "@/src/lib/prisma";
|
||||
import BusinessPublicToggle from "../components/BusinessPublicToggle";
|
||||
|
||||
const SettingsView = async () => {
|
||||
const SettingsPublicPageView = async () => {
|
||||
const userData = await requireAuthWithData();
|
||||
|
||||
if (!isManager(userData)) {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<h1 className="text-3xl font-bold mb-2">Einstellungen</h1>
|
||||
<p className="text-gray-500">Keine weiteren Einstellungen verfügbar.</p>
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold mb-1">Öffentliche Seite</h1>
|
||||
<p className="text-gray-500 text-sm">Keine Berechtigung.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -21,17 +23,25 @@ const SettingsView = async () => {
|
|||
});
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">Einstellungen</h1>
|
||||
<p className="text-gray-500 mt-1">Verwalte die öffentlichen Seiten deiner Businesses</p>
|
||||
<Link
|
||||
href="/settings"
|
||||
className="inline-flex items-center gap-1 text-sm text-gray-500 hover:text-gray-900 transition-colors mb-3"
|
||||
>
|
||||
<ChevronLeft size={15} className="mb-1" />
|
||||
Einstellungen
|
||||
</Link>
|
||||
<h1 className="text-2xl font-bold">Öffentliche Seite</h1>
|
||||
<p className="text-sm text-gray-500 mt-1">
|
||||
Steuere welche Kursseiten öffentlich sichtbar sind
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{businesses.length === 0 ? (
|
||||
<p className="text-gray-400">Noch kein Business angelegt.</p>
|
||||
<p className="text-gray-400 text-sm">Noch kein Business angelegt.</p>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-semibold">Öffentliche Seiten</h2>
|
||||
<div className="space-y-3">
|
||||
{businesses.map((business) => (
|
||||
<BusinessPublicToggle
|
||||
key={business.id}
|
||||
|
|
@ -47,4 +57,4 @@ const SettingsView = async () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default SettingsView;
|
||||
export default SettingsPublicPageView;
|
||||
Loading…
Add table
Add a link
Reference in a new issue