This commit is contained in:
2025-03-11 15:51:31 +01:00
parent bccd089c7f
commit 7135e34699
34 changed files with 633 additions and 130 deletions
+11 -4
View File
@@ -1,22 +1,29 @@
"use server";
import { articleSchema } from "@/lib/validation/zod/article";
import { appRoutes } from "@/config";
import {
articleSchema,
createArticleSchema,
} from "@/lib/validation/zod/article";
import { api } from "@/trpc/server";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { z } from "zod";
export async function createArticle(article: z.infer<typeof articleSchema>) {
export async function createArticle(
article: z.infer<typeof createArticleSchema>,
) {
const result = await api.article.create({
article,
});
if (!result[0]?.slug?.length) return false;
return redirect(`/artikel/${result[0].slug}/edit`);
return redirect(appRoutes.editArticle(result[0].slug));
}
export async function updateArticle(
article: z.infer<typeof articleSchema>,
articleId: string,
) {
console.log("Content :: action", JSON.stringify(article.content));
const result = await api.article.update({
article,
articleId,
+2 -1
View File
@@ -3,7 +3,7 @@ import { categoryRouter } from "@/server/api/routers/category";
import { createCallerFactory, createTRPCRouter } from "@/server/api/trpc";
import { usersRouter } from "./routers/users";
import { authorRouter } from "./routers/author";
import { appRouter as globalRouter } from "./routers/app";
/**
* This is the primary router for your server.
*
@@ -14,6 +14,7 @@ export const appRouter = createTRPCRouter({
category: categoryRouter,
users: usersRouter,
author: authorRouter,
app: globalRouter,
});
// export type definition of API
+16
View File
@@ -0,0 +1,16 @@
import { createTRPCRouter, publicProcedure } from "../trpc";
export const appRouter = createTRPCRouter({
getSidebarContent: publicProcedure.query(async ({ ctx }) => {
return await ctx.db.query.categories.findMany({
with: {
articles: {
columns: {
title: true,
slug: true,
},
},
},
});
}),
});
+11 -2
View File
@@ -6,7 +6,10 @@ import {
publicProcedure,
} from "@/server/api/trpc";
import { articles } from "@/server/db/schema";
import { articleSchema } from "@/lib/validation/zod/article";
import {
articleSchema,
createArticleSchema,
} from "@/lib/validation/zod/article";
import { count, eq } from "drizzle-orm";
import { hasPermission, Role } from "@/lib/validation/permissions";
import { generateSlug } from "@/lib/utils";
@@ -18,6 +21,7 @@ export const articleRouter = createTRPCRouter({
.query(async ({ ctx, input }) => {
return await ctx.db.query.articles.findFirst({
where: eq(articles.slug, input.slug),
with: { category: true },
});
}),
@@ -60,7 +64,7 @@ export const articleRouter = createTRPCRouter({
}),
// mutations
create: protectedProcedure
.input(z.object({ article: articleSchema }))
.input(z.object({ article: createArticleSchema }))
.mutation(async ({ ctx, input }) => {
const isEditor = hasPermission(ctx.session.user.role, Role.EDITOR);
if (!isEditor) {
@@ -81,6 +85,11 @@ export const articleRouter = createTRPCRouter({
if (!isEditor) {
throw new Error("You are not allowed to update articles");
}
console.log(
"Content before save",
JSON.stringify(input.article.content),
);
return await ctx.db
.update(articles)
.set(input.article)
+7 -5
View File
@@ -4,6 +4,7 @@ import {
boolean,
index,
integer,
jsonb,
pgTableCreator,
primaryKey,
text,
@@ -11,6 +12,8 @@ import {
varchar,
} from "drizzle-orm/pg-core";
import { type AdapterAccount } from "next-auth/adapters";
import { type JSONContent } from "@tiptap/react";
/**
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
* database instance for multiple projects.
@@ -27,9 +30,9 @@ export const articles = createTable(
.$defaultFn(() => createId())
.notNull(),
title: varchar("title", { length: 256 }),
slug: varchar("slug", { length: 256 }).unique(),
slug: varchar("slug", { length: 256 }).unique().notNull(),
authorId: varchar("author_id", { length: 255 }),
content: text("content"),
content: text("content"),
categoryId: varchar("category_id", { length: 255 }),
published: boolean("published").default(false),
createdAt: timestamp("created_at", { withTimezone: true })
@@ -44,9 +47,8 @@ export const articles = createTable(
}),
);
export type Article = typeof articles.$inferSelect;
export const articleRelations = relations(articles, ({ one }) => ({
categories: one(categories, {
category: one(categories, {
fields: [articles.categoryId],
references: [categories.id],
}),
@@ -60,7 +62,7 @@ export const categories = createTable(
.$defaultFn(() => createId())
.notNull(),
name: varchar("name", { length: 256 }),
slug: varchar("slug", { length: 256 }).unique(),
slug: varchar("slug", { length: 256 }).unique().notNull(),
createdAt: timestamp("created_at", { withTimezone: true })
.default(sql`CURRENT_TIMESTAMP`)