music and animation system
This commit is contained in:
@@ -85,3 +85,21 @@ export const techStack = createTable(
|
||||
stackItems: stackItemEnum().array()
|
||||
})
|
||||
)
|
||||
|
||||
export const music = createTable(
|
||||
"music",
|
||||
(d) => ({
|
||||
id: d.uuid().primaryKey().notNull(),
|
||||
title: d.varchar({ length: 100 }).notNull(),
|
||||
description: d.text(),
|
||||
fileUrl: d.varchar("file_url", { length: 500 }).notNull(),
|
||||
fileKey: d.varchar("file_key", { length: 200 }).notNull(),
|
||||
fileName: d.varchar("file_name", { length: 200 }).notNull(),
|
||||
createdAt: d
|
||||
.timestamp({ withTimezone: true })
|
||||
.default(sql`CURRENT_TIMESTAMP`)
|
||||
.notNull()
|
||||
.$type<Date>(),
|
||||
updatedAt: d.timestamp({ withTimezone: true }).$onUpdate(() => new Date()).$type<Date>(),
|
||||
})
|
||||
)
|
||||
|
||||
@@ -5,6 +5,7 @@ import { projectRouter } from "./project";
|
||||
import { techStackRouter } from "./techStack";
|
||||
import { cvCategoryRouter } from "./cvCategory";
|
||||
import { cvEntryRouter } from "./cvEntry";
|
||||
import { musicRouter } from "./music";
|
||||
import { trpcCrudRouterFromDrizzleEntity } from "../lib";
|
||||
import { cvCategory } from "../dbschema/schema";
|
||||
|
||||
@@ -17,6 +18,7 @@ export const trpcRouter = router({
|
||||
categoryv2: cvCategoryRouter,
|
||||
entry: trpcCrudRouterFromDrizzleEntity('cvEntry').router,
|
||||
entryv2: cvEntryRouter,
|
||||
music: musicRouter,
|
||||
});
|
||||
|
||||
export type TrpcRouter = typeof trpcRouter;
|
||||
|
||||
48
src/server/routers/music.ts
Normal file
48
src/server/routers/music.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { publicProcedure, router } from "~/server/trpc";
|
||||
import { db } from "~/server/db";
|
||||
import { music } from "~/server/dbschema/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { isAdmin } from "~/app/actions";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { z } from "zod";
|
||||
import { createMusicInputSchema, updateMusicInputSchema } from "~/lib/trpc/music/schemas";
|
||||
import { utapi } from "../uploadthing";
|
||||
export const musicRouter = router({
|
||||
list: publicProcedure.query(async () => {
|
||||
let res = await db.select().from(music).orderBy(music.createdAt);
|
||||
console.log(res);
|
||||
return res;
|
||||
}),
|
||||
create: publicProcedure
|
||||
.input(
|
||||
createMusicInputSchema
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
const admin = await isAdmin();
|
||||
if (!admin) throw new TRPCError({ code: "FORBIDDEN", message: "Access denied" });
|
||||
let res = await db.insert(music).values(input).returning();
|
||||
return res.at(0);
|
||||
}),
|
||||
update: publicProcedure
|
||||
.input(
|
||||
updateMusicInputSchema
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
const admin = await isAdmin();
|
||||
if (!admin) throw new TRPCError({ code: "FORBIDDEN", message: "Access denied" });
|
||||
const { id, ...data } = input;
|
||||
return db.update(music).set(data).where(eq(music.id, id)).returning();
|
||||
}),
|
||||
delete: publicProcedure
|
||||
.input(z.object({id:z.string().uuid()}))
|
||||
.mutation(async ({ input }) => {
|
||||
const admin = await isAdmin();
|
||||
if (!admin) throw new TRPCError({ code: "FORBIDDEN", message: "Access denied" });
|
||||
let res = await db.delete(music).where(eq(music.id, input.id)).returning();
|
||||
let ret = res.at(0)
|
||||
if (ret) {
|
||||
utapi.deleteFiles(ret.fileKey)
|
||||
}
|
||||
return ret;
|
||||
}),
|
||||
});
|
||||
22
src/server/uploadthing.ts
Normal file
22
src/server/uploadthing.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { createUploadthing, type FileRouter as UploadThingFileRouter } from "uploadthing/next";
|
||||
import { UTApi } from 'uploadthing/server'
|
||||
import { isAdmin } from "~/app/actions";
|
||||
|
||||
const f = createUploadthing();
|
||||
|
||||
export const fileRouter = {
|
||||
musicUploader: f({ audio: { maxFileSize: "64MB", maxFileCount: 1 } })
|
||||
.middleware(async () => {
|
||||
const admin = await isAdmin();
|
||||
if (!admin) throw new Error("Unauthorized");
|
||||
return {};
|
||||
})
|
||||
.onUploadComplete(async ({ file }) => {
|
||||
console.log(file)
|
||||
return { fileUrl: file.ufsUrl, fileKey: file.key, fileName: file.name };
|
||||
}),
|
||||
} satisfies UploadThingFileRouter ;
|
||||
|
||||
export type FileRouter = typeof fileRouter;
|
||||
|
||||
export const utapi = new UTApi();
|
||||
Reference in New Issue
Block a user