150 lines
4.9 KiB
TypeScript
150 lines
4.9 KiB
TypeScript
import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
|
|
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
|
import { date, z } from "zod";
|
|
|
|
import { SqliteError } from "@lifetracker/db";
|
|
import { categories, days, hours, colors } from "@lifetracker/db/schema";
|
|
import {
|
|
zDaySchema, ZDay, ZHour, zHourSchema
|
|
} 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";
|
|
import { dateFromInput } from "@lifetracker/shared/utils/days";
|
|
|
|
|
|
export async function hourColors(hour: ZHour, ctx: Context) {
|
|
|
|
const categoryColor = await ctx.db.select()
|
|
.from(colors)
|
|
.leftJoin(categories, eq(categories.id, hour.categoryId))
|
|
.where(and(
|
|
eq(colors.id, categories.colorId),
|
|
eq(colors.userId, ctx.user!.id)
|
|
))
|
|
|
|
// console.log(categoryColor);
|
|
if (!categoryColor[0]) {
|
|
return {
|
|
background: "inherit",
|
|
foreground: "inherit"
|
|
}
|
|
}
|
|
else {
|
|
return {
|
|
background: categoryColor[0].color.hexcode,
|
|
foreground: categoryColor[0].color.inverse,
|
|
}
|
|
}
|
|
}
|
|
|
|
export const hoursAppRouter = router({
|
|
get: authedProcedure
|
|
.input(z.object({
|
|
dateQuery: z.string(),
|
|
time: z.number()
|
|
}))
|
|
.output(zHourSchema)
|
|
.query(async ({ input, ctx }) => {
|
|
const date = dateFromInput(input);
|
|
const hourRes = await ctx.db
|
|
.select({
|
|
id: hours.id,
|
|
dayId: hours.dayId,
|
|
time: hours.time,
|
|
categoryId: hours.categoryId,
|
|
categoryCode: categories.code,
|
|
categoryName: categories.name,
|
|
categoryDesc: categories.description,
|
|
comment: hours.comment,
|
|
})
|
|
.from(hours)
|
|
.leftJoin(days, eq(days.id, hours.dayId)) // Ensure days table is joined first
|
|
.leftJoin(categories, eq(categories.id, hours.categoryId))
|
|
.where(and(eq(hours.time, input.time), eq(days.date, date))) // Use correct alias for days table
|
|
return {
|
|
date: format(date, "yyyy-MM-dd"),
|
|
...hourRes[0]
|
|
};
|
|
}),
|
|
update: authedProcedure
|
|
.input(
|
|
z.object({
|
|
hourId: z.string().optional(),
|
|
dayId: z.string().optional(),
|
|
dateQuery: z.string(),
|
|
time: z.number(),
|
|
code: z.string().optional(),
|
|
comment: z.string().nullable().optional(),
|
|
}),
|
|
)
|
|
.output(zHourSchema)
|
|
.mutation(async ({ input, ctx }) => {
|
|
const { dateQuery, time, code, ...updatedProps } = input;
|
|
let dateCondition;
|
|
if (input.dayId) {
|
|
dateCondition = eq(days.id, input.dayId)
|
|
}
|
|
else {
|
|
dateCondition = eq(days.date, dateFromInput({ dateQuery: dateQuery }));
|
|
}
|
|
|
|
const category =
|
|
code == "" ? [{
|
|
id: null,
|
|
name: null
|
|
}]
|
|
: await ctx.db.select(
|
|
{
|
|
id: categories.id,
|
|
name: categories.name,
|
|
description: categories.description
|
|
}
|
|
)
|
|
.from(categories)
|
|
.where(
|
|
and(
|
|
eq(categories.code, code),
|
|
eq(categories.userId, ctx.user!.id),
|
|
)
|
|
);
|
|
|
|
const day = await ctx.db.select()
|
|
.from(days)
|
|
.where(
|
|
and(
|
|
dateCondition,
|
|
eq(days.userId, ctx.user!.id),
|
|
)
|
|
);
|
|
|
|
const newProps = {
|
|
categoryId: category[0].id,
|
|
code: code,
|
|
...updatedProps
|
|
};
|
|
|
|
if (newProps.comment == "") { newProps.comment = null }
|
|
|
|
const hourRes = await ctx.db
|
|
.update(hours)
|
|
.set(newProps)
|
|
.where(
|
|
and(
|
|
eq(hours.time, time),
|
|
eq(hours.dayId, day[0].id),
|
|
eq(hours.userId, ctx.user!.id)
|
|
)
|
|
)
|
|
.returning();
|
|
|
|
return {
|
|
date: format(day[0].date, "yyyy-MM-dd"),
|
|
categoryName: category[0].name,
|
|
categoryDesc: category[0].description,
|
|
...hourRes[0]
|
|
}
|
|
}),
|
|
});
|