Untitled
unknown
plain_text
a year ago
15 kB
3
Indexable
"use client"; import React, { useState, useEffect } from "react"; import { Line } from "react-chartjs-2"; import moment from "moment-timezone"; import Image from "next/image"; import { useRouter } from "next/navigation"; import zoomPlugin from 'chartjs-plugin-zoom'; import { Chart, registerables } from 'chart.js'; import { querykWh, kWhData, RangeTime } from "@/app/lib/influxQueries"; import { Types } from "@/app/types"; import dynamic from "next/dynamic"; import { useAuth } from "@/app/Auth/AuthContext"; import { getDevices } from "@/app/api/api"; const Dropdown = dynamic(()=>import("@/app/(dashboard)/dashboard/dropdown")); Chart.register(...registerables, zoomPlugin); interface Props { allDevices: Types.Device[]; deviceId:string | null; devicePhase: string | null dayId:string | null; } // const devices: { [key: string]: number } = { // "0": 2, // "1": 2, // "215616591345044": 3, // }; const IndexPage: React.FC<Props> = ({ allDevices, deviceId, devicePhase, dayId }: Props) => { const [devices, setDevices] = useState<Types.Device[]>([]); const [activeDevice, setActiveDevice] = useState<string>(deviceId ?? "0"); const [activeDevicePhase, setActiveDevicePhase] = useState<number>(devicePhase === "Single Phase" ? 2 : 3); const [killoWattData, setKilloWattData] = useState<kWhData | null>(null); const [loading, setLoading] = useState(false); const [selectedDuration, setSelectedDuration] = useState<string>(dayId ?? "-1d"); const [filteredGroupNames, setFilteredGroupNames] = useState<string[]>([]); const [filteredVendorNames, setFilteredVendorNames] = useState<string[]>([]); const [selectedGroup, setSelectedGroup] = useState<string | null>(null); const [selectedVendor, setSelectedVendor] = useState<string | null>(null); const [selectedDevice, setSelectedDevice] = useState<string | null>(null); const [selectedDay, setSelectedDay] = useState<string | null>(null); const [selectedInterval, setSelectedInterval] = useState<string | null>(null); const [deviceNames, setDeviceNames] = useState<string[]>([]); const [filter, setFilter] = useState<boolean>(false); const [groupNames, setGroupNames] = useState<string[]>([]); const [vendorNames, setVendorNames] = useState<string[]>([]); const [deviceCount, setDeviceCount] = useState(0); const [deviceIds, setDeviceIds] = useState<string[]>([]); const router = useRouter(); const { token, role, name, profilePicture } = useAuth(); const [activeDevicesCount, setActiveDevicesCount] = useState(0); const [inactiveDevicesCount, setInactiveDevicesCount] = useState(0); const [error, setError] = useState<string | null>(null); useEffect(() => { if (!token) { router.push("/login"); return; } let maintoken: string; try { const jsonObject = JSON.parse(token); maintoken = jsonObject.token; } catch (err) { router.push("/login"); return; } const loadCustomers = async () => { try { const data: Types.Device[] = await getDevices(maintoken); setDevices(data); const uniqueGroupNames = Array.from( new Set(data.map((device) => device.group?.groupName).filter(Boolean)) ); const uniqueVendorNames = Array.from( new Set(data.map((device) => device.vendor?.vendorName).filter(Boolean)) ); const uniqueDeviceNames = Array.from( new Set(data.map((device) => device.deviceName)) ); const uniqueId = Array.from( new Set(data.map((device) => device.deviceId)) ); setGroupNames(uniqueGroupNames); setVendorNames(uniqueVendorNames); setDeviceNames(uniqueDeviceNames); setDeviceIds(uniqueId); const totalDevices = data.length; setDeviceCount(totalDevices); const activeDevices = data.filter((device) => device.isActive).length; setActiveDevicesCount(activeDevices); const inactiveDevices = data.filter( (device) => !device.isActive ).length; setInactiveDevicesCount(inactiveDevices); } catch (err) { if (err instanceof Error) { setError(err.message); } else { setError("An unknown error occurred"); } } finally { setLoading(false); } }; loadCustomers(); }, [token, router]); // const mapToPowerDevice = () => { // console.log(selectedDevice); // return { // id: selectedDevice.deviceId, // phase: selectedDevice.deviceConnectedWith == "Single Phase" ? 2 : 3, // }; // }; // useEffect(() => { // if (deviceId !== null) { // // setActiveDevice(deviceId); // // setPhase(devices[deviceId]); // } // if (dayId !== null) { // setSelectedDuration(dayId); // } // }, [deviceId, dayId]); const handleDeviceChange = (event: React.ChangeEvent<HTMLSelectElement>) => { const selectedDeviceId = event.target.value; const selectedDevice = allDevices.find(device => device.deviceId.toString() === selectedDeviceId.toString()); console.log('Selected Device ID:', selectedDeviceId); console.log('Selected Device:', selectedDevice); setActiveDevice(selectedDeviceId); if (selectedDevice) { setActiveDevicePhase(selectedDevice.deviceConnectedWith === "Single Phase" ? 2 : 3); console.log('Updated Device Phase:', selectedDevice.deviceConnectedWith); } }; useEffect(() => { const fetchData = async () => { setLoading(true); try { const kwh = await querykWh({ id: activeDevice, phase: activeDevicePhase }, selectedDuration as RangeTime); setKilloWattData(kwh); console.log("KWH ACTIVE DEVICE",activeDevice); console.log("KWH ACTIVE DEVICE PHASE",activeDevicePhase); console.log("KWH SELECTDURATION",selectedDuration); } catch (error) { } finally { setLoading(false); } }; fetchData(); }, [activeDevice, activeDevicePhase, selectedDuration]); useEffect(() => { if(selectedGroup && selectedVendor){ const filteredDevices = allDevices .filter( (device) => device.group?.groupName === selectedGroup && device.vendor?.vendorName === selectedVendor ) .map((device) => device.deviceName); const filteredId = allDevices .filter( (device) => device.group?.groupName === selectedGroup && device.vendor?.vendorName === selectedVendor ) .map((device) => device.deviceId); //setDeviceId(filteredId) setDeviceNames(filteredDevices); } else if (selectedGroup) { const filteredDevices = allDevices .filter( (device) => device.group?.groupName === selectedGroup ) .map((device) => device.deviceName); const filteredId = allDevices .filter( (device) => device.group?.groupName === selectedGroup ) .map((device) => device.deviceId); //setDeviceId(filteredId) setDeviceNames(filteredDevices); } else if(selectedVendor) { const filteredDevices = allDevices .filter( (device) => device.vendor?.vendorName === selectedVendor ) .map((device) => device.deviceName); const filteredId = allDevices .filter( (device) => device.vendor?.vendorName === selectedVendor ) .map((device) => device.deviceId); //setDeviceId(filteredId) setDeviceNames(filteredDevices); } }, [selectedGroup, selectedVendor, allDevices]); useEffect(()=>{ if (selectedGroup) { const filteredVendors = allDevices .filter((device) => device.group?.groupName === selectedGroup) .map((device) => device.vendor?.vendorName) .filter(Boolean); setFilteredVendorNames(Array.from(new Set(filteredVendors))); } else { setFilteredVendorNames(vendorNames); } }, [ allDevices, vendorNames, selectedGroup]) const handleDurationChange = (event: React.ChangeEvent<HTMLSelectElement>) => { setSelectedDuration(event.target.value); }; useEffect(() => { if (selectedVendor) { const filteredGroups = allDevices .filter((device) => device.vendor?.vendorName === selectedVendor) .map((device) => device.group?.groupName) .filter(Boolean); setFilteredGroupNames(Array.from(new Set(filteredGroups))); } else { setFilteredGroupNames(groupNames); } }, [selectedVendor, allDevices, groupNames]); // if (loading) { // return ( // <p className="h-full flex justify-center items-center poppins text-[48px] font-semibold"> // Loading... // </p> // ); // } useEffect(() => { if (selectedDay) { const selectedDayId = getDayId(selectedDay); setSelectedDuration(selectedDayId); } }, [selectedDay]); const applyFilter = () => { if (filter===false &&(selectedGroup || selectedVendor || selectedDay)) { const selectedDeviceInfo = allDevices.find(device => device.deviceName === selectedDevice); if (selectedDeviceInfo) { setActiveDevice(selectedDeviceInfo.deviceId); setActiveDevicePhase(selectedDeviceInfo.deviceConnectedWith === "Single Phase" ? 2 : 3); } setFilter(true); } else { // Reset selectedVendor and selectedGroup setSelectedVendor(null); setSelectedGroup(null); setSelectedDevice(null); setSelectedDay(null); setSelectedInterval(null); setFilter(false); } }; const getDayId = (day: string | null) => { switch (day) { case "Today": return "-1d"; case "Last month": return "-30d"; case "Last year": return "-1y"; default: return "-1d"; } }; const formatTimestamps = (timestamps: string[], duration: string) => { if (duration === "-1y") { return timestamps.map((timestamp) => moment(timestamp).tz("Asia/Dhaka").format("MMM YYYY") ); } else if (duration === "-30d") { return timestamps.map((timestamp) => moment(timestamp).tz("Asia/Dhaka").format("DD MMM") ); } else { return timestamps.map((timestamp) => moment(timestamp).tz("Asia/Dhaka").format("HH:mm") ); } }; const calculateAverage = (data: number[]): number => { if (data.length === 0) return 0; const sum = data.reduce((acc, value) => acc + value, 0); return sum / data.length; }; if (!killoWattData) { return ( <p className="h-full flex justify-center items-center poppins text-[48px] font-semibold"> </p> ); } const kwhLabels = formatTimestamps(killoWattData.xAxis, selectedDuration); const renderKwhDatasets = () => { const datasets = [ { label: activeDevicePhase !== 3 ? "Killo Watt" : "Phase 1", data: killoWattData.series.valuesOne, fill: true, borderColor: "rgb(28, 70, 156)", backgroundColor: "rgba(28, 70, 156, 0.1)", tension: 0.6, }, ]; if (activeDevicePhase === 3) { datasets.push({ label: "Phase 2", data: killoWattData.series.valuesTwo, fill: true, borderColor: "rgb(114, 57, 234)", backgroundColor: "rgba(114, 57, 234, 0.1)", tension: 0.6, }); datasets.push({ label: "Phase 3", data: killoWattData.series.valuesThree, fill: true, borderColor: "rgb(246, 192, 0)", backgroundColor: "rgba(246, 192, 0, 0.1)", tension: 0.6, }); } return datasets; }; const kwhAverage = calculateAverage( killoWattData.series.valuesOne.concat( killoWattData.series.valuesTwo, killoWattData.series.valuesThree ) ); console.log(activeDevicePhase) return ( <div> {/* killoWatt Data Chart */} <div className="flex flex-col items-center bg-[#FFFFFF] rounded-xl p-6 text-[#3F4254] dark:bg-[#030304]" style={{ marginBottom: "20px" }} > <h2 className="items-center text-[#918F92] poppins text-[14px] dark:text-[#FFFFFFD9]"> Killo Watt </h2> {activeDevicePhase !== 3 && ( <div className="text-[#1C469C] text-[20px] font-medium py-2 poppins"> {kwhAverage.toFixed(2)} </div> )} <div className="flex my-6 gap-3"> <Dropdown options={filteredGroupNames} selectedOption={selectedGroup} onSelect={setSelectedGroup} defaultText="Select Group" imageSrc="/dashboard/caret-down-fill.svg" /> <Dropdown options={filteredVendorNames} selectedOption={selectedVendor} onSelect={setSelectedVendor} defaultText="Select Vendor" imageSrc="/dashboard/caret-down-fill.svg" /> <Dropdown options={deviceNames} selectedOption={selectedDevice} onSelect={setSelectedDevice} defaultText="Select Device" imageSrc="/dashboard/caret-down-fill.svg" /> <Dropdown options={["Today", "Last month", "Last year"]} selectedOption={selectedDay} onSelect={setSelectedDay} defaultText="Select Day" imageSrc="/dashboard/calender.svg" /> <Dropdown options={[ "15 mins Interval", "30 mins Interval", "1 hours Interval", ]} selectedOption={selectedInterval} onSelect={setSelectedInterval} defaultText="Select Interval" imageSrc="/dashboard/caret-down-fill.svg" /> <button className={`lg:text-xs xl:text-[14px] lg:w-[122px] xl:w-[170px] rounded-lg font-bold poppins ${ filter ? "text-[#1C469C] dark:text-[#1C469C] dark:bg-[#232026] border border-[#1C469C]" : "bg-[#1C469C] text-[#FFFFFF] dark:bg-[#1C469C]" }`} onClick={applyFilter} > {filter ? "Reset Filter" : "Apply Filter"} </button> </div> { killoWattData ? <div style={{ height: "350px", width: "100%"}}> <Line data={{ labels: kwhLabels, datasets: renderKwhDatasets(), }} options={{ plugins: { legend: { display: true, position: "bottom", align: "start", }, zoom: { pan: { enabled: true, mode: 'x', }, zoom: { mode: 'x', drag: { enabled: true, backgroundColor: 'rgba(28, 70, 156, 0.2)', borderColor: 'rgba(28, 70, 156, 1)', borderWidth: 1 } } } }, maintainAspectRatio: false, scales: { x: { grid: { display: false, }, }, }, }} /> </div> :null } </div> </div> ); }; export default IndexPage;
Editor is loading...
Leave a Comment