import { experimental_trpcMiddleware, TRPCError } from "@trpc/server"; import { and, desc, eq, inArray, notExists } from "drizzle-orm"; import { z } from "zod"; import { SqliteError } from "@lifetracker/db"; import { days, } from "@lifetracker/db/schema"; import { zDaySchema, ZDay } from "@lifetracker/shared/types/days"; import type { Context } from "../index"; import { authedProcedure, router } from "../index"; import { format } from "date-fns"; import { TZDate } from "@date-fns/tz"; function dateFromInput(input: { dateQuery: string }) { let t: string; if (input.dateQuery == "today") { t = TZDate.tz("America/Los_Angeles"); } else { t = new TZDate(input.dateQuery, "Etc/UTC"); } return format(t, "yyyy-MM-dd") + "T00:00:00"; } async function createDay(date: string, ctx: Context) { return await ctx.db.transaction(async (trx) => { try { const result = await trx .insert(days) .values({ date: date, }) .returning({ id: days.id, date: days.date, mood: days.mood, comment: days.comment, }); return result[0]; } catch (e) { console.log(e); if (e instanceof SqliteError) { if (e.code == "SQLITE_CONSTRAINT_UNIQUE") { throw new TRPCError({ code: "BAD_REQUEST", message: "This day already exists", }); } } throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Something went wrong", }); } }); } export const daysAppRouter = router({ get: authedProcedure .input(z.object({ dateQuery: z.string(), })) .output(zDaySchema) .query(async ({ input, ctx }) => { const date = dateFromInput(input); const res = await ctx.db .select({ id: days.id, date: days.date, mood: days.mood, comment: days.comment, }) .from(days) .where(eq(days.date, date)); const day = res.length == 0 ? createDay(date, ctx) : res[0]; return day; }), update: authedProcedure .input( z.object({ mood: z.string().optional().or(z.number()), comment: z.string().optional(), dateQuery: z.string(), }), ) .mutation(async ({ input, ctx }) => { const { dateQuery, ...updatedProps } = input; // Convert mood to number, if it exists if (updatedProps.mood) { updatedProps.mood = parseInt(updatedProps.mood); } console.log(dateQuery, "::", dateFromInput({ dateQuery: dateQuery })); await ctx.db .update(days) .set(updatedProps) .where(eq(days.date, dateFromInput({ dateQuery: dateQuery }))); }), });