|
1 | 1 | 'use client';
|
2 | 2 |
|
3 |
| -import { Button, Tooltip } from '@mantine/core'; |
4 |
| -import { MonthPickerInput } from '@mantine/dates'; |
5 | 3 | import { useQuery } from '@tanstack/react-query';
|
6 | 4 | import { format } from 'date-fns';
|
7 | 5 | import { Session } from 'next-auth';
|
8 |
| -import { useState } from 'react'; |
9 |
| -import DataTable from '@/components/generic/data-table/DataTable'; |
10 |
| -import LoadingBox from '@/components/generic/LoadingBox'; |
11 |
| -import MonthlyCostSummary from '@/components/private-cloud/monthly-cost/MonthlyCostSummary'; |
12 |
| -import MonthlyCostChart from '@/components/private-cloud/monthly-cost/MonthyCostChart'; |
13 |
| -import { dailyCostColumns, periodicCostColumns } from '@/constants/private-cloud'; |
14 |
| -import { downloadPrivateCloudMonthlyCosts, getMonthlyCosts } from '@/services/backend/private-cloud/products'; |
15 |
| -import { DailyCostMetric, PeriodicCostMetric } from '@/types/private-cloud'; |
16 |
| -import { getDateFromYyyyMmDd } from '@/utils/js'; |
17 |
| - |
18 |
| -export default function Monthly({ licencePlate, session }: { licencePlate: string; session: Session }) { |
19 |
| - const [selectedDate, setSelectedDate] = useState<Date>(new Date()); |
20 |
| - const [downloading, setDownloading] = useState(false); |
21 |
| - |
22 |
| - const { data, isLoading, isError } = useQuery({ |
| 6 | +import { useEffect } from 'react'; |
| 7 | +import MonthlyCostChart from '@/components/private-cloud/monthly-cost/MonthlyCostChart'; |
| 8 | +import { getMonthlyCosts } from '@/services/backend/private-cloud/products'; |
| 9 | +import { MonthlyCost } from '@/types/private-cloud'; |
| 10 | + |
| 11 | +export default function Monthly({ |
| 12 | + selectedDate, |
| 13 | + licencePlate, |
| 14 | + session, |
| 15 | + onDataLoaded, |
| 16 | + forecastEnabled, |
| 17 | + onLoadingDone, |
| 18 | +}: { |
| 19 | + selectedDate: Date; |
| 20 | + licencePlate: string; |
| 21 | + session: Session; |
| 22 | + onDataLoaded: (data: MonthlyCost) => void; |
| 23 | + forecastEnabled: boolean; |
| 24 | + onLoadingDone: (isLoading: boolean) => void; |
| 25 | +}) { |
| 26 | + const { data, isLoading } = useQuery({ |
23 | 27 | queryKey: ['costItems', licencePlate, selectedDate ? format(selectedDate, 'yyyy-MM') : null],
|
24 | 28 | queryFn: () => getMonthlyCosts(licencePlate, format(selectedDate!, 'yyyy-MM')),
|
25 | 29 | enabled: !!licencePlate && !!selectedDate,
|
26 | 30 | });
|
27 | 31 |
|
| 32 | + useEffect(() => { |
| 33 | + onLoadingDone(isLoading); |
| 34 | + }, [isLoading, onLoadingDone]); |
| 35 | + |
| 36 | + useEffect(() => { |
| 37 | + if (data) { |
| 38 | + onDataLoaded(data); |
| 39 | + } |
| 40 | + }, [data, onDataLoaded]); |
| 41 | + |
28 | 42 | if (!data || !session.previews.costRecovery) {
|
29 | 43 | return null;
|
30 | 44 | }
|
31 | 45 |
|
32 |
| - const handleChange = (date: string | null) => { |
33 |
| - setSelectedDate(date ? getDateFromYyyyMmDd(date) : new Date()); |
34 |
| - }; |
35 |
| - |
36 |
| - const dailyCostData = data.days.map((day, idx) => { |
37 |
| - const { cpuToDate, storageToDate, cpuToProjected, storageToProjected } = data.dayDetails; |
38 |
| - const totalCost = cpuToDate[idx] + storageToDate[idx] + cpuToProjected[idx] + storageToProjected[idx]; |
39 |
| - |
40 |
| - return { |
41 |
| - day, |
42 |
| - dayDetails: { |
43 |
| - cpuToDate: cpuToDate[idx], |
44 |
| - storageToDate: storageToDate[idx], |
45 |
| - cpuToProjected: cpuToProjected[idx], |
46 |
| - storageToProjected: storageToProjected[idx], |
47 |
| - totalCost, |
48 |
| - }, |
49 |
| - }; |
50 |
| - }); |
51 |
| - |
52 | 46 | return (
|
53 |
| - <div> |
54 |
| - <div className="flex items-center gap-4 mb-6"> |
55 |
| - <Tooltip label="Select a month"> |
56 |
| - <MonthPickerInput |
57 |
| - placeholder="Select a month" |
58 |
| - value={selectedDate} |
59 |
| - onChange={handleChange} |
60 |
| - maw={200} |
61 |
| - clearable |
62 |
| - /> |
63 |
| - </Tooltip> |
64 |
| - |
65 |
| - {data.items.length > 0 && ( |
66 |
| - <div className="ml-auto"> |
67 |
| - <Button |
68 |
| - loading={downloading} |
69 |
| - onClick={async () => { |
70 |
| - if (!data) return; |
71 |
| - setDownloading(true); |
72 |
| - await downloadPrivateCloudMonthlyCosts(licencePlate, format(selectedDate, 'yyyy-MM')); |
73 |
| - setDownloading(false); |
74 |
| - }} |
75 |
| - > |
76 |
| - Download PDF |
77 |
| - </Button> |
78 |
| - </div> |
79 |
| - )} |
80 |
| - </div> |
81 |
| - |
82 |
| - <MonthlyCostSummary data={data} /> |
83 |
| - |
| 47 | + <> |
84 | 48 | {data.items.length > 0 && (
|
85 |
| - <div className="my-8"> |
86 |
| - <MonthlyCostChart data={{ days: data.days, dayDetails: data.dayDetails }} /> |
87 |
| - </div> |
| 49 | + <MonthlyCostChart |
| 50 | + data={{ days: data.days, dayDetails: data.dayDetails, billingPeriod: data.billingPeriod }} |
| 51 | + isForecastEnabled={forecastEnabled} |
| 52 | + /> |
88 | 53 | )}
|
89 |
| - |
90 |
| - <LoadingBox isLoading={isLoading}> |
91 |
| - <DataTable<PeriodicCostMetric> data={data.items} columns={periodicCostColumns} defaultPageSize={5} /> |
92 |
| - <DataTable<DailyCostMetric> data={dailyCostData} columns={dailyCostColumns} defaultPageSize={5} /> |
93 |
| - </LoadingBox> |
94 |
| - </div> |
| 54 | + </> |
95 | 55 | );
|
96 | 56 | }
|
0 commit comments