update the ideas page
This commit is contained in:
parent
e10c25fc3e
commit
67815aec2d
|
|
@ -1,4 +1,4 @@
|
|||
import { ChevronDown, ChevronUp, RefreshCw, Eye, Star } from "lucide-react";
|
||||
import { ChevronDown, ChevronUp, RefreshCw, Eye, Star, TrendingUp, Hexagon, Download } from "lucide-react";
|
||||
import { useCallback, useEffect, useRef, useState, useMemo } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
|
|
@ -21,6 +21,18 @@ import {
|
|||
import apiService from "~/lib/api";
|
||||
import { formatCurrency, formatNumber } from "~/lib/utils";
|
||||
import { DashboardLayout } from "../layout";
|
||||
import {
|
||||
ChartContainer,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
type ChartConfig,
|
||||
} from "~/components/ui/chart";
|
||||
import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer, CartesianGrid, LabelList, Cell, RadialBarChart, PolarGrid, RadialBar, PolarRadiusAxis } from "recharts";
|
||||
import { BaseCard } from "~/components/ui/base-card";
|
||||
import { Label } from "~/components/ui/label";
|
||||
import { MetricCard } from "~/components/ui/metric-card";
|
||||
|
||||
|
||||
|
||||
interface IdeaData {
|
||||
idea_title: string;
|
||||
|
|
@ -48,6 +60,18 @@ interface PersonRanking {
|
|||
stars: number;
|
||||
}
|
||||
|
||||
interface IdeaStatusData {
|
||||
idea_status: string;
|
||||
idea_status_count: number;
|
||||
}
|
||||
|
||||
interface IdeaStatsData {
|
||||
registered_innovation_technology_idea: string;
|
||||
ongoing_innovation_technology_ideas: string;
|
||||
increased_revenue_from_ideas: string;
|
||||
increased_revenue_from_ideas_percent: string;
|
||||
}
|
||||
|
||||
interface SortConfig {
|
||||
field: string;
|
||||
direction: "asc" | "desc";
|
||||
|
|
@ -88,6 +112,14 @@ export function ManageIdeasTechPage() {
|
|||
const [peopleRanking, setPeopleRanking] = useState<PersonRanking[]>([]);
|
||||
const [loadingPeople, setLoadingPeople] = useState(false);
|
||||
|
||||
// Chart state
|
||||
const [chartData, setChartData] = useState<IdeaStatusData[]>([]);
|
||||
const [loadingChart, setLoadingChart] = useState(false);
|
||||
|
||||
// Stats state
|
||||
const [statsData, setStatsData] = useState<IdeaStatsData | null>(null);
|
||||
const [loadingStats, setLoadingStats] = useState(false);
|
||||
|
||||
const observerRef = useRef<HTMLDivElement>(null);
|
||||
const fetchingRef = useRef(false);
|
||||
const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
|
@ -204,6 +236,8 @@ export function ManageIdeasTechPage() {
|
|||
fetchIdeas(true);
|
||||
fetchTotalCount();
|
||||
fetchPeopleRanking();
|
||||
fetchChartData();
|
||||
fetchStatsData();
|
||||
}, [sortConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -350,6 +384,68 @@ export function ManageIdeasTechPage() {
|
|||
}
|
||||
};
|
||||
|
||||
const fetchChartData = async () => {
|
||||
try {
|
||||
setLoadingChart(true);
|
||||
|
||||
const response = await apiService.select({
|
||||
ProcessName: "idea",
|
||||
OutputFields: ["idea_status", "count(idea_status)"],
|
||||
GroupBy: ["idea_status"],
|
||||
});
|
||||
|
||||
if (response.state === 0) {
|
||||
const dataString = response.data;
|
||||
if (dataString && typeof dataString === "string") {
|
||||
try {
|
||||
const parsedData: IdeaStatusData[] = JSON.parse(dataString);
|
||||
if (Array.isArray(parsedData)) {
|
||||
setChartData(parsedData?.reverse());
|
||||
}
|
||||
} catch (parseError) {
|
||||
console.error("Error parsing chart data:", parseError);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toast.error(response.message || "خطا در دریافت اطلاعات نمودار");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching chart data:", error);
|
||||
toast.error("خطا در دریافت اطلاعات نمودار");
|
||||
} finally {
|
||||
setLoadingChart(false);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchStatsData = async () => {
|
||||
try {
|
||||
setLoadingStats(true);
|
||||
|
||||
const response = await apiService.call({
|
||||
idea_page_function: {}
|
||||
});
|
||||
|
||||
if (response.state === 0) {
|
||||
const dataString = response.data;
|
||||
if (dataString && typeof dataString === "string") {
|
||||
try {
|
||||
const parsedData: IdeaStatsData = JSON.parse(dataString);
|
||||
setStatsData(parsedData);
|
||||
} catch (parseError) {
|
||||
console.error("Error parsing stats data:", parseError);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toast.error(response.message || "خطا در دریافت آمار ایدهها");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching stats data:", error);
|
||||
toast.error("خطا در دریافت آمار ایدهها");
|
||||
} finally {
|
||||
setLoadingStats(false);
|
||||
}
|
||||
};
|
||||
|
||||
const toPersianDigits = (input: string | number): string => {
|
||||
const str = String(input);
|
||||
const map: Record<string, string> = {
|
||||
|
|
@ -395,7 +491,30 @@ export function ManageIdeasTechPage() {
|
|||
}
|
||||
};
|
||||
|
||||
// Chart configuration for shadcn/ui
|
||||
const chartConfig: ChartConfig = {
|
||||
count: {
|
||||
label: "تعداد",
|
||||
},
|
||||
};
|
||||
|
||||
// Color palette for idea status
|
||||
// Specific colors for idea statuses
|
||||
const getChartStatusColor = (status: string) => {
|
||||
switch (status) {
|
||||
case "اجرا شده":
|
||||
return "#69C8EA";
|
||||
case "تایید شده":
|
||||
return "#3AEA83";
|
||||
case "در حال بررسی":
|
||||
return "#EAD069";
|
||||
case "رد شده":
|
||||
return "#F76276";
|
||||
default:
|
||||
return "#6B7280";
|
||||
}
|
||||
};
|
||||
|
||||
const statusColorPalette = ["#3AEA83", "#69C8EA", "#F76276", "#FFD700", "#A757FF", "#E884CE", "#C3BF8B", "#FB7185"];
|
||||
|
||||
// Build a mapping of status value -> color based on loaded ideas
|
||||
|
|
@ -469,7 +588,7 @@ export function ManageIdeasTechPage() {
|
|||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleShowDetails(item)}
|
||||
className="underline text-pr-green underline-offset-4 text-sm hover:bg-emerald-500/20"
|
||||
className="underline text-pr-green underline-offset-4 text-sm hover:bg-pr-green/20"
|
||||
>
|
||||
جزئیات بیشتر
|
||||
</Button> );
|
||||
|
|
@ -482,9 +601,104 @@ export function ManageIdeasTechPage() {
|
|||
}
|
||||
};
|
||||
|
||||
// Custom Vertical Bar Chart Component using shadcn/ui
|
||||
const VerticalBarChart = () => {
|
||||
if (loadingChart) {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<div className="bg-gray-600 rounded animate-pulse w-48 mx-auto"></div>
|
||||
<div className="h-40 bg-gray-700 rounded animate-pulse"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!chartData.length) {
|
||||
return (
|
||||
<div className="p-6 text-center">
|
||||
<h3 className="text-lg font-persian font-semibold text-white mb-4">وضعیت ایده ها</h3>
|
||||
<p className="text-gray-400 font-persian">هیچ دادهای یافت نشد</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare data for recharts
|
||||
const rechartData = chartData.map((item) => ({
|
||||
status: item.idea_status,
|
||||
count: item.idea_status_count,
|
||||
fill: getChartStatusColor(item.idea_status),
|
||||
}));
|
||||
|
||||
return (
|
||||
<ResponsiveContainer width="100%">
|
||||
<ChartContainer config={chartConfig} className="w-full">
|
||||
<BarChart
|
||||
margin={{ top : 25 ,left: 12, right: 12 }}
|
||||
barGap={15}
|
||||
barSize={45}
|
||||
accessibilityLayer
|
||||
data={rechartData} >
|
||||
<CartesianGrid vertical={false} stroke="#475569" />
|
||||
<XAxis
|
||||
dataKey="status"
|
||||
axisLine={false}
|
||||
tickLine={false}
|
||||
tick={{
|
||||
fill: '#fff',
|
||||
fontSize: 14,
|
||||
fontFamily: 'inherit'
|
||||
}}
|
||||
interval={0}
|
||||
angle={0}
|
||||
tickMargin={10}
|
||||
textAnchor="middle"
|
||||
/>
|
||||
<YAxis
|
||||
tickMargin={20}
|
||||
axisLine={false}
|
||||
tickLine={false}
|
||||
tick={{
|
||||
fill: '#9CA3AF',
|
||||
fontSize: 12,
|
||||
fontFamily: 'inherit'
|
||||
}}
|
||||
tickFormatter={(value) => toPersianDigits(value)}
|
||||
label={{
|
||||
value: "تعداد برنامه ها" ,
|
||||
angle: -90,
|
||||
position: "insideLeft",
|
||||
fill: "#94a3b8",
|
||||
fontSize: 11,
|
||||
offset: 0,
|
||||
dy: 0,
|
||||
style: { textAnchor: "middle" },
|
||||
}}
|
||||
/>
|
||||
<Bar
|
||||
dataKey="count"
|
||||
radius={[4, 4, 0, 0]}
|
||||
>
|
||||
<LabelList
|
||||
dataKey="count"
|
||||
position="top"
|
||||
offset={12}
|
||||
style={{
|
||||
fill: "#ffffff",
|
||||
fontSize: "16px",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
formatter={(v: number) => `${formatNumber(Math.round(v))}`}
|
||||
/>
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</ResponsiveContainer>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardLayout title="مدیریت ایده های فناوری و نوآوری">
|
||||
<div className="space-y-6 h-full">
|
||||
|
||||
<div className="grid grid-cols-1 grid-rows-2 lg:grid-cols-3 gap-4 h-full">
|
||||
{/* People Ranking Table */}
|
||||
<div className="lg:col-span-1">
|
||||
|
|
@ -588,7 +802,7 @@ export function ManageIdeasTechPage() {
|
|||
<div className="relative">
|
||||
<Table
|
||||
containerRef={scrollContainerRef}
|
||||
containerClassName="overflow-auto custom-scrollbar max-h-[calc(50vh-100px)]"
|
||||
containerClassName="overflow-auto custom-scrollbar max-h-[calc(50vh-180px)]"
|
||||
>
|
||||
<TableHeader className="sticky top-0 z-50 bg-pr-gray">
|
||||
<TableRow className="bg-pr-gray">
|
||||
|
|
@ -701,127 +915,354 @@ export function ManageIdeasTechPage() {
|
|||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
{/* Chart Section */}
|
||||
<BaseCard icon={TrendingUp} className="col-span-1 row-start-2 col-start-3 row-span-1" title="نمودار ایدهها">
|
||||
<VerticalBarChart />
|
||||
</BaseCard>
|
||||
<div className="col-span-1 col-start-2 row-start-2 flex flex-col-reverse justify-end gap-2 row-span-1">
|
||||
<BaseCard title="ایدههای فناوری و نوآوری">
|
||||
<div className="flex items-center gap-2 justify-center flex-row-reverse">
|
||||
<ChartContainer
|
||||
config={chartConfig}
|
||||
className="aspect-square w-[6rem] h-auto"
|
||||
>
|
||||
<RadialBarChart
|
||||
data={[
|
||||
{
|
||||
browser: "ideas",
|
||||
visitors:
|
||||
parseFloat(
|
||||
statsData?.registered_innovation_technology_idea || "0"
|
||||
) > 0
|
||||
? Math.round(
|
||||
(parseFloat(
|
||||
statsData?.registered_innovation_technology_idea || "0",
|
||||
) /
|
||||
parseFloat(
|
||||
statsData
|
||||
?.registered_innovation_technology_idea ||
|
||||
"1",
|
||||
)) *
|
||||
100,
|
||||
)
|
||||
: 0,
|
||||
fill: "var(--color-green)",
|
||||
},
|
||||
]}
|
||||
startAngle={90}
|
||||
endAngle={
|
||||
90 +
|
||||
((parseFloat(
|
||||
statsData
|
||||
?.registered_innovation_technology_idea || "0",
|
||||
) > 0
|
||||
? Math.round(
|
||||
(parseFloat(
|
||||
statsData
|
||||
?.ongoing_innovation_technology_ideas || "0",
|
||||
) /
|
||||
parseFloat(
|
||||
statsData
|
||||
?.registered_innovation_technology_idea ||
|
||||
"1",
|
||||
)) *
|
||||
100,
|
||||
)
|
||||
: 0) /
|
||||
100) *
|
||||
360
|
||||
}
|
||||
innerRadius={35}
|
||||
outerRadius={55}
|
||||
>
|
||||
<PolarGrid
|
||||
gridType="circle"
|
||||
radialLines={false}
|
||||
stroke="none"
|
||||
className="first:fill-pr-red last:fill-[#24273A]"
|
||||
polarRadius={[38, 31]}
|
||||
/>
|
||||
<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(
|
||||
parseFloat(
|
||||
statsData
|
||||
?.registered_innovation_technology_idea ||
|
||||
"0",
|
||||
) > 0
|
||||
? Math.round(
|
||||
(parseFloat(
|
||||
statsData
|
||||
?.ongoing_innovation_technology_ideas ||
|
||||
"0",
|
||||
) /
|
||||
parseFloat(
|
||||
statsData
|
||||
?.registered_innovation_technology_idea ||
|
||||
"1",
|
||||
)) *
|
||||
100,
|
||||
)
|
||||
: 0,
|
||||
)}
|
||||
</tspan>
|
||||
</text>
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</PolarRadiusAxis>
|
||||
</RadialBarChart>
|
||||
</ChartContainer>
|
||||
<div className="font-bold font-persian text-center">
|
||||
<div className="flex flex-col justify-between items-center gap-2">
|
||||
<span className="flex font-bold items-center gap-1 text-base">
|
||||
<div className="font-light text-sm">ثبت شده :</div>
|
||||
{formatNumber(
|
||||
statsData
|
||||
?.registered_innovation_technology_idea || "0",
|
||||
)}
|
||||
</span>
|
||||
<span className="flex items-center gap-1 font-bold text-base">
|
||||
<div className="font-light text-sm">در حال اجرا :</div>
|
||||
{formatNumber(
|
||||
statsData
|
||||
?.ongoing_innovation_technology_ideas || "0",
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
|
||||
<MetricCard
|
||||
title="درآمد افزایش یافته"
|
||||
value={statsData?.increased_revenue_from_ideas?.replaceAll("," , "") || "0"}
|
||||
percentValue={statsData?.increased_revenue_from_ideas_percent}
|
||||
percentLabel="درصد به کل درآمد"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Details Dialog */}
|
||||
<Dialog open={isDetailsOpen} onOpenChange={setIsDetailsOpen}>
|
||||
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-right font-persian text-xl">
|
||||
جزئیات ایده: {selectedIdea?.idea_title}
|
||||
<DialogContent className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] max-w-6xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader className="border-b border-gray-600/30 pb-4 mb-6">
|
||||
<DialogTitle className="text-right font-persian text-xl text-white flex items-center justify-between">
|
||||
<span>عنوان ایده: میکروکاتالیزورهای دما بالا</span>
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
{selectedIdea && (
|
||||
<div className="space-y-6 text-right font-persian">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
نام و نام خانوادگی
|
||||
</label>
|
||||
<p className="text-foreground">{selectedIdea.full_name || "-"}</p>
|
||||
{selectedIdea && <div className="flex w-full justify-center gap-4">
|
||||
<div className="flex gap-4 flex-col text-right font-persian w-full border-l-2 border-l-pr-gray px-4 pb-4">
|
||||
{/* مشخصات ایده پردازان Section */}
|
||||
<div className="">
|
||||
<h3 className="text-base font-bold text-white mb-2">
|
||||
مشخصات ایده پردازان
|
||||
</h3>
|
||||
<div className="flex flex-col gap-4 mr-5">
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]"/>
|
||||
<span className="text-white text-sm text-light">نام ایده پرداز:</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
شماره پرسنلی
|
||||
</label>
|
||||
<p className="text-foreground">{toPersianDigits(selectedIdea.personnel_number) || "-"}</p>
|
||||
<span className="text-white font-normal text-sm mr-10">{selectedIdea.full_name || "-"}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
مدیریت
|
||||
</label>
|
||||
<p className="text-foreground">{selectedIdea.management || "-"}</p>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">شماره پرسنلی:</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
معاونت مربوطه
|
||||
</label>
|
||||
<p className="text-foreground">{selectedIdea.deputy || "-"}</p>
|
||||
<span className="text-white font-normal text-sm mr-10">{toPersianDigits(selectedIdea.personnel_number) || "۱۳۰۶۵۸۰۶"}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
نوع نوآوری
|
||||
</label>
|
||||
<p className="text-foreground">{selectedIdea.innovation_type || "-"}</p>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">مدیریت:</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
میزان اصالت ایده
|
||||
</label>
|
||||
<p className="text-foreground">{selectedIdea.idea_originality || "-"}</p>
|
||||
<span className="text-white font-normal text-sm mr-10">{selectedIdea.management || "مدیریت توسعه"}</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">معاونت:</span>
|
||||
</div>
|
||||
<span className="text-white font-normal text-sm mr-10">{selectedIdea.deputy || "توسعه"}</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-2 col-span-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">اعضای تیم:</span>
|
||||
</div>
|
||||
<span className="text-white font-normal text-sm mr-10">
|
||||
{selectedIdea.innovator_team_members || "رضا حسین پور, محمد رضا شیاطی, محمد مددی"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
محور ایده
|
||||
</label>
|
||||
<p className="text-foreground">{selectedIdea.idea_axis || "-"}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
اعضای تیم نوآور
|
||||
</label>
|
||||
<p className="text-foreground">{selectedIdea.innovator_team_members || "-"}</p>
|
||||
{/* مشخصات ایده Section */}
|
||||
<div className="">
|
||||
<h3 className="text-base font-bold text-white mb-2">
|
||||
مشخصات ایده
|
||||
</h3>
|
||||
<div className="flex flex-col gap-4 mr-5">
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">تاریخ ثبت ایده:</span>
|
||||
</div>
|
||||
|
||||
<span className="text-white font-normal text-sm mr-10">{formatDate(selectedIdea.idea_registration_date) || "-"}</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">نوع نوآوری:</span>
|
||||
</div>
|
||||
<span className="text-white font-normal text-sm mr-10">{selectedIdea.innovation_type || "-"}</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">اصالت ایده:</span>
|
||||
</div>
|
||||
<span className="text-white font-normal text-sm mr-10">{selectedIdea.idea_originality || "-"}</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light min-w-max">محور ایده:</span>
|
||||
</div>
|
||||
<span className="text-white font-normal text-sm mr-10">{selectedIdea.idea_axis || "-"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* نتایج و خروجی ها Section */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
<h3 className="text-base font-bold text-white mb-2">
|
||||
نتایج و خروجی ها
|
||||
</h3>
|
||||
<div className="flex flex-col gap-4 mr-5">
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">درآمد حاصل:</span>
|
||||
</div>
|
||||
<span className="text-white text-sm font-normal mr-10">{formatNumber(selectedIdea.increased_revenue) || "-"}
|
||||
<span className="text-[11px] mr-2 font-light">
|
||||
میلیون ریال
|
||||
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">مقاله چاپ شده:</span>
|
||||
</div>
|
||||
<span className="text-white font-normal cursor-pointer text-sm flex items-center gap-2 mr-10">
|
||||
<Download className="h-4 w-4" />
|
||||
|
||||
دانلود
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Hexagon className="stroke-pr-green h-5 w-5 stroke-[1px]" />
|
||||
<span className="text-white text-sm text-light">پتنت ثبت شده:</span>
|
||||
</div>
|
||||
<span className="text-white cursor-pointer font-normal text-sm flex items-center gap-2 mr-10">
|
||||
<Download className="h-4 w-4"/>
|
||||
دانلود
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full flex flex-col gap-8">
|
||||
|
||||
{/* شرح ایده Section */}
|
||||
<div>
|
||||
<h3 className="text-base font-bold text-white mb-4">
|
||||
شرح ایده
|
||||
</label>
|
||||
<p className="text-foreground leading-relaxed">
|
||||
{selectedIdea.idea_description || "-"}
|
||||
</h3>
|
||||
<div className="">
|
||||
<p className="text-white text-sm">
|
||||
{selectedIdea.idea_description ||
|
||||
"-"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* شرح وضعیت موجود ایده Section */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
توضیح وضعیت فعلی ایده
|
||||
</label>
|
||||
<p className="text-foreground leading-relaxed">
|
||||
{selectedIdea.idea_current_status_description || "-"}
|
||||
<h3 className="text-base font-bold text-white mb-4">
|
||||
شرح وضعیت موجود ایده
|
||||
</h3>
|
||||
<div className="">
|
||||
<p className="text-white leading-relaxed text-sm">
|
||||
{selectedIdea.idea_current_status_description ||
|
||||
"-"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* منافع حاصل از ایده Section */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
مزایای اجرای ایده
|
||||
</label>
|
||||
<p className="text-foreground leading-relaxed">
|
||||
{selectedIdea.idea_execution_benefits || "-"}
|
||||
<h3 className="text-base font-bold text-white mb-4">
|
||||
منافع حاصل از ایده
|
||||
</h3>
|
||||
<div>
|
||||
<p className="text-white leading-relaxed text-sm">
|
||||
{selectedIdea.idea_execution_benefits ||
|
||||
"-"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* بهبود های فرآیندی ایده Section */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
بهبودهای فرآیندی
|
||||
</label>
|
||||
<p className="text-foreground leading-relaxed">
|
||||
{selectedIdea.process_improvements || "-"}
|
||||
<h3 className="text-base font-bold text-white mb-4">
|
||||
بهبود های فرآیندی ایده
|
||||
</h3>
|
||||
<div>
|
||||
<p className="text-white leading-relaxed text-sm">
|
||||
{selectedIdea.process_improvements ||
|
||||
"-"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-1">
|
||||
درآمد حاصل از ایده
|
||||
</label>
|
||||
<p className="text-success font-medium">
|
||||
{formatCurrency(selectedIdea.increased_revenue)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -616,22 +616,22 @@ export function ProductInnovationPage() {
|
|||
size="sm"
|
||||
onClick={() => {
|
||||
handleProjectDetails(item)}}
|
||||
className="text-emerald-400 underline underline-offset-4 font-ligth text-base hover:bg-emerald-500/20 p-2 h-auto"
|
||||
className="text-emerald-400 underline underline-offset-4 font-ligth text-sm hover:bg-emerald-500/20 p-2 h-auto"
|
||||
>
|
||||
جزئیات بیشتر
|
||||
</Button>
|
||||
);
|
||||
case "project_no":
|
||||
return (
|
||||
<Badge variant="outline" className="font-mono text-base font-light">
|
||||
<Badge variant="outline" className="font-mono text-sm font-light">
|
||||
{String(value)}
|
||||
</Badge>
|
||||
);
|
||||
case "title":
|
||||
return <span className="font-light text-base text-white">{String(value)}</span>;
|
||||
return <span className="font-light text-sm text-white">{String(value)}</span>;
|
||||
case "project_status":
|
||||
return (
|
||||
<div className="flex items-center text-base font-light gap-1">
|
||||
<div className="flex items-center text-sm font-light gap-1">
|
||||
<Badge
|
||||
variant={statusColor(value as projectStatus)}
|
||||
className="font-semibold text-base border-2 p-0 block w-2 h-2 rounded-full"
|
||||
|
|
@ -652,7 +652,7 @@ export function ProductInnovationPage() {
|
|||
</Badge>
|
||||
);
|
||||
default:
|
||||
return <span className="text-white text-base font-light">{String(value) || "-"}</span>;
|
||||
return <span className="text-white text-sm font-light">{String(value) || "-"}</span>;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user