MIF_E31220954/frontend/src/pages/LandingPage/ViewGrafik.jsx

277 lines
11 KiB
JavaScript

import React, { useState, useEffect } from "react";
import { format, parseISO, isBefore, isAfter, startOfDay } from "date-fns";
import { CalendarIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
CartesianGrid,
Line,
LineChart,
XAxis,
YAxis,
Tooltip,
ResponsiveContainer,
Legend
} from "recharts";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area'
import axios from 'axios';
import { API_URL } from "../../helpers/networt";
import { useToast } from '@/hooks/use-toast';
const ViewGrafik = ({ date, setDate, dataYAxis, setDataYAxis, priceType, setPriceType, chartData, setChartData, setTabelDataAktual, setTabelDataPredict }) => {
const { toast } = useToast();
const [dateTerbaru, setDateTerbaru] = useState(null);
const [dateTerlama, setDateTerlama] = useState(null);
const oldestDate = dateTerlama ? parseISO(dateTerlama) : null;
const latestDate = dateTerbaru ? parseISO(dateTerbaru) : null;
const [tempPriceType, setTempPriceType] = useState("");
const handleDateChange = (selectedDate) => setDate(selectedDate);
const handlePriceTypeChange = (value) => setTempPriceType(value);
const fetchDataDate = async () => {
try {
const response = await axios.get(`${API_URL}/predict/date`);
console.log(response.data.tanggal_old)
setDateTerbaru(response.data.tanggal_new)
setDateTerlama(response.data.tanggal_old)
} catch (error) {
console.error("Error fetching data", error);
}
}
useEffect(() => {
fetchDataDate();
}, []);
const fetchData = async () => {
const formattedDate = format(date, "yyyy-MM-dd");
if (!date && !tempPriceType) {
setTabelDataAktual([]);
setTabelDataPredict([]);
setPriceType("");
setChartData([]);
setDataYAxis([11000, 15000]);
toast({
description: "tanggal dan harga harus di isi!",
variant: "destructive",
});
return;
}
if (!date) {
setTabelDataAktual([]);
setTabelDataPredict([]);
setPriceType("");
setChartData([]);
setDataYAxis([11000, 15000]);
toast({
description: "Pilih tanggal terlebih dahulu!",
variant: "destructive",
});
return;
}
if (formattedDate==dateTerbaru && tempPriceType=="all") {
setTabelDataAktual([]);
setTabelDataPredict([]);
setPriceType("");
setChartData([]);
setDataYAxis([11000, 15000]);
toast({
description: "tanggal ini hanya ada data prediksi",
variant: "destructive",
});
return;
}
if (formattedDate==dateTerbaru && tempPriceType=="actual") {
setTabelDataAktual([]);
setTabelDataPredict([]);
setPriceType("");
setChartData([]);
setDataYAxis([11000, 15000]);
toast({
description: "tanggal ini hanya ada data prediksi",
variant: "destructive",
});
return;
}
if (!tempPriceType) {
setTabelDataAktual([]);
setTabelDataPredict([]);
setPriceType("");
setChartData([]);
setDataYAxis([11000, 15000]);
toast({
description: "Pilih harga terlebih dahulu!",
variant: "destructive",
});
return;
}
try {
const response = await axios.get(`${API_URL}/predict/history?tanggal=${formattedDate}&data_type=${tempPriceType}`);
const formattedData = response.data.dataGrafik.map(item => ({
date: item.tanggal,
actual: item.harga_aktual,
predicted: item.harga_prediksi
}));
setPriceType(tempPriceType);
setDataYAxis(response.data.YAxis);
setChartData(formattedData);
setTabelDataAktual(response.data.dataTableAktual);
setTabelDataPredict(response.data.dataTablePrediksi)
toast({
description: "Data berhasil di tampilkan",
});
} catch (error) {
console.error("Error fetching data", error);
}
};
return (
<div className=' border rounded-2xl bg-[#ffffff81] shadow-lg'>
<div className='bg-white py-3 px-5 rounded-t-2xl text-center sm:text-left'>
<h1 className='text-sm font-bold '>Grafik Harga Tomat Konsumen dari Tanggal Terpilih</h1>
</div>
<div className='grid gap-6 mt-6 px-4 sm:px-10'>
<div className='flex flex-col sm:flex-row sm:justify-between gap-4'>
<div className='flex flex-col sm:flex-row gap-4'>
<div className='flex items-center gap-2 '>
<p className="font-semibold">Tanggal:</p>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" className="w-full sm:w-[240px] flex items-center justify-start gap-2">
<CalendarIcon className="h-4 w-4" />
{date ? format(date, "yyyy-MM-dd") : <span>Pilih tanggal</span>}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={date}
onSelect={handleDateChange}
initialFocus
defaultMonth={latestDate}
disabled={(day) =>
// Nonaktifkan tanggal SETELAH tanggal terbaru
(latestDate && isAfter(startOfDay(day), latestDate)) ||
// Nonaktifkan tanggal SEBELUM tanggal terlama
(oldestDate && isBefore(startOfDay(day), oldestDate))
}
/>
</PopoverContent>
</Popover>
</div>
<div className='flex items-center gap-6 sm:gap-2'>
<p className="font-semibold">Harga:</p>
<Select onValueChange={handlePriceTypeChange}>
<SelectTrigger className="w-full sm:w-[180px] bg-white">
<SelectValue placeholder="Pilih" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="all">Semua</SelectItem>
<SelectItem value="actual">Aktual</SelectItem>
<SelectItem value="predicted">Prediksi</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
</div>
<Button className='bg-gradient-to-r from-[#402412a8] to-[#9a070790]' onClick={fetchData} >Tampilkan</Button>
</div>
<div className='mb-4'>
<Card>
<CardHeader>
<CardTitle>
{priceType === "all" ? "Harga Aktual vs Prediksi" : priceType === "actual" ? "Harga Aktual" : "Harga Prediksi"}
</CardTitle>
<CardDescription>Data harga tomat</CardDescription>
</CardHeader>
<CardContent>
<ScrollArea>
<ResponsiveContainer width="100%" height={300}>
<LineChart data={chartData} margin={{ left: 12, right: 12 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="date" tickLine={false} axisLine={false} tickMargin={8} />
<YAxis domain={dataYAxis} tickFormatter={(value) => `Rp${value}`} />
<Tooltip formatter={(value) => `Rp${value}`} />
{/* <Legend/> */}
{priceType !== "predicted" && (
<Line dataKey="actual" type="monotone" stroke="#ff7300" strokeWidth={2} dot={false} name="Harga Aktual" />
)}
{priceType !== "actual" && (
<Line dataKey="predicted" type="monotone" stroke="#387ef5" strokeWidth={2} dot={false} name="Harga Prediksi" />
)}
</LineChart>
</ResponsiveContainer>
<ScrollBar orientation="horizontal" />
</ScrollArea>
</CardContent>
<CardFooter className="flex flex-col text-sm">
<h5>Tanggal</h5>
<div className='flex flex-wrap gap-4'>
{priceType !== "predicted" && (
<div className='flex items-center gap-2'>
<p>Harga Aktual</p>
<span className='w-4 h-4 bg-[#ff7300] block' />
</div>
)}
{priceType !== "actual" && (
<div className='flex items-center gap-2'>
<p>Harga Prediksi</p>
<span className='w-4 h-4 bg-[#387ef5] block' />
</div>
)}
</div>
</CardFooter>
</Card>
</div>
</div>
</div>
);
};
export default ViewGrafik;