fix: bugs and chnage some logic
This commit is contained in:
parent
c31eba3c19
commit
ac1081cdd2
|
|
@ -15,6 +15,7 @@ import moment from "moment-jalaali";
|
|||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import { BaseCard } from "~/components/ui/base-card";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card, CardContent } from "~/components/ui/card";
|
||||
import { Checkbox } from "~/components/ui/checkbox";
|
||||
|
|
@ -763,12 +764,12 @@ export function DigitalInnovationPage() {
|
|||
</div>
|
||||
|
||||
{/* Process Impacts Chart */}
|
||||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-lg w-full overflow-hidden h-[18rem]">
|
||||
<BaseCard className="rounded-xl w-full overflow-hidden">
|
||||
{/* <CardContent > */}
|
||||
<CustomBarChart
|
||||
title="تاثیرات نوآوری دیجیتال به صورت درصد مقایسه ای"
|
||||
loading={statsLoading}
|
||||
height="100%"
|
||||
// height="100%"
|
||||
data={[
|
||||
{
|
||||
label: DigitalCardLabel.decreasCost,
|
||||
|
|
@ -798,8 +799,7 @@ export function DigitalInnovationPage() {
|
|||
barHeight="h-5"
|
||||
showAxisLabels={true}
|
||||
/>
|
||||
{/* </CardContent> */}
|
||||
</Card>
|
||||
</BaseCard>
|
||||
</div>
|
||||
|
||||
{/* Data Table */}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import {
|
|||
} from "lucide-react";
|
||||
import moment from "moment-jalaali";
|
||||
import toast from "react-hot-toast";
|
||||
import { MetricCard } from "~/components/ui/metric-card";
|
||||
import { useStoredDate } from "~/hooks/useStoredDate";
|
||||
import apiService from "~/lib/api";
|
||||
import { formatCurrency } from "~/lib/utils";
|
||||
|
|
@ -519,13 +520,13 @@ export function GreenInnovationPage() {
|
|||
},
|
||||
|
||||
pollution: {
|
||||
value: formatNumber(parseNum(stats.pollution_reduction)),
|
||||
percent: formatNumber(parseNum(stats.pollution_reduction_percent)),
|
||||
value: parseNum(stats.pollution_reduction),
|
||||
percent: parseNum(stats.pollution_reduction_percent),
|
||||
},
|
||||
|
||||
waste: {
|
||||
value: formatNumber(parseNum(stats.waste_reduction)),
|
||||
percent: formatNumber(parseNum(stats.waste_reductionn_percent)),
|
||||
value: parseNum(stats.waste_reduction),
|
||||
percent: parseNum(stats.waste_reductionn_percent),
|
||||
},
|
||||
avarage: stats.average_project_score,
|
||||
countInnovationGreenProjects: stats.count_innovation_green_projects,
|
||||
|
|
@ -543,7 +544,6 @@ export function GreenInnovationPage() {
|
|||
setStatsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const setPageData = (normalized: any) => {
|
||||
setSustainabilityStats((prev) => ({
|
||||
...prev,
|
||||
|
|
@ -747,39 +747,14 @@ export function GreenInnovationPage() {
|
|||
</Card>
|
||||
))
|
||||
: Object.entries(sustainabilityStats).map(([key, value]) => (
|
||||
<Card
|
||||
<MetricCard
|
||||
key={key}
|
||||
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] rounded-lg backdrop-blur-sm border-gray-700/50"
|
||||
>
|
||||
<CardContent className="p-0 h-full">
|
||||
<div className="flex flex-col justify-between gap-2 h-full">
|
||||
<div className="flex justify-between items-center border-b-2 border-gray-500/20 ">
|
||||
<h3 className="text-lg font-bold text-white font-persian p-4">
|
||||
{value.title}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-6 flex-row-reverse">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-3xl font-bold text-pr-green mb-1 font-persian">
|
||||
% {value.percent?.value}
|
||||
</span>
|
||||
<span className="text-sm text-gray-400 font-persian">
|
||||
{value.percent?.description}
|
||||
</span>
|
||||
</div>
|
||||
<b className="block w-0.5 h-8 bg-gray-600 rotate-45" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-3xl font-bold text-pr-green mb-1 font-persian">
|
||||
{value.total?.value}
|
||||
</span>
|
||||
<span className="text-sm text-gray-400 font-persian">
|
||||
{value.total?.description}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
title={value.title}
|
||||
value={Math.round(value.total.value || 0)}
|
||||
valueLabel={value.total?.description}
|
||||
percentValue={value.percent?.value || 0}
|
||||
percentLabel={value.percent?.description}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import {
|
|||
ResponsiveContainer,
|
||||
XAxis,
|
||||
} from "recharts";
|
||||
import { MetricCard } from "~/components/ui/metric-card";
|
||||
import { useStoredDate } from "~/hooks/useStoredDate";
|
||||
import apiService from "~/lib/api";
|
||||
import { EventBus, formatCurrency, formatNumber } from "~/lib/utils";
|
||||
|
|
@ -523,15 +524,13 @@ export function InnovationBuiltInsidePage() {
|
|||
const stats = data[0];
|
||||
const normalized: any = {
|
||||
currencySaving: {
|
||||
value: formatNumber(parseNum(stats?.foreign_currency_saving)),
|
||||
percent: formatNumber(
|
||||
parseNum(stats?.foreign_currency_saving_percent)
|
||||
),
|
||||
value: parseNum(stats?.foreign_currency_saving),
|
||||
percent: parseNum(stats?.foreign_currency_saving_percent),
|
||||
},
|
||||
|
||||
investmentAmount: {
|
||||
value: formatNumber(parseNum(stats?.investment_amount)),
|
||||
percent: formatNumber(parseNum(stats?.investment_amount_percent)),
|
||||
value: parseNum(stats?.investment_amount),
|
||||
percent: parseNum(stats?.investment_amount_percent),
|
||||
},
|
||||
|
||||
technology: {
|
||||
|
|
@ -755,39 +754,47 @@ export function InnovationBuiltInsidePage() {
|
|||
</Card>
|
||||
))
|
||||
: Object.entries(sustainabilityStats).map(([key, value]) => (
|
||||
<Card
|
||||
<MetricCard
|
||||
key={key}
|
||||
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] rounded-lg backdrop-blur-sm border-gray-700/50"
|
||||
>
|
||||
<CardContent className="p-0 h-full">
|
||||
<div className="flex flex-col justify-between gap-2 h-full">
|
||||
<div className="flex justify-between items-center border-b-2 border-gray-500/20 ">
|
||||
<h3 className="text-lg font-semibold text-white p-4">
|
||||
{value.title}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-6 flex-row-reverse">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-3xl font-bold text-pr-green mb-1 font-persian">
|
||||
% {value.percent?.value}
|
||||
</span>
|
||||
<span className="text-sm text-gray-400 font-persian">
|
||||
{value.percent?.description}
|
||||
</span>
|
||||
</div>
|
||||
<b className="block w-0.5 h-8 bg-gray-600 rotate-45" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-3xl font-bold text-pr-green mb-1 font-persian">
|
||||
{value.total?.value}
|
||||
</span>
|
||||
<span className="text-sm text-gray-400 font-persian">
|
||||
{value.total?.description}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
title={value.title}
|
||||
value={Math.round(value.total.value || 0)}
|
||||
valueLabel={value.total?.description}
|
||||
percentValue={value.percent?.value || 0}
|
||||
percentLabel={value.percent?.description}
|
||||
/>
|
||||
// <Card
|
||||
// key={key}
|
||||
// className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] rounded-lg backdrop-blur-sm border-gray-700/50"
|
||||
// >
|
||||
// <CardContent className="p-0 h-full">
|
||||
// <div className="flex flex-col justify-between gap-2 h-full">
|
||||
// <div className="flex justify-between items-center border-b-2 border-gray-500/20 ">
|
||||
// <h3 className="text-lg font-semibold text-white p-4">
|
||||
// {value.title}
|
||||
// </h3>
|
||||
// </div>
|
||||
// <div className="flex items-center justify-between p-6 flex-row-reverse">
|
||||
// <div className="flex flex-col">
|
||||
// <span className="text-3xl font-bold text-pr-green mb-1 font-persian">
|
||||
// % {value.percent?.value}
|
||||
// </span>
|
||||
// <span className="text-sm text-gray-400 font-persian">
|
||||
// {value.percent?.description}
|
||||
// </span>
|
||||
// </div>
|
||||
// <b className="block w-0.5 h-8 bg-gray-600 rotate-45" />
|
||||
// <div className="flex flex-col">
|
||||
// <span className="text-3xl font-bold text-pr-green mb-1 font-persian">
|
||||
// {value.total?.value}
|
||||
// </span>
|
||||
// <span className="text-sm text-gray-400 font-persian">
|
||||
// {value.total?.description}
|
||||
// </span>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </CardContent>
|
||||
// </Card>
|
||||
))}
|
||||
|
||||
{statsLoading ? (
|
||||
|
|
|
|||
|
|
@ -187,11 +187,12 @@ export function ProcessInnovationPage() {
|
|||
icon: DollarSign,
|
||||
color: "text-pr-green",
|
||||
},
|
||||
currencyreduction1: {
|
||||
id: "currencyreduction1",
|
||||
decreaseCurrencyOperation: {
|
||||
id: "decreaseCurrencyOperation",
|
||||
title: "کاهش هزینه عملیاتی",
|
||||
value: formatNumber(
|
||||
stats.reductionCostOprationSum.toFixed?.(0) ?? stats.reductionCostOprationSum
|
||||
stats.reductionCostOprationSum.toFixed?.(0) ??
|
||||
stats.reductionCostOprationSum
|
||||
),
|
||||
description: "میلیون ریال یافته",
|
||||
icon: DollarSign,
|
||||
|
|
@ -213,15 +214,6 @@ export function ProcessInnovationPage() {
|
|||
const observerRef = useRef<HTMLDivElement>(null);
|
||||
const fetchingRef = useRef(false);
|
||||
|
||||
// Selection handlers
|
||||
// const handleSelectAll = () => {
|
||||
// if (selectedProjects.size === projects.length) {
|
||||
// setSelectedProjects(new Set());
|
||||
// } else {
|
||||
// setSelectedProjects(new Set(projects.map((p) => p.project_no)));
|
||||
// }
|
||||
// };
|
||||
|
||||
const handleSelectProject = (projectNo: string) => {
|
||||
const newSelected = new Set(selectedProjects);
|
||||
if (newSelected.has(projectNo)) {
|
||||
|
|
@ -489,7 +481,8 @@ export function ProcessInnovationPage() {
|
|||
currencyReductionSum: parseNum(stats?.sum_reduction_value_currency),
|
||||
frequentFailuresReductionSum: parseNum(stats?.sum_reducing_breakdowns),
|
||||
percentProductionStops: stats?.percent_sum_stopping_production,
|
||||
percentOperatingCostBeforeInnovation: stats?.percent_operating_cost_before_innovation,
|
||||
percentOperatingCostBeforeInnovation:
|
||||
stats?.percent_operating_cost_before_innovation,
|
||||
percentBottleneckRemoval: stats?.percent_throat_removal,
|
||||
percentCurrencyReduction: stats?.percent_reduction_value_currency,
|
||||
percentFailuresReduction: stats?.percent_reducing_breakdowns,
|
||||
|
|
@ -512,6 +505,10 @@ export function ProcessInnovationPage() {
|
|||
...prev.currencyreduction,
|
||||
value: formatNumber(normalized.currencyReductionSum),
|
||||
},
|
||||
decreaseCurrencyOperation: {
|
||||
...prev.decreaseCurrencyOperation,
|
||||
value: formatNumber(normalized.reductionCostOprationSum),
|
||||
},
|
||||
}));
|
||||
setStats(normalized);
|
||||
} catch (error) {
|
||||
|
|
@ -638,13 +635,14 @@ export function ProcessInnovationPage() {
|
|||
<div className="flex gap-4">
|
||||
<div className="space-y-4 w-full">
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{loading || statsLoading
|
||||
? // Loading skeleton for stats cards - matching new design
|
||||
Array.from({ length: 4 }).map((_, index) => (
|
||||
<div className="h-full">
|
||||
{loading || statsLoading ? (
|
||||
// Skeleton cards
|
||||
<div className="flex flex-wrap justify-between gap-3">
|
||||
{Array.from({ length: 6 }).map((_, index) => (
|
||||
<BaseCard
|
||||
key={`skeleton-${index}`}
|
||||
className="rounded-2xl overflow-hidden"
|
||||
className="rounded-2xl overflow-hidden w-full sm:w-[48%] md:w-[30%]"
|
||||
>
|
||||
<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">
|
||||
|
|
@ -668,42 +666,112 @@ export function ProcessInnovationPage() {
|
|||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
))
|
||||
: Object.entries(stateCard).map(([key, card]) => {
|
||||
// map percent values for each card key
|
||||
const percentMap: Record<
|
||||
string,
|
||||
number | string | undefined
|
||||
> = {
|
||||
productionstopsprevention: stats.percentProductionStops,
|
||||
bottleneckremoval: stats.percentBottleneckRemoval,
|
||||
currencyreduction: stats.percentCurrencyReduction,
|
||||
frequentfailuresreduction: stats.percentFailuresReduction,
|
||||
};
|
||||
const percentValue = percentMap[key];
|
||||
|
||||
return (
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col h-full gap-5">
|
||||
<div className="flex flex-row gap-4 h-full">
|
||||
<BaseCard
|
||||
key={card.id}
|
||||
title={card.title}
|
||||
className="border-gray-700/50"
|
||||
icon={card.icon}
|
||||
key={stateCard.bottleneckremoval.id}
|
||||
title={stateCard.bottleneckremoval.title}
|
||||
className="border-gray-700/50 w-full"
|
||||
icon={stateCard.bottleneckremoval.icon}
|
||||
>
|
||||
<div className="flex items-center justify-center flex-col">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="text-center">
|
||||
<p className="text-3xl text-pr-green font-bold mb-1">
|
||||
{card.value}
|
||||
{stateCard.bottleneckremoval.value}
|
||||
</p>
|
||||
<div className="text-[11px] text-[#ACACAC] font-light font-persian">
|
||||
{card.description}
|
||||
{stateCard.bottleneckremoval.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
);
|
||||
})}
|
||||
|
||||
<BaseCard
|
||||
key={stateCard.currencyreduction.id}
|
||||
title={stateCard.currencyreduction.title}
|
||||
className="border-gray-700/50 w-full"
|
||||
icon={stateCard.currencyreduction.icon}
|
||||
>
|
||||
<div className="flex items-center justify-center flex-col">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="text-center">
|
||||
<p className="text-3xl text-pr-green font-bold mb-1">
|
||||
{stateCard.currencyreduction.value}
|
||||
</p>
|
||||
<div className="text-[11px] text-[#ACACAC] font-light font-persian">
|
||||
{stateCard.currencyreduction.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</div>
|
||||
<div className="flex flex-row gap-4 h-full">
|
||||
<BaseCard
|
||||
key={stateCard.frequentfailuresreduction.id}
|
||||
title={stateCard.frequentfailuresreduction.title}
|
||||
className="border-gray-700/50 w-full"
|
||||
icon={stateCard.frequentfailuresreduction.icon}
|
||||
>
|
||||
<div className="flex items-center justify-center flex-col">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="text-center">
|
||||
<p className="text-3xl text-pr-green font-bold mb-1">
|
||||
{stateCard.frequentfailuresreduction.value}
|
||||
</p>
|
||||
<div className="text-[11px] text-[#ACACAC] font-light font-persian">
|
||||
{stateCard.frequentfailuresreduction.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
<BaseCard
|
||||
key={stateCard.decreaseCurrencyOperation.id}
|
||||
title={stateCard.decreaseCurrencyOperation.title}
|
||||
className="border-gray-700/50 w-full"
|
||||
icon={stateCard.decreaseCurrencyOperation.icon}
|
||||
>
|
||||
<div className="flex items-center justify-center flex-col">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="text-center">
|
||||
<p className="text-3xl text-pr-green font-bold mb-1">
|
||||
{stateCard.decreaseCurrencyOperation.value}
|
||||
</p>
|
||||
<div className="text-[11px] text-[#ACACAC] font-light font-persian">
|
||||
{stateCard.decreaseCurrencyOperation.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
<BaseCard
|
||||
key={stateCard.productionstopsprevention.id}
|
||||
title={stateCard.productionstopsprevention.title}
|
||||
className="border-gray-700/50 w-full"
|
||||
icon={stateCard.productionstopsprevention.icon}
|
||||
>
|
||||
<div className="flex items-center justify-center flex-col">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="text-center">
|
||||
<p className="text-3xl text-pr-green font-bold mb-1">
|
||||
{stateCard.productionstopsprevention.value}
|
||||
</p>
|
||||
<div className="text-[11px] text-[#ACACAC] font-light font-persian">
|
||||
{stateCard.productionstopsprevention.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -736,7 +804,8 @@ export function ProcessInnovationPage() {
|
|||
},
|
||||
{
|
||||
label: "کاهش هزینه عملیاتی",
|
||||
value: Number(stats.percentOperatingCostBeforeInnovation) || 0,
|
||||
value:
|
||||
Number(stats.percentOperatingCostBeforeInnovation) || 0,
|
||||
labelColor: "text-white",
|
||||
},
|
||||
{
|
||||
|
|
@ -745,7 +814,7 @@ export function ProcessInnovationPage() {
|
|||
labelColor: "text-white",
|
||||
},
|
||||
]}
|
||||
barHeight="h-6"
|
||||
barHeight="h-5"
|
||||
showAxisLabels={true}
|
||||
/>
|
||||
</BaseCard>
|
||||
|
|
|
|||
|
|
@ -105,8 +105,8 @@ export function NetworkGraph({
|
|||
return await apiService.call<any>({
|
||||
get_values_workflow_function: {
|
||||
stage_id: stage_id,
|
||||
start_date: date?.start || null,
|
||||
end_date: date?.end || null,
|
||||
// start_date: date?.start || null,
|
||||
// end_date: date?.end || null,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
@ -194,7 +194,7 @@ export function NetworkGraph({
|
|||
aborted = true;
|
||||
controller.abort();
|
||||
};
|
||||
}, [isMounted, token, getImageUrl]);
|
||||
}, [isMounted, token, getImageUrl, date]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMounted || !svgRef.current || isLoading || nodes.length === 0)
|
||||
|
|
|
|||
|
|
@ -23,22 +23,34 @@ export function BaseCard({
|
|||
return (
|
||||
<Card
|
||||
className={cn(
|
||||
"bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm py-4 grid items-center",
|
||||
"bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm py-2 pb-0 grid items-center",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{Icon && title ? (
|
||||
<CardHeader className={cn("border-b-2 border-gray-500/20 py-2 px-0 pb-4", headerClassName)}>
|
||||
<CardTitle className="text-white text-sm text-right font-persian px-4 my-auto items-center flex w-full justify-between">{title} {<Icon />} </CardTitle>
|
||||
<CardHeader
|
||||
className={cn(
|
||||
"border-b-2 border-gray-500/20 py-2 px-0 pb-4",
|
||||
headerClassName
|
||||
)}
|
||||
>
|
||||
<CardTitle className="text-white text-sm text-right font-persian px-4 my-auto items-center flex w-full justify-between">
|
||||
{title} {<Icon />}{" "}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
) :
|
||||
withHeader && title ? (
|
||||
<CardHeader className={cn("pb-2 border-b-2 border-gray-500/20", headerClassName)}>
|
||||
<CardTitle className="text-white text-sm text-right font-persian px-4">{title}</CardTitle>
|
||||
) : withHeader && title ? (
|
||||
<CardHeader
|
||||
className={cn("pb-2 border-b-2 border-gray-500/20", headerClassName)}
|
||||
>
|
||||
<CardTitle className="text-white text-sm text-right font-persian px-4">
|
||||
{title}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
) : title ? (
|
||||
<div className="border-b-2 border-gray-500/20 pb-2">
|
||||
<h3 className="text-sm font-bold text-white text-right font-persian px-4">{title}</h3>
|
||||
<h3 className="text-sm font-bold text-white text-right font-persian px-4">
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
) : null}
|
||||
<CardContent className={cn("py-2 px-4 ", contentClassName)}>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export function CustomBarChart({
|
|||
// Loading skeleton
|
||||
if (loading) {
|
||||
return (
|
||||
<div className={`space-y-6 p-4 ${className}`} style={{ height }}>
|
||||
<div className={`space-y-6 p-4 pt-0 ${className}`} style={{ height }}>
|
||||
{title && (
|
||||
<div className="h-7 bg-gray-600 rounded animate-pulse mb-4 w-1/2"></div>
|
||||
)}
|
||||
|
|
@ -71,7 +71,7 @@ export function CustomBarChart({
|
|||
<div className={`space-y-6 ${className}`} style={{ height }}>
|
||||
{title && (
|
||||
<div className="border-b-[#3F415A] border-b-2">
|
||||
<h3 className="text-sm font-semibold text-white font-persian text-right p-4">
|
||||
<h3 className="text-sm font-semibold text-white font-persian text-right px-4 pb-3">
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ export function MetricCard({
|
|||
percentLabel = "درصد به کل",
|
||||
}: MetricCardProps) {
|
||||
return (
|
||||
<BaseCard title={title}>
|
||||
<BaseCard title={title} className="h-full">
|
||||
<div className="flex items-center justify-center flex-col">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-4 h-full">
|
||||
<div className="text-center">
|
||||
<p className="text-3xl font-bold text-green-400">
|
||||
{formatNumber(value)}
|
||||
|
|
|
|||
5140
package-lock.json
generated
Normal file
5140
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user