Duffer Derek
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