- 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
46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
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>
|
|
);
|
|
}
|