diff --git a/src/Interfaces/index.ts b/src/Interfaces/index.ts index 41e81983d..7c0860a4e 100644 --- a/src/Interfaces/index.ts +++ b/src/Interfaces/index.ts @@ -33,3 +33,5 @@ export interface ILocationState { export interface ImpossibleGoal extends GoalItem { impossible: boolean; } + +export type ScheduleStatus = "pending" | "scheduled" | "impossible" | "future" | null; diff --git a/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.scss b/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.scss index ed1f3d62c..727ce1fe9 100644 --- a/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.scss +++ b/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.scss @@ -156,3 +156,8 @@ gap: 10px; justify-content: center; } + +.schedule-status { + margin-top: 8px; + text-align: center; +} diff --git a/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx b/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx index 56541b32f..23ef1c95f 100644 --- a/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx +++ b/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx @@ -17,10 +17,12 @@ import { useParentGoalContext } from "@src/contexts/parentGoal-context"; import useGoalActions from "@src/hooks/useGoalActions"; import useGoalStore from "@src/hooks/useGoalStore"; import { unarchiveUserGoal } from "@src/api/GoalsAPI"; -import { ILocationState } from "@src/Interfaces"; +import { ILocationState, ScheduleStatus } from "@src/Interfaces"; import { useLocation, useNavigate } from "react-router-dom"; import { suggestedGoalState } from "@src/store/SuggestedGoalState"; import { getHistoryUptoGoal } from "@src/helpers/GoalProcessor"; +import { ISchedulerOutput } from "@src/Interfaces/IScheduler"; +import useScheduler from "@src/hooks/useScheduler"; import { colorPalleteList, calDays, convertOnFilterToArray, getSelectedLanguage } from "../../../utils"; import "./ConfigGoal.scss"; @@ -47,6 +49,9 @@ const ConfigGoal = ({ type, goal, mode }: { type: TGoalCategory; mode: TGoalConf const location = useLocation(); const navigate = useNavigate(); + const { checkGoalSchedule } = useScheduler(); + const [scheduleStatus, setScheduleStatus] = useState(null); + let defaultColorIndex = Math.floor(Math.random() * colorPalleteList.length - 1) + 1; let defaultAfterTime = isEditMode ? (goal.afterTime ?? 9) : 9; let defaultBeforeTime = isEditMode ? (goal.beforeTime ?? 18) : 18; @@ -279,6 +284,53 @@ const ConfigGoal = ({ type, goal, mode }: { type: TGoalCategory; mode: TGoalConf const titlePlaceholder = t(`${type !== "Budget" ? "goal" : "budget"}Title`); + const checkSchedulingStatus = async (schedulerOutput: ISchedulerOutput | undefined, goalId: string) => { + if (!schedulerOutput) return "pending"; + + const { scheduled, impossible } = schedulerOutput; + + if (impossible?.some((task) => task.id === goalId)) { + return "impossible"; + } + + const isScheduledInNext7Days = scheduled.some((day) => day.tasks.some((task) => task.goalid === goalId)); + + return isScheduledInNext7Days ? "scheduled" : "future"; + }; + + const getScheduleStatusText = (status: ScheduleStatus) => { + switch (status) { + case "scheduled": + return "Auto scheduled"; + case "impossible": + return "! Impossible"; + case "future": + return "Scheduled someday"; + default: + return ""; + } + }; + + const checkSchedule = async () => { + setScheduleStatus("pending"); + try { + const schedulerOutput = await checkGoalSchedule(getFinalTags()); + const status = await checkSchedulingStatus(schedulerOutput, goal.id); + setScheduleStatus(status); + } catch (error) { + setScheduleStatus(null); + } + }; + + useEffect(() => { + const debounceTimer = setTimeout(() => { + console.log("checking schedule"); + checkSchedule(); + }, 1000); + + return () => clearTimeout(debounceTimer); + }, [tags.duration, afterTime, beforeTime, perDayHrs, perWeekHrs]); + return ( + {scheduleStatus && ( +
{getScheduleStatusText(scheduleStatus)}
+ )} ) : (
@@ -446,6 +501,9 @@ const ConfigGoal = ({ type, goal, mode }: { type: TGoalCategory; mode: TGoalConf disablePastDates />
+ {scheduleStatus && tags.duration && ( +
{getScheduleStatusText(scheduleStatus)}
+ )} )} diff --git a/src/hooks/useScheduler.tsx b/src/hooks/useScheduler.tsx index 98e780c83..f7259de1e 100644 --- a/src/hooks/useScheduler.tsx +++ b/src/hooks/useScheduler.tsx @@ -98,10 +98,28 @@ function useScheduler() { } }, [action]); + const checkGoalSchedule = async (goal: GoalItem) => { + try { + const activeGoals: GoalItem[] = await getAllGoals(); + const goalsWithConfig = [...activeGoals, goal]; + + const { schedulerInput } = await organizeDataForInptPrep(goalsWithConfig); + + await init(); + const res = schedule(schedulerInput); + + return res; + } catch (error) { + console.log("Error checking goal schedule:", error); + return null; + } + }; + return { tasks, tasksStatus, setTasksStatus, + checkGoalSchedule, }; }