|
| 1 | +'use client' |
| 2 | + |
| 3 | +import { Bar, BarChart, CartesianGrid, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts' |
| 4 | +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" |
| 5 | + |
| 6 | +interface CategoryStats { |
| 7 | + totalRegisteredStudentsCount: number |
| 8 | + placedStudentsCount: number |
| 9 | + placementPercentage: number |
| 10 | + unplacedPercentage: number |
| 11 | + highestPackage: number |
| 12 | + lowestPackage: number |
| 13 | + meanPackage: number |
| 14 | + medianPackage: number |
| 15 | + modePackage: number |
| 16 | + totalOffers: number |
| 17 | + totalCompaniesOffering: number |
| 18 | +} |
| 19 | + |
| 20 | +interface CategoryWiseStats { |
| 21 | + [key: string]: CategoryStats |
| 22 | +} |
| 23 | + |
| 24 | +interface OffersByCategoryProps { |
| 25 | + viewType: 'chart' | 'table' |
| 26 | + data: CategoryWiseStats |
| 27 | +} |
| 28 | + |
| 29 | +const CustomTooltip = ({ active, payload, label }: any) => { |
| 30 | + if (active && payload && payload.length) { |
| 31 | + const stats = payload[0].payload.stats; |
| 32 | + return ( |
| 33 | + <div className="bg-white p-4 rounded-lg shadow-lg border"> |
| 34 | + <h3 className="font-bold">{label}</h3> |
| 35 | + <p>Total Registered Students: {stats.totalRegisteredStudentsCount}</p> |
| 36 | + <p>Placed Students: {stats.placedStudentsCount}</p> |
| 37 | + <p>Placement %: {stats.placementPercentage.toFixed(2)}%</p> |
| 38 | + <p>Unplaced %: {stats.unplacedPercentage.toFixed(2)}%</p> |
| 39 | + <p>Highest Package: ₹{stats.highestPackage.toFixed(2)}L</p> |
| 40 | + <p>Lowest Package: ₹{stats.lowestPackage.toFixed(2)}L</p> |
| 41 | + <p>Mean Package: ₹{stats.meanPackage.toFixed(2)}L</p> |
| 42 | + <p>Median Package: ₹{stats.medianPackage.toFixed(2)}L</p> |
| 43 | + <p>Mode Package: ₹{stats.modePackage.toFixed(2)}L</p> |
| 44 | + <p>Total Offers: {stats.totalOffers}</p> |
| 45 | + <p>Total Companies Offering: {stats.totalCompaniesOffering}</p> |
| 46 | + </div> |
| 47 | + ); |
| 48 | + } |
| 49 | + return null; |
| 50 | +}; |
| 51 | + |
| 52 | +export function OffersByCategory({ viewType, data = {} }: OffersByCategoryProps) { |
| 53 | + const transformedData = Object.entries(data).map(([course, stats]) => ({ |
| 54 | + course, |
| 55 | + placementPercentage: stats.placementPercentage, |
| 56 | + stats |
| 57 | + })); |
| 58 | + |
| 59 | + if (viewType === 'table') { |
| 60 | + return ( |
| 61 | + <Table> |
| 62 | + <TableHeader> |
| 63 | + <TableRow> |
| 64 | + <TableHead>Course</TableHead> |
| 65 | + <TableHead>Total Students</TableHead> |
| 66 | + <TableHead>Placed Students</TableHead> |
| 67 | + <TableHead>Placement %</TableHead> |
| 68 | + <TableHead>Unplaced %</TableHead> |
| 69 | + <TableHead>Highest Package (₹L)</TableHead> |
| 70 | + <TableHead>Lowest Package (₹L)</TableHead> |
| 71 | + <TableHead>Mean Package (₹L)</TableHead> |
| 72 | + <TableHead>Median Package (₹L)</TableHead> |
| 73 | + <TableHead>Mode Package (₹L)</TableHead> |
| 74 | + <TableHead>Total Offers</TableHead> |
| 75 | + <TableHead>Companies Offering</TableHead> |
| 76 | + </TableRow> |
| 77 | + </TableHeader> |
| 78 | + <TableBody> |
| 79 | + {Object.entries(data).map(([course, stats]) => ( |
| 80 | + <TableRow key={course}> |
| 81 | + <TableCell>{course}</TableCell> |
| 82 | + <TableCell>{stats.totalRegisteredStudentsCount}</TableCell> |
| 83 | + <TableCell>{stats.placedStudentsCount}</TableCell> |
| 84 | + <TableCell>{stats.placementPercentage.toFixed(2)}%</TableCell> |
| 85 | + <TableCell>{stats.unplacedPercentage.toFixed(2)}%</TableCell> |
| 86 | + <TableCell>{stats.highestPackage.toFixed(2)}</TableCell> |
| 87 | + <TableCell>{stats.lowestPackage.toFixed(2)}</TableCell> |
| 88 | + <TableCell>{stats.meanPackage.toFixed(2)}</TableCell> |
| 89 | + <TableCell>{stats.medianPackage.toFixed(2)}</TableCell> |
| 90 | + <TableCell>{stats.modePackage.toFixed(2)}</TableCell> |
| 91 | + <TableCell>{stats.totalOffers}</TableCell> |
| 92 | + <TableCell>{stats.totalCompaniesOffering}</TableCell> |
| 93 | + </TableRow> |
| 94 | + ))} |
| 95 | + </TableBody> |
| 96 | + </Table> |
| 97 | + ) |
| 98 | + } |
| 99 | + |
| 100 | + return ( |
| 101 | + <ResponsiveContainer width="100%" height={400}> |
| 102 | + <BarChart |
| 103 | + data={transformedData} |
| 104 | + margin={{ |
| 105 | + top: 20, |
| 106 | + right: 30, |
| 107 | + left: 20, |
| 108 | + bottom: 100 |
| 109 | + }} |
| 110 | + > |
| 111 | + <CartesianGrid strokeDasharray="3 3" /> |
| 112 | + <XAxis |
| 113 | + dataKey="course" |
| 114 | + interval={0} |
| 115 | + angle={-45} |
| 116 | + textAnchor="end" |
| 117 | + height={100} |
| 118 | + tick={{ |
| 119 | + dx: -8, |
| 120 | + dy: 10, |
| 121 | + fontSize: 12 |
| 122 | + }} |
| 123 | + /> |
| 124 | + <YAxis |
| 125 | + label={{ |
| 126 | + value: 'Placement %', |
| 127 | + angle: -90, |
| 128 | + position: 'insideLeft', |
| 129 | + style: { textAnchor: 'middle' } |
| 130 | + }} |
| 131 | + /> |
| 132 | + <Tooltip content={<CustomTooltip />} /> |
| 133 | + <Bar |
| 134 | + dataKey="placementPercentage" |
| 135 | + fill="#82ca9d" |
| 136 | + name="Placement %" |
| 137 | + /> |
| 138 | + </BarChart> |
| 139 | + </ResponsiveContainer> |
| 140 | + ) |
| 141 | +} |
| 142 | + |
0 commit comments