feat: garden care tracking - logs, schedules, reminders (task 73)
- logCare/deleteCareLog actions with schedule update and reminder wiring - upsertCareSchedule/deleteCareSchedule/toggleCareSchedule actions - updateScheduleAfterCare helper cancels old reminder, schedules new one - getCareLogs/getCareSchedules/getOverduePlants/getCareDueSoon queries - CareLogForm, CareScheduleEditor, CareHistoryList components - Plant detail Care tab wired up with schedule editor + log form + history - Log plant care quick-add added to garden manifest
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import type { CareLogDto } from "../server/queries";
|
||||
|
||||
const CARE_ICONS: Record<string, string> = {
|
||||
watering: "💧",
|
||||
fertilizing: "🌱",
|
||||
repotting: "🪴",
|
||||
pruning: "✂️",
|
||||
"pest-control": "🐛",
|
||||
other: "📋",
|
||||
};
|
||||
|
||||
function timeAgo(iso: string): string {
|
||||
const diff = Date.now() - new Date(iso).getTime();
|
||||
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||
if (days === 0) return "Today";
|
||||
if (days === 1) return "Yesterday";
|
||||
return `${days} days ago`;
|
||||
}
|
||||
|
||||
type Props = {
|
||||
logs: CareLogDto[];
|
||||
};
|
||||
|
||||
export function CareHistoryList({ logs }: Props) {
|
||||
if (logs.length === 0) {
|
||||
return <p className="text-sm text-[var(--ink-mute)]">No care events logged yet.</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ul className="flex flex-col gap-2">
|
||||
{logs.map((log) => (
|
||||
<li key={log.id} className="flex gap-3 items-start text-sm">
|
||||
<span className="text-lg leading-none mt-0.5" aria-hidden>
|
||||
{CARE_ICONS[log.careType] ?? "📋"}
|
||||
</span>
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="font-medium capitalize">{log.careType}</span>
|
||||
<span className="text-xs text-[var(--ink-mute)]">{timeAgo(log.performedAt)}</span>
|
||||
{log.notes && <p className="text-xs text-[var(--ink-mute)]">{log.notes}</p>}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user