290 lines
10 KiB
TypeScript
290 lines
10 KiB
TypeScript
import React from "react";
|
||
import { useAuth } from "~/contexts/auth-context";
|
||
import { Link, useLocation } from "react-router";
|
||
import { Button } from "~/components/ui/button";
|
||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||
import toast from "react-hot-toast";
|
||
|
||
interface DashboardLayoutProps {
|
||
children: React.ReactNode;
|
||
}
|
||
|
||
export function DashboardLayout({ children }: DashboardLayoutProps) {
|
||
const { user, logout } = useAuth();
|
||
|
||
const handleLogout = async () => {
|
||
await logout();
|
||
};
|
||
|
||
return (
|
||
<div
|
||
className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800"
|
||
dir="rtl"
|
||
>
|
||
{/* Header */}
|
||
<header className="bg-white dark:bg-slate-800 shadow-sm border-b">
|
||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||
<div className="flex justify-between items-center h-16">
|
||
{/* Logo/Title */}
|
||
<div className="flex items-center">
|
||
<div className="flex-shrink-0">
|
||
<div className="w-8 h-8 bg-green-500 rounded-lg flex items-center justify-center">
|
||
<svg
|
||
className="w-5 h-5 text-white"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Navigation Menu */}
|
||
<nav className="hidden md:flex items-center space-x-8 space-x-reverse">
|
||
<NavigationLink to="/dashboard" label="داشبورد" />
|
||
<NavigationLink to="/dashboard/projects" label="پروژهها" />
|
||
</nav>
|
||
<div className="mr-4">
|
||
<h1 className="text-xl font-bold text-gray-900 dark:text-white font-persian">
|
||
داشبورد مدیریت
|
||
</h1>
|
||
</div>
|
||
</div>
|
||
|
||
{/* User menu */}
|
||
<div className="flex items-center space-x-4 space-x-reverse">
|
||
<div className="text-sm text-gray-700 dark:text-gray-300 font-persian">
|
||
خوش آمدید، {user?.name} {user?.family}
|
||
</div>
|
||
<Button
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={handleLogout}
|
||
className="font-persian"
|
||
>
|
||
خروج
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
{/* Main content */}
|
||
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
|
||
<div className="px-4 py-6 sm:px-0">{children}</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// Navigation Link Component
|
||
interface NavigationLinkProps {
|
||
to: string;
|
||
label: string;
|
||
}
|
||
|
||
function NavigationLink({ to, label }: NavigationLinkProps) {
|
||
const location = useLocation();
|
||
const isActive = location.pathname === to;
|
||
|
||
return (
|
||
<Link
|
||
to={to}
|
||
className={`px-3 py-2 rounded-md text-sm font-medium font-persian transition-colors ${
|
||
isActive
|
||
? "bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300"
|
||
: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700"
|
||
}`}
|
||
>
|
||
{label}
|
||
</Link>
|
||
);
|
||
}
|
||
|
||
export function DashboardHome() {
|
||
const { user } = useAuth();
|
||
|
||
return (
|
||
<DashboardLayout>
|
||
<div className="space-y-6">
|
||
{/* Welcome Section */}
|
||
<div className="bg-gradient-to-r from-green-500 to-blue-600 rounded-lg p-6 text-white">
|
||
<h2 className="text-2xl font-bold mb-2 font-persian">
|
||
خوش آمدید به داشبورد مدیریت
|
||
</h2>
|
||
<p className="text-green-100 font-persian">
|
||
سیستم مدیریت یکپارچه فناوری و نوآوری
|
||
</p>
|
||
</div>
|
||
|
||
{/* Stats Cards */}
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||
<Card>
|
||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||
<CardTitle className="text-sm font-medium font-persian">
|
||
کل پروژهها
|
||
</CardTitle>
|
||
<svg
|
||
className="h-4 w-4 text-muted-foreground"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth="2"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
|
||
<circle cx="9" cy="7" r="4" />
|
||
<path d="m22 21-3-3" />
|
||
</svg>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="text-2xl font-bold">24</div>
|
||
<p className="text-xs text-muted-foreground font-persian">
|
||
+2 از ماه گذشته
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<Card>
|
||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||
<CardTitle className="text-sm font-medium font-persian">
|
||
پروژههای فعال
|
||
</CardTitle>
|
||
<svg
|
||
className="h-4 w-4 text-muted-foreground"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth="2"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<rect width="20" height="14" x="2" y="5" rx="2" />
|
||
<path d="M2 10h20" />
|
||
</svg>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="text-2xl font-bold">12</div>
|
||
<p className="text-xs text-muted-foreground font-persian">
|
||
+1 از هفته گذشته
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<Card>
|
||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||
<CardTitle className="text-sm font-medium font-persian">
|
||
پروژههای تکمیل شده
|
||
</CardTitle>
|
||
<svg
|
||
className="h-4 w-4 text-muted-foreground"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth="2"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path d="M22 12h-4l-3 9L9 3l-3 9H2" />
|
||
</svg>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="text-2xl font-bold">8</div>
|
||
<p className="text-xs text-muted-foreground font-persian">
|
||
+3 از ماه گذشته
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<Card>
|
||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||
<CardTitle className="text-sm font-medium font-persian">
|
||
درصد موفقیت
|
||
</CardTitle>
|
||
<svg
|
||
className="h-4 w-4 text-muted-foreground"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth="2"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path d="M12 2v20m8-10H4" />
|
||
</svg>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="text-2xl font-bold">85%</div>
|
||
<p className="text-xs text-muted-foreground font-persian">
|
||
+5% از ماه گذشته
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
|
||
{/* Recent Projects */}
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle className="font-persian">پروژههای اخیر</CardTitle>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="space-y-4">
|
||
{[
|
||
{
|
||
name: "سیستم مدیریت محتوا",
|
||
status: "در حال انجام",
|
||
progress: 75,
|
||
},
|
||
{ name: "اپلیکیشن موبایل", status: "تکمیل شده", progress: 100 },
|
||
{
|
||
name: "پلتفرم تجارت الکترونیک",
|
||
status: "شروع شده",
|
||
progress: 25,
|
||
},
|
||
{
|
||
name: "سیستم مدیریت مالی",
|
||
status: "در حال بررسی",
|
||
progress: 10,
|
||
},
|
||
].map((project, index) => (
|
||
<div
|
||
key={index}
|
||
className="flex items-center space-x-4 space-x-reverse"
|
||
>
|
||
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
|
||
<div className="flex-1 min-w-0">
|
||
<p className="text-sm font-medium text-gray-900 dark:text-white font-persian">
|
||
{project.name}
|
||
</p>
|
||
<p className="text-sm text-gray-500 dark:text-gray-400 font-persian">
|
||
{project.status}
|
||
</p>
|
||
</div>
|
||
<div className="flex items-center space-x-2 space-x-reverse">
|
||
<div className="w-16 bg-gray-200 rounded-full h-2 dark:bg-gray-700">
|
||
<div
|
||
className="bg-green-600 h-2 rounded-full"
|
||
style={{ width: `${project.progress}%` }}
|
||
></div>
|
||
</div>
|
||
<span className="text-sm text-gray-500 dark:text-gray-400">
|
||
{project.progress}%
|
||
</span>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</DashboardLayout>
|
||
);
|
||
}
|