diff --git a/src/components/TaskCard.tsx b/src/components/TaskCard.tsx index 3a397fc..018b5d3 100644 --- a/src/components/TaskCard.tsx +++ b/src/components/TaskCard.tsx @@ -1,12 +1,12 @@ import { type Component, createMemo, For, Show } from "solid-js"; -import { type Task, calculateUrgencyFromDate, setActiveTaskId, store, copyTask, updateTask, currentTaskContext } from "@/store"; +import { type Task, calculateUrgencyFromDate, setActiveTaskId, store, copyTask, updateTask, currentTaskContext, now } from "@/store"; import { cn } from "@/lib/utils"; import { Clock, ArrowUpCircle, Copy, Users2 } from "lucide-solid"; import { Badge } from "@/components/ui/badge"; import { useTheme } from "./ThemeProvider"; import { getThemeAdjustedColor } from "@/lib/colors"; import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select"; -import { STATUS_OPTIONS } from "@/lib/constants"; +import { getStatusOptionsForTask } from "@/lib/constants"; import { StatusCircle } from "./StatusCircle"; export const TaskCard: Component<{ task: Task }> = (props) => { @@ -40,17 +40,20 @@ export const TaskCard: Component<{ task: Task }> = (props) => { return tags; }); - const isDueToday = createMemo(() => { + const isDueWithin12Hours = createMemo(() => { if (!props.task.dueDate) return false; try { - const todayStr = new Date().toLocaleDateString('en-CA'); - const dueStr = new Date(props.task.dueDate).toLocaleDateString('en-CA'); - return todayStr === dueStr; + const dueMs = new Date(props.task.dueDate).getTime(); + const diffMs = dueMs - now(); + const twelveHoursMs = 12 * 60 * 60 * 1000; + return Math.abs(diffMs) <= twelveHoursMs; } catch { return false; } }); + const statusOptions = createMemo(() => getStatusOptionsForTask(props.task.recurrence)); + return (
= (props) => { onClick={() => setActiveTaskId(props.task.id)} > {/* Today indicator */} - +
{/* Status Dropdown */} @@ -74,7 +77,7 @@ export const TaskCard: Component<{ task: Task }> = (props) => { if (!isNaN(s)) updateTask(props.task.id, { status: s }); } }} - options={STATUS_OPTIONS} + options={statusOptions()} optionValue="value" optionTextValue="label" placeholder="Status" diff --git a/src/components/TaskDetail.tsx b/src/components/TaskDetail.tsx index 793ea49..0a87834 100644 --- a/src/components/TaskDetail.tsx +++ b/src/components/TaskDetail.tsx @@ -9,7 +9,7 @@ import { calculateDateFromUrgency, calculateUrgencyFromDate } from "@/store"; import { Button } from "./ui/button"; import { TagPicker } from "./TagPicker"; import { Badge } from "./ui/badge"; -import { PRIORITY_OPTIONS, URGENCY_OPTIONS, SIZE_OPTIONS, STATUS_OPTIONS } from "@/lib/constants"; +import { PRIORITY_OPTIONS, URGENCY_OPTIONS, SIZE_OPTIONS, getStatusOptionsForTask } from "@/lib/constants"; import { store } from "@/store"; import { cn } from "@/lib/utils"; import { toast } from "solid-sonner"; @@ -136,6 +136,8 @@ export const TaskDetail: Component = (props) => { return tags; }); + const statusOptions = createMemo(() => getStatusOptionsForTask(props.task.recurrence)); + return ( { if (!open) { @@ -164,7 +166,7 @@ export const TaskDetail: Component = (props) => { value={(props.task.status ?? 0).toString()} onChange={(val: string | null) => val && updateStatus(val)} - options={STATUS_OPTIONS} + options={statusOptions()} optionValue="value" optionTextValue="label" placeholder="Status" diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 1067734..de0bcf3 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -68,3 +68,44 @@ export const STATUS_OPTIONS = [ { value: "1", label: "1" }, { value: "0", label: "0 - Not Yet Started" } ]; + +const DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + +type Recurrence = { + type: 'daily' | 'weekly' | 'monthly'; + days?: number[]; + dayOfMonth?: number; +}; + +export const getRecurrenceCompleteLabel = (recurrence?: Recurrence | null): string => { + if (!recurrence) return "10 - Complete"; + if (recurrence.type === 'daily') return "10 - Complete until tomorrow"; + if (recurrence.type === 'weekly') { + if (recurrence.days && recurrence.days.length > 0) { + const today = new Date().getDay(); + const sorted = [...recurrence.days].sort((a, b) => { + const da = (a - today + 7) % 7 || 7; + const db = (b - today + 7) % 7 || 7; + return da - db; + }); + return `10 - Complete until ${DAY_NAMES[sorted[0]]}`; + } + return "10 - Complete (weekly)"; + } + if (recurrence.type === 'monthly') { + const dom = recurrence.dayOfMonth; + if (dom != null) { + const suffix = dom === 1 || dom === 21 || dom === 31 ? 'st' + : dom === 2 || dom === 22 ? 'nd' + : dom === 3 || dom === 23 ? 'rd' : 'th'; + return `10 - Complete until the ${dom}${suffix}`; + } + } + return "10 - Complete"; +}; + +export const getStatusOptionsForTask = (recurrence?: Recurrence | null) => + STATUS_OPTIONS.map(opt => + opt.value === "10" ? { ...opt, label: getRecurrenceCompleteLabel(recurrence) } : opt + ); +