Untitled
unknown
plain_text
2 years ago
15 kB
10
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