Search
Search
Search
Search
Information
Information
Light
Dark
Open actions menu
Basic upload method
Bypass upload method
Tips!
If you encounter an error (by firewall) while uploading using both methods,
try changing extension of the file before uploading it and rename it right after.
This uploader supports multiple file upload.
Submit
~
var
www
api-mk-planner.bitkit.dk
httpdocs
Frontend
src
context
File Content:
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> ); };
Edit
Download
Unzip
Chmod
Delete