Apply full refactor updates plus pipeline/email UX confirmations
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m33s
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m33s
This commit is contained in:
@@ -1,153 +1,153 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
BarChart,
|
||||
Bar,
|
||||
XAxis,
|
||||
YAxis,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
ResponsiveContainer,
|
||||
Legend,
|
||||
} from 'recharts'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
|
||||
interface StageComparison {
|
||||
stageId: string
|
||||
stageName: string
|
||||
projectCount: number
|
||||
evaluationCount: number
|
||||
completionRate: number
|
||||
averageScore: number | null
|
||||
scoreDistribution: { score: number; count: number }[]
|
||||
}
|
||||
|
||||
interface CrossStageComparisonProps {
|
||||
data: StageComparison[]
|
||||
}
|
||||
|
||||
const STAGE_COLORS = ['#053d57', '#de0f1e', '#557f8c', '#f38a52', '#6ad82f']
|
||||
|
||||
export function CrossStageComparisonChart({ data }: CrossStageComparisonProps) {
|
||||
// Prepare comparison data
|
||||
const comparisonData = data.map((stage, i) => ({
|
||||
name: stage.stageName.length > 20 ? stage.stageName.slice(0, 20) + '...' : stage.stageName,
|
||||
projects: stage.projectCount,
|
||||
evaluations: stage.evaluationCount,
|
||||
completionRate: stage.completionRate,
|
||||
avgScore: stage.averageScore ? parseFloat(stage.averageScore.toFixed(2)) : 0,
|
||||
color: STAGE_COLORS[i % STAGE_COLORS.length],
|
||||
}))
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Metrics Comparison */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Stage Metrics Comparison</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[350px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart
|
||||
data={comparisonData}
|
||||
margin={{ top: 20, right: 30, bottom: 60, left: 20 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
angle={-25}
|
||||
textAnchor="end"
|
||||
height={60}
|
||||
tick={{ fontSize: 12 }}
|
||||
/>
|
||||
<YAxis />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'hsl(var(--card))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
borderRadius: '6px',
|
||||
}}
|
||||
/>
|
||||
<Legend />
|
||||
<Bar dataKey="projects" name="Projects" fill="#053d57" radius={[4, 4, 0, 0]} />
|
||||
<Bar dataKey="evaluations" name="Evaluations" fill="#557f8c" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Completion & Score Comparison */}
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Completion Rate by Stage</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[300px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart
|
||||
data={comparisonData}
|
||||
margin={{ top: 20, right: 20, bottom: 60, left: 20 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
angle={-25}
|
||||
textAnchor="end"
|
||||
height={60}
|
||||
tick={{ fontSize: 12 }}
|
||||
/>
|
||||
<YAxis domain={[0, 100]} unit="%" />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'hsl(var(--card))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
borderRadius: '6px',
|
||||
}}
|
||||
/>
|
||||
<Bar dataKey="completionRate" name="Completion %" fill="#6ad82f" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Average Score by Stage</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[300px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart
|
||||
data={comparisonData}
|
||||
margin={{ top: 20, right: 20, bottom: 60, left: 20 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
angle={-25}
|
||||
textAnchor="end"
|
||||
height={60}
|
||||
tick={{ fontSize: 12 }}
|
||||
/>
|
||||
<YAxis domain={[0, 10]} />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'hsl(var(--card))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
borderRadius: '6px',
|
||||
}}
|
||||
/>
|
||||
<Bar dataKey="avgScore" name="Avg Score" fill="#de0f1e" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
'use client'
|
||||
|
||||
import {
|
||||
BarChart,
|
||||
Bar,
|
||||
XAxis,
|
||||
YAxis,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
ResponsiveContainer,
|
||||
Legend,
|
||||
} from 'recharts'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
|
||||
interface StageComparison {
|
||||
stageId: string
|
||||
stageName: string
|
||||
projectCount: number
|
||||
evaluationCount: number
|
||||
completionRate: number
|
||||
averageScore: number | null
|
||||
scoreDistribution: { score: number; count: number }[]
|
||||
}
|
||||
|
||||
interface CrossStageComparisonProps {
|
||||
data: StageComparison[]
|
||||
}
|
||||
|
||||
const STAGE_COLORS = ['#053d57', '#de0f1e', '#557f8c', '#f38a52', '#6ad82f']
|
||||
|
||||
export function CrossStageComparisonChart({ data }: CrossStageComparisonProps) {
|
||||
// Prepare comparison data
|
||||
const comparisonData = data.map((stage, i) => ({
|
||||
name: stage.stageName.length > 20 ? stage.stageName.slice(0, 20) + '...' : stage.stageName,
|
||||
projects: stage.projectCount,
|
||||
evaluations: stage.evaluationCount,
|
||||
completionRate: stage.completionRate,
|
||||
avgScore: stage.averageScore ? parseFloat(stage.averageScore.toFixed(2)) : 0,
|
||||
color: STAGE_COLORS[i % STAGE_COLORS.length],
|
||||
}))
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Metrics Comparison */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Stage Metrics Comparison</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[350px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart
|
||||
data={comparisonData}
|
||||
margin={{ top: 20, right: 30, bottom: 60, left: 20 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
angle={-25}
|
||||
textAnchor="end"
|
||||
height={60}
|
||||
tick={{ fontSize: 12 }}
|
||||
/>
|
||||
<YAxis />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'hsl(var(--card))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
borderRadius: '6px',
|
||||
}}
|
||||
/>
|
||||
<Legend />
|
||||
<Bar dataKey="projects" name="Projects" fill="#053d57" radius={[4, 4, 0, 0]} />
|
||||
<Bar dataKey="evaluations" name="Evaluations" fill="#557f8c" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Completion & Score Comparison */}
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Completion Rate by Stage</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[300px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart
|
||||
data={comparisonData}
|
||||
margin={{ top: 20, right: 20, bottom: 60, left: 20 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
angle={-25}
|
||||
textAnchor="end"
|
||||
height={60}
|
||||
tick={{ fontSize: 12 }}
|
||||
/>
|
||||
<YAxis domain={[0, 100]} unit="%" />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'hsl(var(--card))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
borderRadius: '6px',
|
||||
}}
|
||||
/>
|
||||
<Bar dataKey="completionRate" name="Completion %" fill="#6ad82f" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Average Score by Stage</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[300px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart
|
||||
data={comparisonData}
|
||||
margin={{ top: 20, right: 20, bottom: 60, left: 20 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
angle={-25}
|
||||
textAnchor="end"
|
||||
height={60}
|
||||
tick={{ fontSize: 12 }}
|
||||
/>
|
||||
<YAxis domain={[0, 10]} />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'hsl(var(--card))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
borderRadius: '6px',
|
||||
}}
|
||||
/>
|
||||
<Bar dataKey="avgScore" name="Avg Score" fill="#de0f1e" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user