Duffer Derek

Current Path : /var/www/api-mk-planner.bitkit.dk/httpdocs/Frontend/src/context/
Upload File :
Current File : /var/www/api-mk-planner.bitkit.dk/httpdocs/Frontend/src/context/dataContext.js

import { createContext, useEffect, useMemo, useReducer, useState } from "react";
import { getDashboardData } from "../utils/commonFunctions";
import { useAuthContext } from "../hooks/useAuthContext";
import { startOfISOWeek, subWeeks, addDays, differenceInDays } from "date-fns";
import { dataReducer } from "./dataReducer";

export const DataContext = createContext();

const partners = Array.from({ length: 50 }, (_, index) => ({
  user_id: index + 1,
  item_id: 50003 + index,
  name: `Partner ${index + 1}`,
  email: `Partner${index + 1}@example.com`,
  phone: `555-${Math.floor(Math.random() * 9000) + 1000}`,
  type: index % 2 === 0 ? "regular" : "admin",
}));

const types = [
  { id: 1, name: "Maleropgave" },
  { id: 2, name: "Maler Reklamationss" },
];

const landsdel = [
  { id: 1, value: "Sjælland" },
  { id: 2, value: "Fyn" },
  { id: 3, value: "Jylland" },
];

const managers = Array.from({ length: 10 }, (_, index) => ({
  user_id: index + 1,
  item_id: 100003 + index,
  name: `Manager ${index + 1}`,
  email: `Manager${index + 1}@example.com`,
  phone: `555-${Math.floor(Math.random() * 9000) + 1000}`,
  type: index % 2 === 0 ? "regular" : "admin",
}));

const task_status = [
  { "id": 1, "name": "Oprettet" },
  { "id": 6, "name": "Booket" },
  { "id": 3, "name": "Fuldført" },
  { "id": 4, "name": "Faktureret" },
  { "id": 5, "name": "Annulleret Maler" },
  { "id": 8, "name": "Annulleret Kunden" }
];

const inquiry_status = [
  { "id": 1,  "name": "Modtaget" },
  { "id": 9,  "name": "Afventer info fra kunden" },
  { "id": 7,  "name": "Følge op på henvendelse" },
  { "id": 5,  "name": "Kontaktet telefonisk" },
  { "id": 3,  "name": "Tilbud sendt" },
  { "id": 10, "name": "Tænker over tilbud" },
  { "id": 6,  "name": "Tilbud accepteret - Opret opgave" },
  { "id": 4,  "name": "Ikke interesseret" },
  { "id": 11, "name": "Dublet" },
  { "id": 15, "name": "Tabt" },
  { "id": 16, "name": "Besigtigelse aftalt" }
];

const Filters = {
  types: types,
  managers: managers,
  partners: partners,
  landsdel: landsdel,
  task_status: task_status,
  inquiry_status: inquiry_status,
};

const getDayName = (date) => {
  const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  return daysOfWeek[date.getDay()];
};

const getMonthName = (date) => {
  const months = [
    "Jan",
    "Feb",
    "Mar",
    "Apr",
    "May",
    "Jun",
    "Jul",
    "Aug",
    "Sep",
    "Oct",
    "Nov",
    "Dec",
  ];
  return months[date.getMonth()];
};

const today = new Date();
// Format the date as "yyyy-mm-dd"
const date = today.toISOString().split("T")[0];

export const DataContextProvider = ({ children }) => {
  const { access_token } = useAuthContext();
  const [loading, setLoading] = useState(false);
  const [state, dispatch] = useReducer(dataReducer, {
    filterOptions: Filters,
    partners: partners,
    data: null,
    unassignedData: null,
    taskDetails: null,
    leaves: null,
    filters: {
      type: null,
      service_managers: null,
      partner: null,
      lansdel: null,
      inquiry_status: null,
      task_status: null,
      date: date,
      startDate: startOfISOWeek(subWeeks(new Date(), 5)),
      endDate: addDays(new Date(), 90),
      filter: "",
      getSelectedYear: null,
      getSelectedMonth: null,
      getSelectedWeekNumbers: 0,
      selectedFilter: null,
    },
    popUpStatus: false,
  });
  const { startDate, endDate } = state.filters;

  useEffect(() => {
    fetchData();
  }, [state.filters]);

  const fetchData = async () => {
    const { filters } = state;
    if (
      filters.selectedFilter === "year_week_number" &&
      (!filters.getSelectedWeekNumbers || !filters.getSelectedYear)
    )
      return;
    if (
      filters.selectedFilter === "year_month_number" &&
      (!filters.getSelectedMonth || !filters.getSelectedYear)
    )
      return;

    setLoading(true);
    try {
      let response = await getDashboardData(access_token, filters);
      setData(response);
    } catch (error) {
      console.error("Error fetching dashboard data:", error);
    } finally {
      setLoading(false);
    }
  };

  const setData = (response) => {
    // API structure: { status: 200, data: { tasks: { assigned: { tasks: [], inquiry: [] } } } }
    // Extract assigned object: { tasks: [], inquiry: [] }
    dispatch({
      type: "DATA",
      payload: response?.data?.tasks?.assigned,
    });
    
    // Extract filter options - check for filters first (admin dashboard), then extract from categories (office partner)
    let filterOptions = response?.data?.filters;
    
    // If filters exist, merge with existing filterOptions to preserve defaults
    if (filterOptions) {
      const currentFilterOptions = state.filterOptions || Filters;
      // Merge filter options: use API values if they exist and are valid arrays, otherwise preserve current values
      filterOptions = {
        ...currentFilterOptions, // Preserve existing defaults (service_managers, partners, etc.)
        // Only update if API provides valid non-empty arrays, otherwise keep current values
        types: (Array.isArray(filterOptions.types) && filterOptions.types.length > 0) ? filterOptions.types : (currentFilterOptions?.types || []),
        inquiry_status: (Array.isArray(filterOptions.inquiry_status) && filterOptions.inquiry_status.length > 0) ? filterOptions.inquiry_status : (currentFilterOptions?.inquiry_status || Filters.inquiry_status || []),
        task_status: (Array.isArray(filterOptions.task_status) && filterOptions.task_status.length > 0) ? filterOptions.task_status : (currentFilterOptions?.task_status || Filters.task_status || []),
        lansdel: (Array.isArray(filterOptions.lansdel) && filterOptions.lansdel.length > 0) ? filterOptions.lansdel : (currentFilterOptions?.lansdel || []),
        service_managers: (Array.isArray(filterOptions.service_managers) && filterOptions.service_managers.length > 0) ? filterOptions.service_managers : (currentFilterOptions?.service_managers || []),
        // Use partners from API if available, otherwise preserve existing
        partners: (Array.isArray(filterOptions.partners) && filterOptions.partners.length > 0) ? filterOptions.partners : (currentFilterOptions?.partners || []),
        managers: currentFilterOptions?.managers || []
      };
    }
    // If filters don't exist, extract from categories
    else if (response?.data?.tasks?.assigned?.categories) {
      const categories = response.data.tasks.assigned.categories;
      
      // Transform categories to match filter options format
      // categories.tasks.type has { id, value } structure, need to map to { id, name }
      const transformTypes = (typeArray) => {
        if (!Array.isArray(typeArray)) return [];
        return typeArray.map(item => ({
          id: item.id,
          name: item.value || item.name || ''
        }));
      };
      
      // Transform country_side to lansdel format
      const transformLansdel = (countrySideArray) => {
        if (!Array.isArray(countrySideArray)) return [];
        return countrySideArray.map(item => ({
          id: item.id,
          name: item.value || item.name || '',
          value: item.value || item.name || ''
        }));
      };
      
      // Transform inquiry status to { id, name } format
      const transformInquiryStatus = (statusArray) => {
        if (!Array.isArray(statusArray)) return [];
        return statusArray.map(item => ({
          id: item.id,
          name: item.name || item.value || ''
        }));
      };
      
      // Transform task status to { id, name } format
      const transformTaskStatus = (statusArray) => {
        if (!Array.isArray(statusArray)) return [];
        return statusArray.map(item => ({
          id: item.id,
          name: item.name || item.value || ''
        }));
      };
      
      // Merge with existing filterOptions to preserve service_managers and partners defaults
      const currentFilterOptions = state.filterOptions || Filters;
      filterOptions = {
        ...currentFilterOptions, // Preserve existing defaults (service_managers, partners, etc.)
        // Extract types from categories.tasks.type and transform to { id, name } format
        types: transformTypes(categories?.tasks?.type) || currentFilterOptions?.types || [],
        // Extract lansdel from categories.inquiry.country_side or categories.tasks.country_side
        lansdel: transformLansdel(categories?.inquiry?.country_side || categories?.tasks?.country_side) || currentFilterOptions?.lansdel || [],
        // Extract inquiry_status from categories.inquiry.status and transform to { id, name } format
        inquiry_status: transformInquiryStatus(categories?.inquiry?.status) || currentFilterOptions?.inquiry_status || Filters.inquiry_status || [],
        // Extract task_status from categories.tasks.status and transform to { id, name } format
        task_status: transformTaskStatus(categories?.tasks?.status) || currentFilterOptions?.task_status || Filters.task_status || []
      };
    }
    // If no filters from API and no categories, preserve existing filter options
    else {
      filterOptions = state.filterOptions || Filters;
    }
    
    // Always dispatch filter options (never undefined or null)
    dispatch({
      type: "SET_FILTER_OPTIONS",
      payload: filterOptions || Filters,
    });
    dispatch({
      type: "UNASSIGNED_TASK",
      payload: response?.data?.tasks?.unassigned,
    });
    dispatch({
      type: "LEAVED_PARTNERS",
      payload: response?.data?.leaved_partners,
    });
  };

  // generate dates array
  const dates = useMemo(() => {
    let dates = [];
    for (
      let date = new Date(startDate);
      date <= endDate;
      date.setDate(date.getDate() + 1)
    ) {
      const formattedDate = {
        date: date.toDateString(),
        dayName: getDayName(date),
        dayNumber: date.getDate(),
        monthName: getMonthName(date),
      };

      dates.push(formattedDate);
    }
    return dates;
  }, [startDate, endDate]);

  // calculate column width
  const columnWidth = useMemo(() => {
    const minWidth = 50;
    const days = differenceInDays(endDate, startDate);
    const mainPanel = document.querySelector(".main-panel");
    let viewWidth = 0;
    if (mainPanel) {
      viewWidth = mainPanel.clientWidth - 116;
    } else {
      viewWidth = window.innerWidth - 116;
    }

    const calendarWidth = viewWidth;

    // const colWidth = Math.floor(calendarWidth / (days + 1));
    const colWidth = calendarWidth / (days + 1);
    return colWidth < minWidth ? minWidth : colWidth;
  }, [startDate, endDate]);

  return (
    <DataContext.Provider
      value={{ ...state, dates, columnWidth, dispatch, loading, fetchData }}
    >
      {children}
    </DataContext.Provider>
  );
};

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists