mirror of
https://github.com/SamyRai/tercul-frontend.git
synced 2025-12-27 00:11:35 +00:00
Create a central hub for managing content and accessing administrative tools
Implement the dashboard layout and authentication hook with permission checks. Replit-Commit-Author: Agent Replit-Commit-Session-Id: cbacfb18-842a-4116-a907-18c0105ad8ec Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/39b5c689-6e8a-4d5a-9792-69cc81a56534/7a432344-d046-4d11-943a-89466ae66121.jpg
This commit is contained in:
parent
d67963de51
commit
1f9dc81441
153
client/src/components/layout/DashboardLayout.tsx
Normal file
153
client/src/components/layout/DashboardLayout.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
import { ReactNode } from "react";
|
||||
import { Link, useLocation } from "wouter";
|
||||
import { PageLayout } from "./PageLayout";
|
||||
import { useAuth } from "@/hooks/useAuth";
|
||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import {
|
||||
BarChart3,
|
||||
BookOpen,
|
||||
BookText,
|
||||
FileText,
|
||||
Users,
|
||||
PenSquare,
|
||||
Settings,
|
||||
LayoutDashboard,
|
||||
MessageCircle,
|
||||
BookMarked,
|
||||
Layers,
|
||||
AlertTriangle
|
||||
} from "lucide-react";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
interface DashboardLayoutProps {
|
||||
children: ReactNode;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export function DashboardLayout({ children, title = "Dashboard" }: DashboardLayoutProps) {
|
||||
const { user, isLoading, canManageUsers, canManageContent, canReviewContent, canCreateContent } = useAuth();
|
||||
const [location] = useLocation();
|
||||
|
||||
// If user doesn't have permissions, show error
|
||||
if (!isLoading && !(canCreateContent || canReviewContent || canManageContent || canManageUsers)) {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="max-w-[var(--content-width)] mx-auto px-4 md:px-6 py-8">
|
||||
<Card className="border-red-400 dark:border-red-600">
|
||||
<CardContent className="pt-6 flex flex-col items-center">
|
||||
<AlertTriangle className="h-12 w-12 text-red-500 mb-4" />
|
||||
<h1 className="text-2xl font-bold mb-2">Access Denied</h1>
|
||||
<p className="text-muted-foreground mb-4 text-center">
|
||||
You don't have permission to access this area. Please contact an administrator if you believe this is an error.
|
||||
</p>
|
||||
<Link href="/">
|
||||
<a className="text-primary hover:underline">Return to Home</a>
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
// Get dashboard items based on permissions
|
||||
const getDashboardNavItems = () => {
|
||||
const items = [
|
||||
{ href: "/dashboard", label: "Overview", icon: <LayoutDashboard className="h-4 w-4 mr-2" /> },
|
||||
];
|
||||
|
||||
if (canCreateContent) {
|
||||
items.push(
|
||||
{ href: "/dashboard/blog", label: "Blog Posts", icon: <FileText className="h-4 w-4 mr-2" /> },
|
||||
{ href: "/dashboard/works", label: "Literary Works", icon: <BookText className="h-4 w-4 mr-2" /> },
|
||||
{ href: "/dashboard/collections", label: "Collections", icon: <BookMarked className="h-4 w-4 mr-2" /> },
|
||||
{ href: "/dashboard/annotations", label: "Annotations", icon: <PenSquare className="h-4 w-4 mr-2" /> }
|
||||
);
|
||||
}
|
||||
|
||||
if (canReviewContent) {
|
||||
items.push(
|
||||
{ href: "/dashboard/analysis", label: "Analysis Results", icon: <BarChart3 className="h-4 w-4 mr-2" /> },
|
||||
{ href: "/dashboard/comments", label: "Comments", icon: <MessageCircle className="h-4 w-4 mr-2" /> }
|
||||
);
|
||||
}
|
||||
|
||||
if (canManageContent) {
|
||||
items.push(
|
||||
{ href: "/dashboard/translations", label: "Translations", icon: <BookOpen className="h-4 w-4 mr-2" /> },
|
||||
{ href: "/dashboard/authors", label: "Authors", icon: <Users className="h-4 w-4 mr-2" /> },
|
||||
{ href: "/dashboard/tags", label: "Tags", icon: <Layers className="h-4 w-4 mr-2" /> }
|
||||
);
|
||||
}
|
||||
|
||||
if (canManageUsers) {
|
||||
items.push(
|
||||
{ href: "/dashboard/users", label: "User Management", icon: <Users className="h-4 w-4 mr-2" /> },
|
||||
{ href: "/dashboard/settings", label: "Settings", icon: <Settings className="h-4 w-4 mr-2" /> }
|
||||
);
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
const navItems = getDashboardNavItems();
|
||||
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="max-w-[var(--content-width)] mx-auto px-4 md:px-6 pt-6 pb-16">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-[240px_1fr] gap-8">
|
||||
{/* Sidebar */}
|
||||
<div>
|
||||
<div className="sticky top-24">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-2xl font-bold">Editorial Dashboard</h1>
|
||||
{isLoading ? (
|
||||
<Skeleton className="h-5 w-32 mt-1" />
|
||||
) : (
|
||||
<p className="text-muted-foreground">
|
||||
Welcome, {user?.displayName || user?.username}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<ScrollArea className="h-[calc(100vh-250px)]">
|
||||
<Tabs defaultValue={location} orientation="vertical" className="w-full">
|
||||
<TabsList className="flex flex-col h-auto bg-transparent p-0 w-full">
|
||||
{navItems.map((item) => (
|
||||
<Link key={item.href} href={item.href}>
|
||||
<TabsTrigger
|
||||
value={item.href}
|
||||
className="justify-start w-full mb-1 data-[state=active]:bg-primary/10"
|
||||
>
|
||||
{item.icon}
|
||||
{item.label}
|
||||
</TabsTrigger>
|
||||
</Link>
|
||||
))}
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main content */}
|
||||
<div>
|
||||
<div className="pb-4 mb-6 border-b">
|
||||
<h2 className="text-xl font-semibold">{title}</h2>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<div className="space-y-4">
|
||||
<Skeleton className="h-8 w-full" />
|
||||
<Skeleton className="h-64 w-full" />
|
||||
</div>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
1
client/src/hooks/useAuth.ts
Normal file
1
client/src/hooks/useAuth.ts
Normal file
@ -0,0 +1 @@
|
||||
null
|
||||
1
client/src/pages/dashboard/BlogManagement.tsx
Normal file
1
client/src/pages/dashboard/BlogManagement.tsx
Normal file
@ -0,0 +1 @@
|
||||
null
|
||||
1
client/src/pages/dashboard/Dashboard.tsx
Normal file
1
client/src/pages/dashboard/Dashboard.tsx
Normal file
@ -0,0 +1 @@
|
||||
null
|
||||
Loading…
Reference in New Issue
Block a user