"use client"; import { usePathname, useRouter } from "next/navigation"; import { toast } from "@/components/ui/use-toast"; import { cn } from "@/lib/utils"; import React, { useState, useEffect, useRef } from 'react'; import { useUpdateHour } from "@lifetracker/shared-react/hooks/days"; import { EditableText } from "@/components/dashboard/EditableText"; import { format } from "date-fns"; import { TZDate } from "@date-fns/tz"; import { ZHour } from "@lifetracker/shared/types/days"; import { MessageCircle, Pencil, Plus } from "lucide-react"; import { ButtonWithTooltip } from "@/components/ui/button"; import { EditableHourCode } from "./EditableHourCode"; import { EditableHourComment } from "./EditableHourComment"; import spacetime from 'spacetime'; import { eq, is } from "drizzle-orm"; import HourMeasurementsDialog from "@/components/dashboard/hours/HourMeasurementsDialog"; import { ActionButtonWithTooltip } from "@/components/ui/action-button"; import { ZMetric } from "@lifetracker/shared/types/metrics"; import { Badge } from "@/components/ui/badge"; import { Icon } from "@/components/ui/icon"; import { titleCase } from "title-case"; import { useDecrementCount, useDeleteMeasurement } from "@lifetracker/shared-react/hooks/measurements"; import { useTimezone } from "@/lib/userLocalSettings/client"; export default function EditableHour({ hour: initialHour, i, j, hourGroup, metrics, isConsecutiveHour = false, className, }: { hour: ZHour, i: number, j: number, hourGroup: ZHour[], metrics: ZMetric[] | undefined, isConsecutiveHour?: boolean, className?: string; }) { const [hour, setHour] = useState(initialHour); const { mutate: updateHour, isPending } = useUpdateHour({ onSuccess: (res, req, meta) => { const { categoryCode: oldCode, comment: oldComment } = hour; const newHour = { categoryCode: parseInt(req.code!), comment: oldComment, ...res, }; setHour(newHour); // Only show toast if client screen is larger than mobile if (window.innerWidth > 640) { toast({ description: "Hour updated!", }); } }, }); const { mutate: decrementCount } = useDecrementCount({ onSuccess: (res, req) => { const oldMeasurementIndex = hour.measurements.findIndex(m => m.metricId === req.metricId); let newMeasurements; if (oldMeasurementIndex !== -1) { if (res === undefined) { // Remove the measurement if res is undefined newMeasurements = [ ...hour.measurements.slice(0, oldMeasurementIndex), ...hour.measurements.slice(oldMeasurementIndex + 1) ]; } else { // Update the measurement newMeasurements = [ ...hour.measurements.slice(0, oldMeasurementIndex), res, ...hour.measurements.slice(oldMeasurementIndex + 1) ]; } } else { // Add the new measurement newMeasurements = [...hour.measurements, res]; } const newHour = { ...hour, measurements: newMeasurements, }; setHour(newHour); toast({ description: res === undefined ? "Measurement removed!" : "Measurement updated!", }); } }); const { mutate: deleteMeasurement } = useDeleteMeasurement({ onSuccess: (_res, req) => { const newHour = { ...hour, measurements: hour.measurements.filter(m => m.metricId !== req.metricId), }; setHour(newHour); reload(newHour); toast({ description: "Measurement deleted!", }); }, onError: (error) => { toast({ description: error.message, }); }, }); const tzOffset = spacetime.now(useTimezone()).offset() / 60; const localDateTime = (h: ZHour): string => { return spacetime(h.datetime).format('{hour} {ampm}'); } useEffect(() => { // console.log(hour.categoryDesc); }, [hour]); function reload(newHour: ZHour) { setHour(newHour); } return (