Merge branch 'main' of http://git.sepehrdata.com/Saeed0920/inogen
This commit is contained in:
commit
584450550b
|
|
@ -594,8 +594,8 @@ export function DashboardHome() {
|
|||
<p className="p-6 font-persian font-semibold text-lg ">
|
||||
تحقق ارزش ها
|
||||
</p>
|
||||
<TabsList className="bg-transparent py-2 border m-6 border-gray-600">
|
||||
<TabsTrigger value="canvas" className="cursor-pointer">
|
||||
<TabsList className="bg-transparent py-2 m-6 border-[1px] border-[#5F6284]">
|
||||
<TabsTrigger value="canvas" className="cursor-pointer">
|
||||
شماتیک
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="charts" className=" text-white cursor-pointer font-light ">
|
||||
|
|
|
|||
|
|
@ -932,15 +932,7 @@ export function ManageIdeasTechPage() {
|
|||
|
||||
{/* Infinite scroll trigger */}
|
||||
<div ref={observerRef} className="h-auto">
|
||||
{loadingMore && (
|
||||
<div className="flex items-center justify-center py-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<RefreshCw className="w-4 h-4 animate-spin text-success" />
|
||||
<span className="font-persian text-muted-foreground text-sm">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
|
|
@ -951,6 +943,15 @@ export function ManageIdeasTechPage() {
|
|||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
{loadingMore && (
|
||||
<div className="flex items-center justify-center py-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<RefreshCw className="w-4 h-4 animate-spin text-success" />
|
||||
<span className="font-persian text-muted-foreground text-sm">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* Chart Section */}
|
||||
<BaseCard icon={TrendingUp} className="col-span-1 mt-12 row-start-2 col-start-3 row-span-1" title="نمودار ایدهها">
|
||||
|
|
|
|||
|
|
@ -237,11 +237,11 @@ export function ProductInnovationPage() {
|
|||
revenueNewProducts: {
|
||||
id: "revenueNewProducts",
|
||||
title: "سهم از درآمد برای محصولات جدید",
|
||||
value: "0",
|
||||
value: 0,
|
||||
description: "میلیون ریال",
|
||||
descriptionPercent: "درصد به کل درآمد",
|
||||
color: "text-[#3AEA83]",
|
||||
percent : "0"
|
||||
percent :0
|
||||
},
|
||||
newProductExports: {
|
||||
id: "newProductExports",
|
||||
|
|
@ -466,8 +466,8 @@ export function ProductInnovationPage() {
|
|||
...prev,
|
||||
revenueNewProducts: {
|
||||
...prev.revenueNewProducts,
|
||||
value: formatNumber(normalized?.new_products_revenue_share),
|
||||
percent: formatNumber(normalized?.new_products_revenue_share_percent),
|
||||
value: normalized.new_products_revenue_share,
|
||||
percent: normalized.new_products_revenue_share_percent,
|
||||
},
|
||||
impactOnImports: {
|
||||
...prev.impactOnImports,
|
||||
|
|
@ -716,8 +716,8 @@ export function ProductInnovationPage() {
|
|||
<div className="col-span-2">
|
||||
<MetricCard
|
||||
title={stateCard.revenueNewProducts.title}
|
||||
value={formatNumber(stateCard.revenueNewProducts.value)}
|
||||
percentValue={formatNumber(stateCard.revenueNewProducts.percent)}
|
||||
value={stateCard.revenueNewProducts.value}
|
||||
percentValue={stateCard.revenueNewProducts.percent}
|
||||
valueLabel={stateCard.revenueNewProducts.description}
|
||||
percentLabel={stateCard.revenueNewProducts.descriptionPercent}
|
||||
/>
|
||||
|
|
@ -756,7 +756,7 @@ export function ProductInnovationPage() {
|
|||
</div>
|
||||
|
||||
{/* Funnel Chart */}
|
||||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] h-full backdrop-blur-sm rounded-2xl w-full overflow-hidden">
|
||||
<Card className=" bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] h-full 2xl:h-auto pb-8 backdrop-blur-sm rounded-2xl w-full overflow-hidden">
|
||||
<CardContent className="px-0 py-4">
|
||||
<FunnelChart
|
||||
title="قيف فرآیند پروژه ها"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import { TruncatedText } from "../ui/truncatedText";
|
|||
|
||||
interface StrategicAlignmentData {
|
||||
strategic_theme: string;
|
||||
operational_fee_sum: number;
|
||||
operational_fee_count: number;
|
||||
percentage?: number;
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ export function StrategicAlignmentPopup({
|
|||
ProcessName: "project",
|
||||
OutputFields: [
|
||||
"strategic_theme",
|
||||
"sum(operational_fee) as operational_fee_sum",
|
||||
"count(operational_fee)",
|
||||
],
|
||||
GroupBy: ["strategic_theme"],
|
||||
});
|
||||
|
|
@ -168,7 +168,7 @@ export function StrategicAlignmentPopup({
|
|||
ProcessName: "project",
|
||||
OutputFields: [
|
||||
"value_technology_and_innovation",
|
||||
"sum(operational_fee)",
|
||||
"count(operational_fee)",
|
||||
],
|
||||
Conditions: [["strategic_theme", "=", item]],
|
||||
GroupBy: ["value_technology_and_innovation"],
|
||||
|
|
@ -233,13 +233,13 @@ export function StrategicAlignmentPopup({
|
|||
.map((item: any) => ({
|
||||
strategic_theme:
|
||||
item.strategic_theme || item.value_technology_and_innovation || "N/A",
|
||||
operational_fee_sum: Math.max(0, Number(item.operational_fee_sum)),
|
||||
operational_fee_count: Math.max(0, Number(item.operational_fee_count)),
|
||||
}))
|
||||
.filter((item: StrategicAlignmentData) => item.strategic_theme !== "");
|
||||
|
||||
const total = processedData.reduce(
|
||||
(acc: number, item: StrategicAlignmentData) =>
|
||||
acc + item.operational_fee_sum,
|
||||
acc + item.operational_fee_count,
|
||||
0
|
||||
);
|
||||
|
||||
|
|
@ -247,7 +247,7 @@ export function StrategicAlignmentPopup({
|
|||
(item: StrategicAlignmentData) => ({
|
||||
...item,
|
||||
percentage:
|
||||
total > 0 ? Math.round((item.operational_fee_sum / total) * 100) : 0,
|
||||
total > 0 ? Math.round((item.operational_fee_count / total) * 100) : 0,
|
||||
})
|
||||
);
|
||||
setData(dataWithPercentage || []);
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ export function NetworkGraph({ onNodeClick, onLoadingChange }: NetworkGraphProps
|
|||
.enter()
|
||||
.append("g")
|
||||
.attr("class", "node")
|
||||
.style("cursor", "pointer");
|
||||
.style("cursor", d => d.stageid === -1 ? "default" : "pointer");
|
||||
|
||||
const drag = d3
|
||||
.drag<SVGGElement, Node>()
|
||||
|
|
@ -437,9 +437,12 @@ export function NetworkGraph({ onNodeClick, onLoadingChange }: NetworkGraphProps
|
|||
.attr("stroke-width", 3);
|
||||
});
|
||||
|
||||
|
||||
nodeGroup.on("click", async function (event, d) {
|
||||
event.stopPropagation();
|
||||
if (d.isCenter) return;
|
||||
|
||||
// جلوگیری از کلیک روی مرکز و دستهبندیها
|
||||
if (d.isCenter || d.stageid === -1) return;
|
||||
|
||||
if (onNodeClick && d.stageid) {
|
||||
// Open dialog immediately with basic info
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ interface FunnelChartProps {
|
|||
title?: string;
|
||||
className?: string;
|
||||
}
|
||||
const greenColors = ["#3C9F71","#3BC47A","#3BC47A","#3BD77E","#3AEA83"]
|
||||
|
||||
export function FunnelChart({ data, title, className = "" }: FunnelChartProps) {
|
||||
const maxValue = Math.max(...data.map(d => d.value));
|
||||
|
|
@ -50,15 +51,15 @@ export function FunnelChart({ data, title, className = "" }: FunnelChartProps) {
|
|||
|
||||
return (
|
||||
<div key={index} className="grid grid-cols-[6rem_1fr] gap-2 w-full">
|
||||
<div className="text-sm font-light text-white cols-start-1 justify-self-start font-thin min-w-[max-content] text-center">
|
||||
<div className="text-sm font-light text-white font-persian cols-start-1 justify-self-start min-w-[max-content] text-center">
|
||||
{item.label}
|
||||
</div>
|
||||
<div className="flex items-center gap-10 w-full cols-start-2 flex items-center justify-center w-full">
|
||||
<div className="flex items-center gap-10 w-full cols-start-2 justify-center">
|
||||
<div className="flex items-center w-full">
|
||||
<div style={{ width: `${(100 - barWidth) / 2}%` }} />
|
||||
<div
|
||||
className="bg-[#3BC47A] h-8 rounded-2xl flex items-center justify-center text-lg relative"
|
||||
style={{ width: `${barWidth}%` }}
|
||||
style={{ width: `${barWidth}%` ,backgroundColor : `${greenColors[index]}`}}
|
||||
>
|
||||
<span className="text-pr-gray text-base font-semibold">
|
||||
{item.value.toLocaleString('fa-IR')}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ const Progress = React.forwardRef<
|
|||
<span className="w-full right-0 text-sm absolute z-10 px-2 text-[#5F6284]"
|
||||
>{formatNumber(Math.ceil(value || 0 * 10) / 10)}%</span>
|
||||
<ProgressPrimitive.Indicator
|
||||
className="h-full w-full flex-1 bg-primary transition-all"
|
||||
className="h-full w-full flex-1 bg-pr-green transition-all"
|
||||
style={{ transform: `translateX(-${15 - (value || 0)}%)` }}
|
||||
/>
|
||||
</ProgressPrimitive.Root>
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ export function TabsTrigger({
|
|||
className={cn(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
isActive
|
||||
? "bg-gray-700 text-foreground shadow-sm"
|
||||
? "bg-pr-gray text-foreground shadow-sm"
|
||||
: "hover:bg-muted/50",
|
||||
className,
|
||||
)}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user