For simple count metrics, increment/decrement from hour measurements dialog

This commit is contained in:
Ryan Pandya 2024-12-17 03:10:18 -08:00
parent 7299f4f7fb
commit e6bb87f741
2 changed files with 91 additions and 11 deletions

View File

@ -13,7 +13,8 @@ import { Icon } from "@/components/ui/icon";
import { titleCase } from "title-case"; import { titleCase } from "title-case";
import { Dialog, DialogClose, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Dialog, DialogClose, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { X } from "lucide-react"; import { X } from "lucide-react";
import { useIncrementCount, } from "@lifetracker/shared-react/hooks/measurements"; import { useDecrementCount, useIncrementCount, } from "@lifetracker/shared-react/hooks/measurements";
import { Separator } from "@radix-ui/react-dropdown-menu";
type CreateMeasurementSchema = z.infer<typeof zMeasurementSchema>; type CreateMeasurementSchema = z.infer<typeof zMeasurementSchema>;
@ -33,15 +34,14 @@ export default function HourMeasurementsDialog({
const { mutate: increment } = useIncrementCount({ const { mutate: increment } = useIncrementCount({
onSuccess: (res) => { onSuccess: (res) => {
onOpenChange(false);
const oldMeasurement = hour.measurements.find(m => m.metricId === res.metricId); const oldMeasurement = hour.measurements.find(m => m.metricId === res.metricId);
const newHour = { const newHour = {
...hour, ...hour,
measurements: oldMeasurement ? hour.measurements.map(m => m.metricId === res.metricId ? res : m) : [...hour.measurements, res], measurements: oldMeasurement ? hour.measurements.map(m => m.metricId === res.metricId ? res : m) : [...hour.measurements, res],
}; };
setHour(newHour);
reload(newHour); reload(newHour);
console.log("New hour's deets", newHour.measurements);
toast({ toast({
description: "Measurement added!", description: "Measurement added!",
}); });
@ -54,17 +54,95 @@ export default function HourMeasurementsDialog({
}, },
}); });
const { mutate: decrement } = 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);
reload(newHour);
toast({
description: res === undefined ? "Measurement removed!" : "Measurement updated!",
});
}
});
let currentMeasurements = hour.measurements.map(measurement => measurement.metricName);
// With useEffect, update currentMeasurements when hour changes
useEffect(() => {
currentMeasurements = hour.measurements.map(measurement => measurement.metricName);
}, [hour]);
return ( return (
<Dialog open={isOpen} onOpenChange={onOpenChange}> <Dialog open={isOpen} onOpenChange={onOpenChange}>
<DialogTrigger asChild>{children}</DialogTrigger> <DialogTrigger asChild>{children}</DialogTrigger>
<DialogContent> <DialogContent>
<DialogHeader> <DialogHeader>
<DialogTitle>Add Measurement</DialogTitle> <DialogTitle>Metrics for {hour.date} at {hour.datetime}</DialogTitle>
</DialogHeader> </DialogHeader>
<Separator />
{hour.measurements && hour.measurements.length > 0 ?
(<>
<div className="font-bold">Measurements</div>
<div className="mx-4 mb-4">
{hour.measurements.map(measurement => {
const metric = metrics.find(m => m.id === measurement.metricId);
return (
<div key={measurement.id} className="flex items-center justify-between">
<div className="gap-4 flex"><Icon name={titleCase(metric.icon)} size={24} />
<div>{metric.name}</div></div>
<div className="flex gap-4 items-center">
<div className="hover:cursor-pointer" onClick={() => {
decrement({ metricId: metric.id, hourId: hour.id, dayId: hour.dayId });
}} ><Icon name={"Minus"} /></div>
<div>{measurement.value}</div>
<div className="hover:cursor-pointer" onClick={() => {
increment({ metricId: metric.id, hourId: hour.id, dayId: hour.dayId });
}}><Icon name={"Plus"} /></div>
</div>
</div>
);
})}
</div>
</>)
: <>
</>
}
<div className="font-bold">Add Measurement</div>
<div className="grid" style={{ gridTemplateColumns: "repeat(6, 1fr)" }}> <div className="grid" style={{ gridTemplateColumns: "repeat(6, 1fr)" }}>
{metrics.map(metric => ( {metrics.map(metric => (
// If metric.name is in currentMeasurements, don't show it
currentMeasurements.includes(metric.name) ? null :
<button style={{ aspectRatio: "1/1" }} key={metric.id} className="flex flex-col items-center justify-center hover:opacity-50" onClick={() => { <button style={{ aspectRatio: "1/1" }} key={metric.id} className="flex flex-col items-center justify-center hover:opacity-50" onClick={() => {
increment({ metricId: metric.id, hourId: hour.id, dayId: hour.dayId }); increment({ metricId: metric.id, hourId: hour.id, dayId: hour.dayId });
// onOpenChange(false);
}}> }}>
<Icon name={titleCase(metric.icon)} size={32} /> <Icon name={titleCase(metric.icon)} size={32} />
<span className="text-sm">{metric.name}</span> <span className="text-sm">{metric.name}</span>

View File

@ -48,6 +48,7 @@ export const measurementsAppRouter = router({
return { return {
...updatedMeasurement[0], ...updatedMeasurement[0],
icon: metric[0].icon, icon: metric[0].icon,
metricName: metric[0].name,
}; };
} else { } else {
const newMeasurement = await ctx.db.insert(measurements).values({ const newMeasurement = await ctx.db.insert(measurements).values({
@ -89,6 +90,7 @@ export const measurementsAppRouter = router({
return { return {
...updatedMeasurement[0], ...updatedMeasurement[0],
icon: metric[0].icon, icon: metric[0].icon,
metricName: metric[0].name,
}; };
} else { } else {
// Delete the measurement if it's zerooo // Delete the measurement if it's zerooo