From e39fab0de501379210ce80c0c5d24e2fb5717b0c Mon Sep 17 00:00:00 2001 From: Nguyen Xuan Nhan Date: Thu, 6 Jun 2024 01:15:47 +0700 Subject: [PATCH] style: add revenue monthly by year chart dashboard --- .../Queries/RevenueYear/RevenueYearHandler.cs | 17 ++--- .../app/(dashboard)/dashboard/page.tsx | 4 +- .../components/custom/best-seller.tsx | 2 +- ui/backoffice/components/custom/overview.tsx | 63 +++---------------- .../features/report/report.service.ts | 8 +++ ui/backoffice/features/report/report.type.ts | 11 ++++ .../report/useGetDiffRevenueByMonth.ts | 3 +- .../features/report/useGetGrownCustomer.ts | 3 +- .../features/report/useGetOrderGrownByDay.ts | 3 +- .../features/report/useGetRevenueByYear.ts | 13 ++++ .../features/report/useGetTodayRevenue.ts | 3 +- 11 files changed, 60 insertions(+), 70 deletions(-) create mode 100644 ui/backoffice/features/report/useGetRevenueByYear.ts diff --git a/src/RookieShop.Application/Reports/Queries/RevenueYear/RevenueYearHandler.cs b/src/RookieShop.Application/Reports/Queries/RevenueYear/RevenueYearHandler.cs index 1ba6ebf..20684f3 100644 --- a/src/RookieShop.Application/Reports/Queries/RevenueYear/RevenueYearHandler.cs +++ b/src/RookieShop.Application/Reports/Queries/RevenueYear/RevenueYearHandler.cs @@ -15,22 +15,23 @@ public sealed class RevenueYearHandler(IDatabaseFactory factory) const string sql = $""" WITH monthly_revenue AS ( SELECT - to_char(o.created_date, 'Mon') AS month, + to_char(o.created_date, 'Mon') AS month_name, SUM(od.price * od.quantity) AS revenue FROM orders o JOIN order_details od ON o.id = od.order_id - WHERE EXTRACT(YEAR FROM o.created_date) = @year - GROUP BY to_char(o.created_date, 'Mon') + WHERE EXTRACT(YEAR FROM o.created_date) = @Year + GROUP BY to_char(o.created_date, 'Mon') ) SELECT month_names.month AS {nameof(RevenueYearDto.Month)}, COALESCE(monthly_revenue.revenue, 0) AS {nameof(RevenueYearDto.Revenue)} FROM ( - VALUES ('Jan'), ('Feb'), ('Mar'), ('Apr'), ('May'), ('Jun'), - ('Jul'), ('Aug'), ('Sep'), ('Oct'), ('Nov'), ('Dec') - ) AS month_names(month) - LEFT JOIN monthly_revenue ON month_names.month = monthly_revenue.month - ORDER BY month_names.month; + VALUES + (1,'Jan'), (2,'Feb'), (3,'Mar'), (4,'Apr'), (5,'May'), (6,'Jun'), + (7,'Jul'), (8,'Aug'), (9,'Sep'), (10,'Oct'), (11,'Nov'), (12,'Dec') + ) AS month_names(month_number, month) + LEFT JOIN monthly_revenue ON month_names.month = monthly_revenue.month_name + ORDER BY month_names.month_number; """; using var conn = factory.GetOpenConnection(); diff --git a/ui/backoffice/app/(dashboard)/dashboard/page.tsx b/ui/backoffice/app/(dashboard)/dashboard/page.tsx index 16553b2..7d2aef3 100644 --- a/ui/backoffice/app/(dashboard)/dashboard/page.tsx +++ b/ui/backoffice/app/(dashboard)/dashboard/page.tsx @@ -14,9 +14,9 @@ import { } from "@/components/ui/card" import { ScrollArea } from "@/components/ui/scroll-area" import { Tabs, TabsContent } from "@/components/ui/tabs" -import { BestSeller } from "@/components/custom/best-seller" +import BestSeller from "@/components/custom/best-seller" import { Icons } from "@/components/custom/icons" -import { Overview } from "@/components/custom/overview" +import Overview from "@/components/custom/overview" export default function Dashboard() { const { data: DiffRevenueByMonth } = useGetDiffRevenueByMonth({ diff --git a/ui/backoffice/components/custom/best-seller.tsx b/ui/backoffice/components/custom/best-seller.tsx index 075462d..3833f95 100644 --- a/ui/backoffice/components/custom/best-seller.tsx +++ b/ui/backoffice/components/custom/best-seller.tsx @@ -5,7 +5,7 @@ import useGetBestSellerProducts from "@/features/report/useGetBestSellerProducts import { Avatar, AvatarFallback } from "@/components/ui/avatar" -export function BestSeller() { +export default function BestSeller() { const { data } = useGetBestSellerProducts({ top: 5 }) return (
diff --git a/ui/backoffice/components/custom/overview.tsx b/ui/backoffice/components/custom/overview.tsx index 4c52428..03cb5c4 100644 --- a/ui/backoffice/components/custom/overview.tsx +++ b/ui/backoffice/components/custom/overview.tsx @@ -1,64 +1,17 @@ "use client" +import useGetRevenueByYear from "@/features/report/useGetRevenueByYear" import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis } from "recharts" -const data = [ - { - name: "Jan", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Feb", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Mar", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Apr", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "May", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Jun", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Jul", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Aug", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Sep", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Oct", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Nov", - total: Math.floor(Math.random() * 5000) + 1000, - }, - { - name: "Dec", - total: Math.floor(Math.random() * 5000) + 1000, - }, -] - -export function Overview() { +export default function Overview() { + const { data: RevenueByYear } = useGetRevenueByYear({ + year: new Date().getFullYear(), + }) return ( - + `$${value}`} /> - + ) diff --git a/ui/backoffice/features/report/report.service.ts b/ui/backoffice/features/report/report.service.ts index 382d1c8..45fde42 100644 --- a/ui/backoffice/features/report/report.service.ts +++ b/ui/backoffice/features/report/report.service.ts @@ -9,6 +9,8 @@ import { GrownCustomer, GrownCustomerParams, OrderGrownByDay, + RevenueByYear, + RevenueByYearParams, TodayRevenue, } from "./report.type" @@ -48,6 +50,12 @@ class ReportService extends HttpService { getOrderGrownByDay(): Promise { return this.get("/reports/orders-grown-by-day") } + + getRevenueByYear( + options: Partial + ): Promise { + return this.get(`/reports/revenue-year?${buildQueryString(options)}`) + } } export default new ReportService() diff --git a/ui/backoffice/features/report/report.type.ts b/ui/backoffice/features/report/report.type.ts index c41ff47..0f8a54f 100644 --- a/ui/backoffice/features/report/report.type.ts +++ b/ui/backoffice/features/report/report.type.ts @@ -58,3 +58,14 @@ export type OrderGrownByDay = { growthPercentage: number currentDate: Date } + +// -- Revenue By Year Report + +export type RevenueByYear = { + month: string + revenue: number +} + +export type RevenueByYearParams = { + year: number +} diff --git a/ui/backoffice/features/report/useGetDiffRevenueByMonth.ts b/ui/backoffice/features/report/useGetDiffRevenueByMonth.ts index 566f439..ebb68b6 100644 --- a/ui/backoffice/features/report/useGetDiffRevenueByMonth.ts +++ b/ui/backoffice/features/report/useGetDiffRevenueByMonth.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query" +import { keepPreviousData, useQuery } from "@tanstack/react-query" import reportService from "./report.service" import { DiffRevenueByMonthParams } from "./report.type" @@ -9,5 +9,6 @@ export default function useGetDiffRevenueByMonth( return useQuery({ queryKey: ["diff-revenue-by-month"], queryFn: () => reportService.getDiffRevenueByMonth(options), + placeholderData: keepPreviousData, }) } diff --git a/ui/backoffice/features/report/useGetGrownCustomer.ts b/ui/backoffice/features/report/useGetGrownCustomer.ts index 02f6f2d..dfb278a 100644 --- a/ui/backoffice/features/report/useGetGrownCustomer.ts +++ b/ui/backoffice/features/report/useGetGrownCustomer.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query" +import { keepPreviousData, useQuery } from "@tanstack/react-query" import reportService from "./report.service" import { GrownCustomerParams } from "./report.type" @@ -9,5 +9,6 @@ export default function useGetGrownCustomer( return useQuery({ queryKey: ["grown-customer"], queryFn: () => reportService.getGrownCustomer(options), + placeholderData: keepPreviousData, }) } diff --git a/ui/backoffice/features/report/useGetOrderGrownByDay.ts b/ui/backoffice/features/report/useGetOrderGrownByDay.ts index 3de3bdf..23c446b 100644 --- a/ui/backoffice/features/report/useGetOrderGrownByDay.ts +++ b/ui/backoffice/features/report/useGetOrderGrownByDay.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query" +import { keepPreviousData, useQuery } from "@tanstack/react-query" import reportService from "./report.service" @@ -6,5 +6,6 @@ export default function useGetOrderGrownByDay() { return useQuery({ queryKey: ["order-grown-by-day"], queryFn: () => reportService.getOrderGrownByDay(), + placeholderData: keepPreviousData, }) } diff --git a/ui/backoffice/features/report/useGetRevenueByYear.ts b/ui/backoffice/features/report/useGetRevenueByYear.ts new file mode 100644 index 0000000..ce76cc1 --- /dev/null +++ b/ui/backoffice/features/report/useGetRevenueByYear.ts @@ -0,0 +1,13 @@ +import { useQuery } from "@tanstack/react-query" + +import reportService from "./report.service" +import { RevenueByYearParams } from "./report.type" + +export default function useGetRevenueByYear( + options: Partial +) { + return useQuery({ + queryKey: ["revenue-by-year", options], + queryFn: () => reportService.getRevenueByYear(options), + }) +} diff --git a/ui/backoffice/features/report/useGetTodayRevenue.ts b/ui/backoffice/features/report/useGetTodayRevenue.ts index 648a4fa..88c975c 100644 --- a/ui/backoffice/features/report/useGetTodayRevenue.ts +++ b/ui/backoffice/features/report/useGetTodayRevenue.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query" +import { keepPreviousData, useQuery } from "@tanstack/react-query" import reportService from "./report.service" @@ -6,5 +6,6 @@ export default function useGetTodayRevenue() { return useQuery({ queryKey: ["total-revenue-by-day"], queryFn: () => reportService.getTodayRevenue(), + placeholderData: keepPreviousData, }) }