feat: garden calendar + lists integrations (task 74)

- calendar-bridge.ts and lists-bridge.ts isolate cross-module deps
- scheduleOnCalendar action: creates event from care schedule with 30-min
  slot, title convention (Water/Fertilize/Repot/Prune/custom), reminder opt
- pushOverdueToTaskList action: inserts one task per overdue (plant+schedule)
  pair into the default task list, skips duplicate text entries
- CareScheduleEditor: per-row calendar 📅 button opens inline form with
  calendar select + optional reminder minutes + success link to /calendar
- Garden page header: PushOverdueButton with auto-dismissing feedback toast
This commit is contained in:
ginnoir
2026-06-01 20:33:15 -05:00
parent eabcebdb00
commit 0b0deff700
8 changed files with 322 additions and 43 deletions
+5 -1
View File
@@ -2,6 +2,7 @@ import Link from "next/link";
import { listContainers, listPlants } from "@/modules/garden/server/queries";
import { ContainerList } from "@/modules/garden/components/container-list";
import { PlantList } from "@/modules/garden/components/plant-list";
import { PushOverdueButton } from "@/modules/garden/components/push-overdue-button";
type Props = {
searchParams: Promise<{ tab?: string }>;
@@ -18,7 +19,10 @@ export default async function GardenPage({ searchParams }: Props) {
return (
<div className="page-content">
<h1 className="page-title">Garden</h1>
<div className="flex items-center justify-between mb-1">
<h1 className="page-title mb-0">Garden</h1>
<PushOverdueButton />
</div>
<div className="flex gap-6 border-b border-[var(--ink-faint)] mb-6">
<Link
+9 -2
View File
@@ -1,19 +1,26 @@
import { notFound } from "next/navigation";
import { listCalendars } from "@/modules/garden/server/calendar-bridge";
import { getCareLogs, getCareSchedules, getPlant } from "@/modules/garden/server/queries";
import { PlantDetail } from "@/modules/garden/components/plant-detail";
export default async function PlantPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const [plant, careLogs, careSchedules] = await Promise.all([
const [plant, careLogs, careSchedules, calendars] = await Promise.all([
getPlant(id),
getCareLogs(id),
getCareSchedules(id),
listCalendars(),
]);
if (!plant) notFound();
return (
<div className="page-content">
<PlantDetail plant={plant} careLogs={careLogs} careSchedules={careSchedules} />
<PlantDetail
plant={plant}
careLogs={careLogs}
careSchedules={careSchedules}
calendars={calendars}
/>
</div>
);
}