Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
15 kB
1
Indexable
Never
"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;
Leave a Comment