Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
10 kB
2
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 zoomPlugin from 'chartjs-plugin-zoom';
import { Chart, registerables } from 'chart.js';
import { queryCost, CostData, RangeTime } from "@/app/lib/influxQueries";
import { Types } from "@/app/types";

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 }) => {
  const [activeDevice, setActiveDevice] = useState<string>(deviceId ?? "0");
  const [activeDevicePhase, setActiveDevicePhase] = useState<number>(devicePhase == "Single Phase" ? 2 : 3);
  const [costData, setCostData] = useState<CostData | null>(null);
  const [loading, setLoading] = useState(false);
  const [selectedDuration, setSelectedDuration] = useState<string>(dayId ?? "-1d");

  // useEffect(() => {
  //   if (deviceId !== null) {
  //     setActiveDevice(deviceId);
  //     setPhase(devices[deviceId]);
  //   }
  //   if (dayId !== null) {
  //     setSelectedDuration(dayId);
  //   }
  // }, [deviceId, dayId]);


  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const kwh = await queryCost({ id: activeDevice, phase: activeDevicePhase }, selectedDuration as RangeTime);
        console.log("COST DATA",kwh);
        setCostData(kwh);
      } catch (error) {
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [activeDevice, activeDevicePhase, selectedDuration]);

  const handleDeviceChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setActiveDevice(event.target.value);
    // activeDevicePhase(devices[event.target.value]);
  };

  const handleDurationChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setSelectedDuration(event.target.value);
  };

  if (loading) {
    return (
      <p className="h-full flex justify-center items-center poppins text-[48px] font-semibold">
        Loading...
      </p>
    );
  }

  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 (!costData) {
    return (
      <p className="h-full flex justify-center items-center poppins text-[48px] font-semibold">
        No data available
      </p>
    );
  }

  const kwhLabels = formatTimestamps(costData.xAxis, selectedDuration);

  const renderKwhDatasets = () => {
    const datasets = [
      {
        label: activeDevicePhase !== 3 ? "Killo Watt" : "Phase 1",
        data: costData.costSeries,
        fill: true,
        borderColor: "rgb(163, 39, 114)",
        backgroundColor: "rgba(163, 39, 114, 0.1)",
        tension: 0.6,
      },
    ];

    if (activeDevicePhase === 3) {
      datasets.push({
        label: "Phase 2",
        data: costData.costSeries,
        fill: true,
        borderColor: "rgb(114, 57, 234)",
        backgroundColor: "rgba(114, 57, 234, 0.1)",
        tension: 0.6,
      });
      datasets.push({
        label: "Phase 3",
        data: costData.costSeries,
        fill: true,
        borderColor: "rgb(246, 192, 0)",
        backgroundColor: "rgba(246, 192, 0, 0.1)",
        tension: 0.6,
      });
    }
    return datasets;
  };

  const kwhAverage = calculateAverage(
    costData.costSeries.concat(
      costData.costSeries,
      costData.costSeries
    )
  );

  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]">
          Cost
        </h2>

        {activeDevicePhase !== 3 && (
          <div className="text-[#1C469C] text-[20px] font-medium py-2 poppins">
            {kwhAverage.toFixed(2)}
          </div>
        )}

        <div className="flex gap-6">

          {/* Dropdown to select Group */}
          <div className="relative inline-flex items-center mb-4 poppins">
            <select
              id="activeGroup"
              // onChange={handleGroupChange}
              // value={activeGroup}
              className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full"
            >
              <option value="Group X">Group X</option>
              <option value="Group Y">Group Y</option>
              <option value="Group Z">Group Z</option>
            </select>
            <Image
              className="absolute right-2 pointer-events-none w-auto h-auto"
              src="/dashboard/caret-down-fill.svg"
              alt="caret-down"
              width={12}
              height={12}
            />
          </div>

          {/* Dropdown to select Vendor */}
          <div className="relative inline-flex items-center mb-4 poppins">
            <select
              id="activeVendor"
              // onChange={handleVendorChange}
              // value={activeVendor}
              className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full"
            >
              <option value="Vendor X">Vendor X</option>
              <option value="Vendor Y">Vendor Y</option>
              <option value="Vendor Z">Vendor Z</option>
            </select>
            <Image
              className="absolute right-2 pointer-events-none w-auto h-auto"
              src="/dashboard/caret-down-fill.svg"
              alt="caret-down"
              width={12}
              height={12}
            />
          </div>

          {/* Dropdown to select device */}
          <div className="relative inline-flex items-center mb-4 c">
            <select
              id="activeDevice"
              onChange={handleDeviceChange}
              value={activeDevice}
              className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full"
            >
              <option value="0">Device 1</option>
              <option value="1">Device 2</option>
              <option value="215616591345044">Device 3</option>
            </select>
            <Image
              className="absolute right-2 pointer-events-none w-auto h-auto"
              src="/dashboard/caret-down-fill.svg"
              alt="caret-down"
              width={12}
              height={12}
            />
          </div>

          {/* Dropdown to select duration */}
          <div className="relative inline-flex items-center mb-4 poppins">
            <select
              id="selectedDuration"
              onChange={handleDurationChange}
              value={selectedDuration}
              className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full"
            >
              <option value="-1d">Today</option>
              <option value="-30d">Last month</option>
              <option value="-1y">Last year</option>
            </select>
            <Image
              className="absolute right-2 pointer-events-none"
              src="/dashboard/calender.svg"
              alt="caret-down"
              width={12}
              height={12}
            />
          </div>

           {/* Dropdown to select Interval */}
           <div className="relative inline-flex items-center mb-4 poppins">
            <select
              id="activeInterval"
              // onChange={handleIntervalChange}
              // value={activeInterval}
              className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full"
            >
              <option value="Interval X">15 mins Interval</option>
              <option value="Interval Y">30 mins Interval</option>
              <option value="Interval Z">1 hours Interval</option>
            </select>
            <Image
              className="absolute right-2 pointer-events-none w-auto h-auto"
              src="/dashboard/caret-down-fill.svg"
              alt="caret-down"
              width={12}
              height={12}
            />
          </div>

        </div>

       {
        costData ?  <div style={{ height: "300px", 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: 'rgb(163, 39, 114,0.2)',
                    borderColor: 'rgb(163, 39, 114, 1)',
                    borderWidth: 1
                  }
                }
              }
            },
            maintainAspectRatio: false,
            scales: {
              x: {
                grid: {
                  display: false,
                },
              },
            },
          }}
        />
      </div> :null
       }
      </div>
    </div>
  );
};

export default IndexPage;
Leave a Comment