Skip to content

Commit

Permalink
Merge pull request #144 from sgcarstrends/141-add-coe-pages
Browse files Browse the repository at this point in the history
Add COE page
  • Loading branch information
ruchernchong authored Oct 12, 2024
2 parents 29ff95d + 36515d8 commit 728db75
Show file tree
Hide file tree
Showing 20 changed files with 1,314 additions and 1,308 deletions.
37 changes: 37 additions & 0 deletions app/coe/(prices)/TrendTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use client";

import { useMemo } from "react";
import { columns } from "@/app/coe/(prices)/columns";
import useStore from "@/app/store";
import { DataTable } from "@/components/ui/data-table";
import type { COEResult } from "@/types";

interface Props {
coeResults: COEResult[];
}

export const TrendTable = ({ coeResults }: Props) => {
const categories = useStore(({ categories }) => categories);

const sortCOEResults = (a: COEResult, b: COEResult) => {
if (a.month !== b.month) {
return b.month.localeCompare(a.month);
}

if (a.bidding_no !== b.bidding_no) {
return b.bidding_no - a.bidding_no;
}

return a.vehicle_class.localeCompare(b.vehicle_class);
};

const sortedData = useMemo(
() =>
coeResults
.filter(({ vehicle_class }) => categories[vehicle_class])
.sort(sortCOEResults),
[categories, coeResults],
);

return <DataTable columns={columns} data={sortedData} />;
};
67 changes: 67 additions & 0 deletions app/coe/(prices)/columns.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"use client";

import { ArrowUpDown } from "lucide-react";
import { Button } from "@/components/ui/button";
import { formatOrdinal } from "@/utils/formatOrdinal";
import type { COEResult } from "@/types";
import type { ColumnDef } from "@tanstack/react-table";

const formatCurrency = (value: any) =>
Intl.NumberFormat("en-SG", {
style: "currency",
currency: "SGD",
minimumFractionDigits: 0,
}).format(value);

// const formatPercent = (value: any) =>
// Intl.NumberFormat("en-SG", { style: "percent" }).format(value);

export const columns: ColumnDef<COEResult>[] = [
{
accessorKey: "month",
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Month
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
),
},
{
accessorKey: "vehicle_class",
header: "Category",
cell: ({ row }) =>
row.getValue<string>("vehicle_class").split("Category")[1],
},
{
accessorKey: "premium",
header: "Quota Premium (S$)",
cell: ({ row }) => `S${formatCurrency(row.getValue<number>("premium"))}`,
},
{
accessorKey: "bidding_no",
header: "Bidding Round",
cell: ({ row }) =>
`${formatOrdinal(row.getValue<number>("bidding_no"))} Round`,
},
// { accessorKey: "quota", header: "Quota" },
// { accessorKey: "bids_received", header: "Bids Received" },
// {
// accessorKey: "bids_success",
// header: "Bids Success",
// cell: ({ row }) =>
// `${row.getValue("bids_success") as number} (${formatPercent((row.getValue("bids_success") as number) / (row.getValue("bids_received") as number))})`,
// },
// {
// accessorKey: "oversubscribed",
// header: "Oversubscribed (%)",
// cell: ({ row }) =>
// formatPercent(
// (row.getValue("bids_received") as number) /
// (row.getValue("quota") as number) -
// 1,
// ),
// },
];
72 changes: 72 additions & 0 deletions app/coe/(prices)/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { TrendTable } from "@/app/coe/(prices)/TrendTable";
import { COECategories } from "@/components/COECategories";
import { COEPremiumChart } from "@/components/COEPremiumChart";
import Typography from "@/components/Typography";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { API_URL } from "@/config";
import { type COEBiddingResult, type COEResult, RevalidateTags } from "@/types";
import { fetchApi } from "@/utils/fetchApi";

const COEPricesPage = async () => {
const params = new URLSearchParams();
params.append("sort", "month");
params.append("orderBy", "asc");
const queryString = params.toString();

const coeResults = await fetchApi<COEResult[]>(
`${API_URL}/coe?${queryString}`,
{ next: { tags: [RevalidateTags.COE] } },
);

const groupedData = coeResults.reduce<COEBiddingResult[]>(
(acc: any, item) => {
const key = `${item.month}-${item.bidding_no}`;

if (!acc[key]) {
acc[key] = {
month: item.month,
biddingNo: item.bidding_no,
};
}
acc[key][item.vehicle_class] = item.premium;

return acc;
},
[],
);

const data: COEBiddingResult[] = Object.values(groupedData);

return (
<div className="flex flex-col gap-y-8">
<Typography.H1>COE Results</Typography.H1>
<div className="grid gap-4 lg:grid-cols-12">
<div className="grid grid-cols-1 gap-4 lg:col-span-8">
<COEPremiumChart data={data} />
</div>
<div className="grid grid-cols-1 gap-4 lg:col-span-4">
<COECategories />
</div>
</div>
<Card>
<CardHeader>
<CardTitle>Overview</CardTitle>
<CardDescription>
Showing the last 12 months of historical trends
</CardDescription>
</CardHeader>
<CardContent>
<TrendTable coeResults={coeResults} />
</CardContent>
</Card>
</div>
);
};

export default COEPricesPage;
101 changes: 0 additions & 101 deletions app/coe/page.tsx

This file was deleted.

49 changes: 0 additions & 49 deletions app/coe/prices/page.tsx

This file was deleted.

11 changes: 0 additions & 11 deletions app/components/CarInfographic.tsx

This file was deleted.

24 changes: 12 additions & 12 deletions app/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Facebook, Github, Instagram, Linkedin, Twitter } from "lucide-react";
import { BrandLogo } from "@/components/BrandLogo";
import { ComingSoon } from "@/components/ComingSoon";
import { Separator } from "@/components/ui/separator";
import { FUEL_TYPE_LINKS, VEHICLE_TYPE_LINKS } from "@/config";
import { COE_LINKS, FUEL_TYPE_LINKS, VEHICLE_TYPE_LINKS } from "@/config";
import type { LinkItem } from "@/types";

interface FooterLink {
Expand Down Expand Up @@ -145,24 +145,24 @@ export const Footer = () => {
};

const footerLinks: FooterLink[] = [
{
title: "Monthly",
links: [
{ label: "Cars", href: "/cars" },
{ label: "COE", href: "/coe", comingSoon: true },
],
},
// {
// title: "Monthly",
// links: [
// { label: "Cars", href: "/cars" },
// { label: "COE", href: "/coe" },
// ],
// },
{
title: "Fuel Types",
links: FUEL_TYPE_LINKS,
},
{ title: "Vehicle Types", links: VEHICLE_TYPE_LINKS },
{
title: "COE",
links: COE_LINKS,
},
// TODO: Coming Soon!
// {
// title: "COE",
// links: coeLinks,
// },
// {
// title: "Resources",
// links: [
// { href: "/about", label: "About" },
Expand Down
Loading

0 comments on commit 728db75

Please sign in to comment.