561 lines
26 KiB
TypeScript
561 lines
26 KiB
TypeScript
import React, { useState, useEffect } from "react";
|
||
import { DashboardLayout } from "./layout";
|
||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||
import { Progress } from "~/components/ui/progress";
|
||
import { Badge } from "~/components/ui/badge";
|
||
import { Button } from "~/components/ui/button";
|
||
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, LineChart, Line } from 'recharts';
|
||
import apiService from "~/lib/api";
|
||
import toast from "react-hot-toast";
|
||
import { Calendar, TrendingUp, TrendingDown, Target, Lightbulb, DollarSign, Minus, CheckCircle, BookOpen } from "lucide-react";
|
||
import { Tabs, TabsList, TabsTrigger, TabsContent } from "~/components/ui/tabs";
|
||
import { CustomBarChart } from "~/components/ui/custom-bar-chart";
|
||
import {
|
||
Label,
|
||
PolarGrid,
|
||
PolarRadiusAxis,
|
||
RadialBar,
|
||
RadialBarChart,
|
||
} from "recharts"
|
||
import { ChartContainer } from "~/components/ui/chart"
|
||
import { formatNumber } from "~/lib/utils";
|
||
|
||
|
||
export function DashboardHome() {
|
||
const [dashboardData, setDashboardData] = useState<any | null>(null);
|
||
const [loading, setLoading] = useState(true);
|
||
const [error, setError] = useState<string | null>(null);
|
||
|
||
useEffect(() => {
|
||
fetchDashboardData();
|
||
}, []);
|
||
|
||
const fetchDashboardData = async () => {
|
||
try {
|
||
setLoading(true);
|
||
setError(null);
|
||
|
||
// First authenticate if needed
|
||
const token = localStorage.getItem('auth_token');
|
||
if (!token) {
|
||
await apiService.login('inogen_admin', '123456');
|
||
}
|
||
|
||
// Fetch top cards data
|
||
const topCardsResponse = await apiService.call({
|
||
main_page_first_function: {}
|
||
});
|
||
|
||
// Fetch left section data
|
||
const leftCardsResponse = await apiService.call({
|
||
main_page_second_function: {}
|
||
});
|
||
|
||
const topCardsResponseData = JSON.parse(topCardsResponse?.data);
|
||
const leftCardsResponseData = JSON.parse(leftCardsResponse?.data);
|
||
|
||
console.log('API Responses:', { topCardsResponseData, leftCardsResponseData });
|
||
|
||
// Use real API data structure with English keys
|
||
const topData = topCardsResponseData || {};
|
||
const leftData = leftCardsResponseData || {};
|
||
const realData = {
|
||
topData: topData,
|
||
leftData: leftData,
|
||
chartData: leftCardsResponseData?.chartData || []
|
||
};
|
||
setDashboardData(realData);
|
||
} catch (error) {
|
||
console.error('Error fetching dashboard data:', error);
|
||
const errorMessage = error instanceof Error ? error.message : 'خطای نامشخص';
|
||
setError(`خطا در بارگذاری دادهها: ${errorMessage}`);
|
||
toast.error(`خطا در بارگذاری دادهها: ${errorMessage}`);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
// RadialBarChart data for ideas visualization
|
||
const getIdeasChartData = () => {
|
||
if (!dashboardData?.topData) return [{ browser: "safari", visitors: 0, fill: "var(--color-safari)" }];
|
||
|
||
const registered = parseFloat(dashboardData.topData.registered_innovation_technology_idea || '0');
|
||
const ongoing = parseFloat(dashboardData.topData.ongoing_innovation_technology_ideas || '0');
|
||
const percentage = registered > 0 ? Math.round((ongoing / registered) * 100) : 0;
|
||
|
||
return [{ browser: "safari", visitors: percentage, fill: "var(--color-safari)" }];
|
||
};
|
||
|
||
const chartData = getIdeasChartData();
|
||
|
||
const chartConfig = {
|
||
visitors: {
|
||
label: "Ideas Progress",
|
||
},
|
||
safari: {
|
||
label: "Safari",
|
||
color: "var(--chart-2)",
|
||
},
|
||
};
|
||
|
||
|
||
if (loading) {
|
||
return (
|
||
<DashboardLayout>
|
||
<div className="p-6">
|
||
<div className="flex items-center justify-center h-64">
|
||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>
|
||
</div>
|
||
</div>
|
||
</DashboardLayout>
|
||
);
|
||
}
|
||
|
||
if (error || !dashboardData) {
|
||
return (
|
||
<DashboardLayout>
|
||
<div className="p-6">
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-red-500/50">
|
||
<CardContent className="p-6">
|
||
<div className="flex flex-col items-center justify-center space-y-4">
|
||
<div className="p-4 bg-red-500/20 rounded-full">
|
||
<CheckCircle className="w-12 h-12 text-red-400" />
|
||
</div>
|
||
<h3 className="text-xl font-bold text-red-400 text-center">
|
||
خطا در بارگذاری دادهها
|
||
</h3>
|
||
<p className="text-gray-300 text-center max-w-md">
|
||
{error || 'خطای نامشخص در بارگذاری دادههای داشبورد رخ داده است'}
|
||
</p>
|
||
<Button
|
||
onClick={fetchDashboardData}
|
||
variant="outline"
|
||
className="border-red-500/50 text-red-400 hover:bg-red-500/10"
|
||
>
|
||
تلاش مجدد
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</DashboardLayout>
|
||
);
|
||
}
|
||
|
||
|
||
|
||
return (
|
||
<DashboardLayout>
|
||
<div className="p-3 pb-0 grid grid-cols-3 gap-4">
|
||
{/* Top Cards Row - Redesigned to match other components */}
|
||
<div className="flex justify-between gap-6 [&>*]:w-full col-span-3">
|
||
{/* Ideas Card */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardContent className="p-4">
|
||
<div className="flex flex-col justify-between gap-2">
|
||
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
|
||
<h3 className="text-lg font-bold text-white font-persian py-2">
|
||
ایدههای فناوری و نوآوری
|
||
</h3>
|
||
</div>
|
||
<div className="flex items-center gap-2 justify-center flex-row-reverse p-1">
|
||
<ChartContainer config={chartConfig} className="w-full h-full max-h-20 max-w-40">
|
||
<RadialBarChart data={chartData} startAngle={0} endAngle={250} innerRadius={30} outerRadius={50}>
|
||
<PolarGrid
|
||
gridType="circle"
|
||
radialLines={false}
|
||
stroke="none"
|
||
className="first:fill-muted last:fill-background"
|
||
polarRadius={[36, 24]}
|
||
/>
|
||
<RadialBar dataKey="visitors" background cornerRadius={5} />
|
||
<PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>
|
||
<Label
|
||
content={({ viewBox }) => {
|
||
if (viewBox && "cx" in viewBox && "cy" in viewBox) {
|
||
return (
|
||
<text x={viewBox.cx} y={viewBox.cy} textAnchor="middle" dominantBaseline="middle">
|
||
<tspan x={viewBox.cx} y={viewBox.cy} className="fill-foreground text-lg font-bold">
|
||
{formatNumber(dashboardData.topData?.ongoing_innovation_technology_ideas || '0')}%
|
||
</tspan>
|
||
|
||
</text>
|
||
)
|
||
}
|
||
}}
|
||
/>
|
||
</PolarRadiusAxis>
|
||
</RadialBarChart>
|
||
</ChartContainer>
|
||
<div className="font-bold font-persian text-center mt-2">
|
||
<div className="flex flex-col justify-between items-center">
|
||
<span className="flex font-bold items-center gap-1">
|
||
<div className="font-light">ثبت شده :</div>
|
||
{formatNumber(dashboardData.topData?.registered_innovation_technology_idea || '0')}
|
||
</span>
|
||
<span className="flex items-center gap-1 font-bold">
|
||
<div className="font-light">در حال اجرا :</div>
|
||
{formatNumber(dashboardData.topData?.ongoing_innovation_technology_ideas || '0')}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Revenue Card */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardContent className="p-4">
|
||
<div className="flex flex-col justify-between gap-2">
|
||
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
|
||
<h3 className="text-lg font-bold text-white font-persian">
|
||
افزایش درآمد مبتنی بر فناوری و نوآوری
|
||
</h3>
|
||
</div>
|
||
<div className="flex items-center justify-center flex-col p-1">
|
||
<div className="flex items-center gap-4">
|
||
<div className="text-center">
|
||
<p className="text-2xl font-bold text-green-400">
|
||
%{formatNumber(dashboardData.topData?.technology_innovation_based_revenue_growth_percent || '0')}
|
||
</p>
|
||
<div className="text-xs text-gray-400 font-persian">
|
||
درصد به کل درآمد
|
||
</div>
|
||
</div>
|
||
<div className="text-center">
|
||
<p className="text-2xl font-bold text-green-400">
|
||
{formatNumber(dashboardData.topData?.technology_innovation_based_revenue_growth || '0')}
|
||
</p>
|
||
<div className="text-xs text-gray-400 font-persian">
|
||
میلیون ریال
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Cost Reduction Card */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardContent className="p-4">
|
||
<div className="flex flex-col justify-between gap-2">
|
||
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
|
||
<h3 className="text-lg font-bold text-white font-persian">
|
||
کاهش هزینه ها مبتنی بر فناوری و نوآوری
|
||
</h3>
|
||
</div>
|
||
<div className="flex items-center justify-center flex-col p-1">
|
||
<div className="flex items-center gap-4">
|
||
<div className="text-center">
|
||
<p className="text-2xl font-bold text-orange-400">
|
||
%{formatNumber(dashboardData.topData?.technology_innovation_based_cost_reduction_percent || '0')}
|
||
</p>
|
||
<div className="text-xs text-gray-400 font-persian">
|
||
درصد به کل هزینه
|
||
</div>
|
||
</div>
|
||
<div className="text-center">
|
||
<p className="text-2xl font-bold text-orange-400">
|
||
{formatNumber(Math.round((parseFloat(dashboardData.topData?.technology_innovation_based_cost_reduction?.replace(/,/g, '') || '0')) / 1000000))}
|
||
</p>
|
||
<div className="text-xs text-gray-400 font-persian">
|
||
میلیون ریال
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Budget Ratio Card */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardContent className="p-4">
|
||
<div className="flex flex-col justify-between gap-2">
|
||
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
|
||
<h3 className="text-lg font-bold text-white font-persian">
|
||
نسبت تحقق بودجه فناوی و نوآوری
|
||
</h3>
|
||
</div>
|
||
<div className="flex items-center gap-2 justify-center flex-row-reverse p-1">
|
||
<ChartContainer config={chartConfig} className="w-full h-full max-h-20 max-w-40">
|
||
<RadialBarChart data={[{
|
||
browser: "budget",
|
||
visitors: parseFloat(dashboardData.topData?.innovation_budget_achievement_percent || '0'),
|
||
fill: "var(--chart-3)"
|
||
}]} startAngle={0} endAngle={250} innerRadius={30} outerRadius={50}>
|
||
<PolarGrid
|
||
gridType="circle"
|
||
radialLines={false}
|
||
stroke="none"
|
||
className="first:fill-muted last:fill-background"
|
||
polarRadius={[36, 24]}
|
||
/>
|
||
<RadialBar dataKey="visitors" background cornerRadius={5} />
|
||
<PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>
|
||
<Label
|
||
content={({ viewBox }) => {
|
||
if (viewBox && "cx" in viewBox && "cy" in viewBox) {
|
||
return (
|
||
<text x={viewBox.cx} y={viewBox.cy} textAnchor="middle" dominantBaseline="middle">
|
||
<tspan x={viewBox.cx} y={viewBox.cy} className="fill-foreground text-lg font-bold">
|
||
%{formatNumber(dashboardData.topData?.innovation_budget_achievement_percent || '0')}
|
||
</tspan>
|
||
</text>
|
||
)
|
||
}
|
||
}}
|
||
/>
|
||
</PolarRadiusAxis>
|
||
</RadialBarChart>
|
||
</ChartContainer>
|
||
<div className="font-bold font-persian text-center mt-2">
|
||
<div className="flex flex-col justify-between items-center">
|
||
<span className="flex font-bold items-center gap-1">
|
||
<div className="font-light">مصوب :</div>
|
||
{formatNumber(Math.round((parseFloat(dashboardData.topData?.approved_innovation_budget_achievement_ratio?.replace(/,/g, '') || '0')) / 1000000000))}
|
||
</span>
|
||
<span className="flex items-center gap-1 font-bold">
|
||
<div className="font-light">جذب شده :</div>
|
||
{formatNumber(Math.round((parseFloat(dashboardData.topData?.allocated_innovation_budget_achievement_ratio?.replace(/,/g, '') || '0')) / 1000000000))}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
|
||
{/* Main Content with Tabs */}
|
||
<Tabs defaultValue="charts" className=" col-span-2 row-start-2 bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)]">
|
||
<TabsList className="bg-transparent">
|
||
<TabsTrigger value="charts" className=" text-white data-[state=active]:bg-blue-500/20 data-[state=active]:text-blue-400">
|
||
مقایسه ای
|
||
</TabsTrigger>
|
||
<TabsTrigger value="canvas" disabled className="text-gray-500 cursor-not-allowed">
|
||
شماتیک
|
||
</TabsTrigger>
|
||
</TabsList>
|
||
|
||
<TabsContent value="charts" className="">
|
||
<div className=" gap-6">
|
||
{/* Right Section - Charts */}
|
||
<div className="">
|
||
{/* Main Chart */}
|
||
<Card className="bg-transparent px-2 border-none">
|
||
<CardHeader>
|
||
<CardTitle className="text-white text-xl">تحلیل ارزشها</CardTitle>
|
||
<p className="text-gray-400 text-sm">نمودار مقایسهای عملکرد ماهانه</p>
|
||
</CardHeader>
|
||
<CardContent className="border-none">
|
||
<div className="h-60 ">
|
||
<ResponsiveContainer width="100%" height="100%">
|
||
<LineChart data={[
|
||
{ month: 'فروردین', ideas: 12, revenue: 850, cost: 320 },
|
||
{ month: 'اردیبهشت', ideas: 19, revenue: 1200, cost: 450 },
|
||
{ month: 'خرداد', ideas: 8, revenue: 980, cost: 280 },
|
||
{ month: 'تیر', ideas: 15, revenue: 1400, cost: 520 },
|
||
{ month: 'مرداد', ideas: 22, revenue: 1650, cost: 680 },
|
||
{ month: 'شهریور', ideas: 18, revenue: 1320, cost: 590 }
|
||
]}>
|
||
<CartesianGrid strokeDasharray="3 3" stroke="#374151" />
|
||
<XAxis
|
||
dataKey="month"
|
||
stroke="#9CA3AF"
|
||
fontSize={11}
|
||
/>
|
||
<YAxis stroke="#9CA3AF" fontSize={11} />
|
||
<Tooltip
|
||
contentStyle={{
|
||
backgroundColor: '#1F2937',
|
||
border: '1px solid #374151',
|
||
borderRadius: '8px',
|
||
color: '#F9FAFB'
|
||
}}
|
||
/>
|
||
<Line
|
||
type="monotone"
|
||
dataKey="ideas"
|
||
stroke="#3B82F6"
|
||
strokeWidth={3}
|
||
name="ایدهها"
|
||
dot={{ fill: '#3B82F6', strokeWidth: 2, r: 4 }}
|
||
/>
|
||
<Line
|
||
type="monotone"
|
||
dataKey="revenue"
|
||
stroke="#10B981"
|
||
strokeWidth={3}
|
||
name="درآمد (میلیون)"
|
||
dot={{ fill: '#10B981', strokeWidth: 2, r: 4 }}
|
||
/>
|
||
<Line
|
||
type="monotone"
|
||
dataKey="cost"
|
||
stroke="#F59E0B"
|
||
strokeWidth={3}
|
||
name="کاهش هزینه (میلیون)"
|
||
dot={{ fill: '#F59E0B', strokeWidth: 2, r: 4 }}
|
||
/>
|
||
</LineChart>
|
||
</ResponsiveContainer>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
</div>
|
||
</div>
|
||
</TabsContent>
|
||
</Tabs>
|
||
|
||
{/* Left Section - Status Cards */}
|
||
<div className="space-y-4 row-start-2 col-spend-1 ">
|
||
{/* Technology Intensity */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardContent className="p-4">
|
||
<div className="flex items-center gap-3">
|
||
<CardTitle className="text-white text-base min-w-[120px]">شدت فناوری</CardTitle>
|
||
<Progress value={parseFloat(dashboardData.leftData?.technology_intensity || '0')} className="h-2 flex-1" />
|
||
<p className="text-sm text-gray-400 min-w-[60px] text-left">%{formatNumber(dashboardData.leftData?.technology_intensity || '0')}</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Program Status */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardContent className="p-4">
|
||
<CustomBarChart
|
||
title="وضعیت برنامههای فناوری و نوآوری"
|
||
loading={loading}
|
||
data={[
|
||
{
|
||
label: "اجرا شده",
|
||
value: parseFloat(dashboardData?.leftData?.executed_project || '0'),
|
||
color: "bg-green-400",
|
||
labelColor: "text-white",
|
||
},
|
||
{
|
||
label: "در حال اجرا",
|
||
value: parseFloat(dashboardData?.leftData?.in_progress_project || '0'),
|
||
color: "bg-blue-400",
|
||
labelColor: "text-white",
|
||
},
|
||
{
|
||
label: "برنامهریزی شده",
|
||
value: parseFloat(dashboardData?.leftData?.planned_project || '0'),
|
||
color: "bg-red-400",
|
||
labelColor: "text-white",
|
||
},
|
||
]}
|
||
barHeight="h-5"
|
||
showAxisLabels={false}
|
||
/>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Publications */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardHeader className="pb-3">
|
||
<CardTitle className="text-white text-lg">انتشارات فناوری و نوآوری</CardTitle>
|
||
</CardHeader>
|
||
<CardContent className="p-4">
|
||
<div className="grid grid-cols-2 grid-rows-2 gap-3">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-blue-400" />
|
||
<span className="text-gray-300 text-sm">کتاب:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-blue-400">
|
||
{formatNumber(dashboardData.leftData?.printed_books_count || '0')}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-purple-400" />
|
||
<span className="text-gray-300 text-sm">پتنت:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-purple-400">
|
||
{formatNumber(dashboardData.leftData?.registered_patents_count || '0')}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-yellow-400" />
|
||
<span className="text-gray-300 text-sm">گزارش:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-yellow-400">
|
||
{formatNumber(dashboardData.leftData?.published_reports_count || '0')}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-green-400" />
|
||
<span className="text-gray-300 text-sm">مقاله:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-green-400">
|
||
{formatNumber(dashboardData.leftData?.printed_articles_count || '0')}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Promotion */}
|
||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50">
|
||
<CardHeader className="pb-3">
|
||
<CardTitle className="text-white text-lg">ترویج فناوری و نوآوری</CardTitle>
|
||
</CardHeader>
|
||
<CardContent className="p-4">
|
||
<div className="space-y-3">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-purple-400" />
|
||
<span className="text-gray-300 text-sm">کنفرانس:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-purple-400">
|
||
{formatNumber(dashboardData.leftData?.attended_conferences_count || '0')}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-blue-400" />
|
||
<span className="text-gray-300 text-sm">شرکت در رویداد:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-blue-400">
|
||
{formatNumber(dashboardData.leftData?.attended_events_count || '0')}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-yellow-400" />
|
||
<span className="text-gray-300 text-sm">نمایشگاه:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-yellow-400">
|
||
{formatNumber(dashboardData.leftData?.attended_exhibitions_count || '0')}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<BookOpen className="w-4 h-4 text-green-400" />
|
||
<span className="text-gray-300 text-sm">برگزاری رویداد:</span>
|
||
</div>
|
||
<span className="text-lg font-bold text-green-400">
|
||
{formatNumber(dashboardData.leftData?.organized_events_count || '0')}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</DashboardLayout>
|
||
);
|
||
}
|
||
|
||
export default DashboardHome;
|