Fix measurements api post logic for hour.datetime
This commit is contained in:
parent
10b1ed944d
commit
9782d3642c
@ -21,8 +21,7 @@ export const POST = (req: NextRequest) =>
|
|||||||
// })).id;
|
// })).id;
|
||||||
|
|
||||||
const hour = await api.hours.get({
|
const hour = await api.hours.get({
|
||||||
dateQuery: datetime.format("iso-short"),
|
dateQuery: spacetime(datetime).startOf("hour").format("iso"),
|
||||||
time: datetime.hour(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import { ZMetric } from "@lifetracker/shared/types/metrics";
|
|||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Icon } from "@/components/ui/icon";
|
import { Icon } from "@/components/ui/icon";
|
||||||
import { titleCase } from "title-case";
|
import { titleCase } from "title-case";
|
||||||
import { useDecrementCount } from "@lifetracker/shared-react/hooks/measurements";
|
import { useDecrementCount, useDeleteMeasurement } from "@lifetracker/shared-react/hooks/measurements";
|
||||||
import { useTimezone } from "@/lib/userLocalSettings/client";
|
import { useTimezone } from "@/lib/userLocalSettings/client";
|
||||||
|
|
||||||
|
|
||||||
@ -98,6 +98,26 @@ export default function EditableHour({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 tzOffset = spacetime.now(useTimezone()).offset() / 60;
|
||||||
|
|
||||||
@ -177,7 +197,10 @@ export default function EditableHour({
|
|||||||
(<Icon name={titleCase(m.icon)} size={24}
|
(<Icon name={titleCase(m.icon)} size={24}
|
||||||
color={hour.foreground}
|
color={hour.foreground}
|
||||||
tooltip={`${m.metricName}: ${m.value} ${m.unit}`}
|
tooltip={`${m.metricName}: ${m.value} ${m.unit}`}
|
||||||
key={m.id}
|
key={m.id} className="hover:cursor-no-drop"
|
||||||
|
onClick={(e) => {
|
||||||
|
deleteMeasurement({ metricId: m.metricId, hourId: hour.id });
|
||||||
|
}}
|
||||||
/>)
|
/>)
|
||||||
: Array.from({ length: m.value }).map((_, index) =>
|
: Array.from({ length: m.value }).map((_, index) =>
|
||||||
<div key={`${m.id}-${index}`} className="hover:cursor-no-drop" onClick={(e) => {
|
<div key={`${m.id}-${index}`} className="hover:cursor-no-drop" onClick={(e) => {
|
||||||
@ -208,6 +231,6 @@ export default function EditableHour({
|
|||||||
</div>
|
</div>
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ 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 { Trash, X } from "lucide-react";
|
import { Trash, X } from "lucide-react";
|
||||||
import { useDecrementCount, useIncrementCount, useSetValue, } from "@lifetracker/shared-react/hooks/measurements";
|
import { useDecrementCount, useDeleteMeasurement, useIncrementCount, useSetValue, } from "@lifetracker/shared-react/hooks/measurements";
|
||||||
import { Separator } from "@radix-ui/react-dropdown-menu";
|
import { Separator } from "@radix-ui/react-dropdown-menu";
|
||||||
import { EditableText } from "../EditableText";
|
import { EditableText } from "../EditableText";
|
||||||
import spacetime from "spacetime";
|
import spacetime from "spacetime";
|
||||||
@ -105,6 +105,28 @@ export default function HourMeasurementsDialog({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 { mutate: decrement } = useDecrementCount({
|
const { mutate: decrement } = useDecrementCount({
|
||||||
onSuccess: (res, req) => {
|
onSuccess: (res, req) => {
|
||||||
const oldMeasurementIndex = hour.measurements.findIndex(m => m.metricId === req.metricId);
|
const oldMeasurementIndex = hour.measurements.findIndex(m => m.metricId === req.metricId);
|
||||||
@ -195,7 +217,7 @@ export default function HourMeasurementsDialog({
|
|||||||
});
|
});
|
||||||
}} />
|
}} />
|
||||||
<Trash size={16} color="red" onClick={() => {
|
<Trash size={16} color="red" onClick={() => {
|
||||||
decrement({ metricId: metric!.id!, hourId: hour.id! });
|
deleteMeasurement({ metricId: metric!.id!, hourId: hour.id! });
|
||||||
}} />
|
}} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -35,4 +35,16 @@ export function useDecrementCount(
|
|||||||
return opts[0]?.onSuccess?.(res, req, meta);
|
return opts[0]?.onSuccess?.(res, req, meta);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDeleteMeasurement(
|
||||||
|
...opts: Parameters<typeof api.measurements.delete.useMutation>
|
||||||
|
) {
|
||||||
|
const apiUtils = api.useUtils();
|
||||||
|
return api.measurements.delete.useMutation({
|
||||||
|
...opts[0],
|
||||||
|
onSuccess: (res, req, meta) => {
|
||||||
|
return opts[0]?.onSuccess?.(res, req, meta);
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@ -168,6 +168,30 @@ export const measurementsAppRouter = router({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
delete: authedProcedure
|
||||||
|
.input(z.object({ metricId: z.string(), hourId: z.string() }))
|
||||||
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const metric = await ctx.db.select().from(metrics).where(eq(metrics.id, input.metricId));
|
||||||
|
if (!metric[0]) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Metric not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Check if there is a measurement for this metric in this hour, if so, delete it, if not, throw an error
|
||||||
|
const existingMeasurement = await ctx.db.select().from(measurements).where(and(
|
||||||
|
eq(measurements.metricId, input.metricId),
|
||||||
|
eq(measurements.hourId, input.hourId),
|
||||||
|
));
|
||||||
|
if (existingMeasurement[0]) {
|
||||||
|
await ctx.db.delete(measurements).where(eq(measurements.id, existingMeasurement[0].id));
|
||||||
|
} else {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Measurement not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
timeSinceLastMeasurement: authedProcedure
|
timeSinceLastMeasurement: authedProcedure
|
||||||
.input(z.object({ metricId: z.string() }))
|
.input(z.object({ metricId: z.string() }))
|
||||||
.output(z.number())
|
.output(z.number())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user