diff --git a/src/components/StatusCircle.tsx b/src/components/StatusCircle.tsx new file mode 100644 index 0000000..fc3c9ce --- /dev/null +++ b/src/components/StatusCircle.tsx @@ -0,0 +1,67 @@ +import { type Component } from "solid-js"; +import { CheckCircle2 } from "lucide-solid"; +import { cn } from "@/lib/utils"; + +interface StatusCircleProps { + status: number; + size?: number; + className?: string; +} + +export const StatusCircle: Component = (props) => { + const size = () => props.size || 24; + const radius = () => (size() / 2) - 2; // Subtract stroke width/padding + const circumference = () => 2 * Math.PI * radius(); + + // Status 0: Empty Circle + // Status 10: CheckCircle2 (Green) + // Status 1-9: Progress Ring + + const strokeDashoffset = () => { + // Invert to fill clockwise? + // Progress 1-9. + // 1 = 10%, 9 = 90% + const percentage = Math.max(0, Math.min(10, props.status)) / 10; + return circumference() * (1 - percentage); + }; + + return ( +
+ {props.status >= 10 ? ( + + ) : ( + // Progress Circle +
+ {/* Background Circle (Ghost) */} + + + {/* Progress Arc */} + + + {/* Hover indicator (maybe show check on hover?) + User didn't ask for generic hover, just visual update. + */} +
+ )} +
+ ); +}; diff --git a/src/components/TaskCard.tsx b/src/components/TaskCard.tsx index b4c05b6..fe7c6e5 100644 --- a/src/components/TaskCard.tsx +++ b/src/components/TaskCard.tsx @@ -1,11 +1,13 @@ -import { type Component, createMemo } from "solid-js"; -import { type Task, toggleTask, calculateUrgencyFromDate, setActiveTaskId, store, copyTask } from "@/store"; +import { type Component, createMemo, For } from "solid-js"; +import { type Task, calculateUrgencyFromDate, setActiveTaskId, store, copyTask, updateTask } from "@/store"; import { cn } from "@/lib/utils"; -import { CheckCircle2, Circle, Clock, ArrowUpCircle, Copy, Users2 } from "lucide-solid"; +import { Clock, ArrowUpCircle, Copy, Users2 } from "lucide-solid"; import { Badge } from "@/components/ui/badge"; -import { For } from "solid-js"; 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 { StatusCircle } from "./StatusCircle"; export const TaskCard: Component<{ task: Task }> = (props) => { const { resolvedTheme } = useTheme(); @@ -32,16 +34,36 @@ export const TaskCard: Component<{ task: Task }> = (props) => { )} onClick={() => setActiveTaskId(props.task.id)} > - + {/* Status Dropdown */} +
e.stopPropagation()}> + + value={(props.task.status ?? 0).toString()} + onChange={(val: any) => { + const value = typeof val === 'object' ? val?.value : val; + if (value) { + const s = parseInt(value); + if (!isNaN(s)) updateTask(props.task.id, { status: s }); + } + }} + options={STATUS_OPTIONS} + optionValue="value" + optionTextValue="label" + placeholder="Status" + itemComponent={(props: any) => {props.item.rawValue.label}} + > + { + e.preventDefault(); + e.stopPropagation(); + updateTask(props.task.id, { status: 10 }); + }} + > + + + + +

= (props) => { } }; + const updateStatus = (val: any) => { + const value = typeof val === 'object' ? val.value : val; + const s = parseInt(value); + if (!isNaN(s)) { + updateTask(props.task.id, { status: s }); + } + }; + const updateUrgency = (val: any) => { const value = typeof val === 'object' ? val.value : val; const u = parseInt(value); @@ -119,29 +128,57 @@ export const TaskDetail: Component = (props) => { > {/* Header Area */}
-