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
@@ -4,6 +4,7 @@ import { useState, useTransition } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { deletePlant, addPlantImage, removePlantImage, setPrimaryImage } from "../server/actions";
import type { CalendarDto } from "../server/calendar-bridge";
import type { CareLogDto, CareScheduleDto, PlantDetailDto } from "../server/queries";
import { CareHistoryList } from "./care-history-list";
import { CareLogForm } from "./care-log-form";
@@ -15,6 +16,7 @@ type Props = {
plant: PlantDetailDto;
careLogs: CareLogDto[];
careSchedules: CareScheduleDto[];
calendars: CalendarDto[];
};
function InfoRow({
@@ -41,7 +43,7 @@ function healthBadgeClass(status: string): string {
return "badge-warning";
}
export function PlantDetail({ plant, careLogs, careSchedules }: Props) {
export function PlantDetail({ plant, careLogs, careSchedules, calendars }: Props) {
const [tab, setTab] = useState<Tab>("info");
const [confirming, setConfirming] = useState(false);
const [isPending, startTransition] = useTransition();
@@ -260,7 +262,7 @@ export function PlantDetail({ plant, careLogs, careSchedules }: Props) {
{/* Care */}
{tab === "care" && (
<div className="flex flex-col gap-6">
<CareScheduleEditor plantId={plant.id} schedules={careSchedules} />
<CareScheduleEditor plantId={plant.id} schedules={careSchedules} calendars={calendars} />
<div className="border-t border-[var(--ink-faint)] pt-4">
<p className="text-sm font-semibold text-[var(--ink-mute)] uppercase tracking-wide mb-3">
Log care