import Link from "next/link"; import { useEffect, useState } from "react"; import { ActionButton } from "@/components/ui/action-button"; import { Button } from "@/components/ui/button"; import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { toast } from "@/components/ui/use-toast"; import { api } from "@/lib/trpc"; import { zodResolver } from "@hookform/resolvers/zod"; import { TRPCClientError } from "@trpc/client"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { Textarea } from "@/components/ui/textarea"; import { zMetricSchema } from "@lifetracker/shared/types/metrics"; import { Icon, } from "@/components/ui/icon"; import { icons } from "lucide-react"; import { titleCase } from "title-case"; type CreateMetricSchema = z.infer; export default function AddMetricDialog({ initialMetric = undefined, children, }: { initialMetric?: CreateMetricSchema; children?: React.ReactNode; }) { const apiUtils = api.useUtils(); const [isOpen, onOpenChange] = useState(false); const form = useForm({ resolver: zodResolver(zMetricSchema), defaultValues: { type: "count", ...initialMetric, }, }); const handleSuccess = (message: string) => { toast({ description: message, }); apiUtils.metrics.list.invalidate(); onOpenChange(false); }; const handleError = (error: any, defaultMessage: string) => { if (error instanceof TRPCClientError) { toast({ variant: "destructive", description: error.message, }); } else { toast({ variant: "destructive", description: defaultMessage, }); } }; const { mutate, isPending } = initialMetric ? api.metrics.update.useMutation({ onSuccess: () => handleSuccess("Metric updated successfully"), onError: (error) => handleError(error, "Failed to update metric"), }) : api.metrics.create.useMutation({ onSuccess: () => handleSuccess("New metric created successfully"), onError: (error) => handleError(error, "Failed to create metric"), }); useEffect(() => { if (!isOpen) { form.reset(); } }, [isOpen, form]); const [icon, setIcon] = useState("FileQuestion"); if (initialMetric?.icon) { useEffect(() => { searchIcons(initialMetric.icon); }, []); } const searchIcons = (query: string) => { const icon = Object.keys(icons).find((i) => i.toLowerCase() == (query.toLowerCase())); if (icon) { setIcon(icon); } else { setIcon("FileQuestion"); return; } } return ( {children} {initialMetric ? "Update " + initialMetric.name : "New " + titleCase(form.watch('type')) + " Metric" }
mutate(val))}>
( )} /> ( )} /> ( )} />
( {/* Description */}