diff --git a/app/components/dashboard/dashboard-custom-bar-chart.tsx b/app/components/dashboard/dashboard-custom-bar-chart.tsx new file mode 100644 index 0000000..516cffb --- /dev/null +++ b/app/components/dashboard/dashboard-custom-bar-chart.tsx @@ -0,0 +1,74 @@ +import React from "react"; +import { formatNumber } from "~/lib/utils"; + +interface DataItem { + label: string; + value: number; + color: string; +} + +interface DashboardCustomBarChartProps { + title: string; + data: DataItem[]; + loading?: boolean; +} + +export function DashboardCustomBarChart({ + title, + data, + loading = false, +}: DashboardCustomBarChartProps) { + if (loading) { + return ( +
+

+ {title} +

+
+ {[1, 2, 3].map((i) => ( +
+
+
+ ))} +
+
+ ); + } + + // Calculate the maximum value for scaling + const maxValue = Math.max(...data.map((item) => item.value)); + + return ( +
+

+ {title} +

+
+ {data.map((item, index) => { + const widthPercentage = + maxValue > 0 ? (item.value / maxValue) * 100 : 0; + + return ( +
+ {/* Bar container */} +
+ {/* Animated bar */} +
+ + {formatNumber(item.value)} + + + {item.label} + +
+
+
+ ); + })} +
+
+ ); +} diff --git a/app/components/dashboard/dashboard-home.tsx b/app/components/dashboard/dashboard-home.tsx index 75b2b58..4af7528 100644 --- a/app/components/dashboard/dashboard-home.tsx +++ b/app/components/dashboard/dashboard-home.tsx @@ -4,23 +4,43 @@ 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 { + 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 { + 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 { DashboardCustomBarChart } from "./dashboard-custom-bar-chart"; import { Label, PolarGrid, PolarRadiusAxis, RadialBar, RadialBarChart, -} from "recharts" -import { ChartContainer } from "~/components/ui/chart" +} from "recharts"; +import { ChartContainer } from "~/components/ui/chart"; import { formatNumber } from "~/lib/utils"; - export function DashboardHome() { const [dashboardData, setDashboardData] = useState(null); const [loading, setLoading] = useState(true); @@ -36,25 +56,28 @@ export function DashboardHome() { setError(null); // First authenticate if needed - const token = localStorage.getItem('auth_token'); + const token = localStorage.getItem("auth_token"); if (!token) { - await apiService.login('inogen_admin', '123456'); + await apiService.login("inogen_admin", "123456"); } // Fetch top cards data const topCardsResponse = await apiService.call({ - main_page_first_function: {} + main_page_first_function: {}, }); // Fetch left section data const leftCardsResponse = await apiService.call({ - main_page_second_function: {} + main_page_second_function: {}, }); - + const topCardsResponseData = JSON.parse(topCardsResponse?.data); const leftCardsResponseData = JSON.parse(leftCardsResponse?.data); - console.log('API Responses:', { topCardsResponseData, leftCardsResponseData }); + console.log("API Responses:", { + topCardsResponseData, + leftCardsResponseData, + }); // Use real API data structure with English keys const topData = topCardsResponseData || {}; @@ -62,12 +85,13 @@ export function DashboardHome() { const realData = { topData: topData, leftData: leftData, - chartData: leftCardsResponseData?.chartData || [] + chartData: leftCardsResponseData?.chartData || [], }; setDashboardData(realData); } catch (error) { - console.error('Error fetching dashboard data:', error); - const errorMessage = error instanceof Error ? error.message : 'خطای نامشخص'; + console.error("Error fetching dashboard data:", error); + const errorMessage = + error instanceof Error ? error.message : "خطای نامشخص"; setError(`خطا در بارگذاری داده‌ها: ${errorMessage}`); toast.error(`خطا در بارگذاری داده‌ها: ${errorMessage}`); } finally { @@ -75,34 +99,41 @@ export function DashboardHome() { } }; - // RadialBarChart data for ideas visualization + // 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)" }]; + 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)", - }, -}; - + const chartConfig = { + visitors: { + label: "Ideas Progress", + }, + safari: { + label: "Safari", + color: "var(--chart-2)", + }, + }; if (loading) { return ( -
+
@@ -114,9 +145,9 @@ const chartConfig = { if (error || !dashboardData) { return ( -
+
- +
@@ -125,11 +156,12 @@ const chartConfig = { خطا در بارگذاری داده‌ها

- {error || 'خطای نامشخص در بارگذاری داده‌های داشبورد رخ داده است'} + {error || + "خطای نامشخص در بارگذاری داده‌های داشبورد رخ داده است"}

-