.
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
import { Article } from "@/server/db/schema";
|
||||
import Link from "next/link";
|
||||
import React from "react";
|
||||
|
||||
function ArticleCard({
|
||||
title,
|
||||
slug,
|
||||
createdAt,
|
||||
}: Pick<Article, "title" | "slug" | "createdAt">) {
|
||||
return (
|
||||
<Link href={`/artikel/${slug}`}>
|
||||
<div className="rounded-md border p-4">{title}</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export default ArticleCard;
|
||||
@@ -1,81 +0,0 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { articleSchema } from "@/lib/validation/zod/article";
|
||||
import { createArticle } from "@/server/actions/article";
|
||||
|
||||
const formSchema = articleSchema.pick({
|
||||
title: true,
|
||||
});
|
||||
|
||||
function CreateArticleDialog() {
|
||||
const [open, setOpen] = React.useState<boolean>(false);
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
title: "",
|
||||
},
|
||||
});
|
||||
|
||||
// 2. Define a submit handler.
|
||||
async function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
setOpen(false);
|
||||
await createArticle(values);
|
||||
}
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<Button asChild>
|
||||
<DialogTrigger className="w-full">Artikel Erstellen</DialogTrigger>
|
||||
</Button>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Neuen Artikel Erstellen</DialogTitle>
|
||||
<DialogDescription></DialogDescription>
|
||||
</DialogHeader>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Titel</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Artikel Titel" {...field} />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit">Artikel Erstellen</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export default CreateArticleDialog;
|
||||
@@ -1,3 +1,4 @@
|
||||
import { appRoutes } from "@/config";
|
||||
import { Category } from "@/server/db/schema";
|
||||
import Link from "next/link";
|
||||
import React from "react";
|
||||
@@ -8,7 +9,7 @@ function CategoryCard({
|
||||
createdAt,
|
||||
}: Pick<Category, "name" | "slug" | "createdAt">) {
|
||||
return (
|
||||
<Link href={`/kategorie/${slug}`}>
|
||||
<Link href={appRoutes.category(slug)}>
|
||||
<div className="rounded-md border p-4">{name}</div>
|
||||
</Link>
|
||||
);
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import { auth } from "@/server/auth";
|
||||
import { api } from "@/trpc/server";
|
||||
import { notFound } from "next/navigation";
|
||||
import React from "react";
|
||||
import Editor from "@/components/article/editor/article-form";
|
||||
import ArticleEditor from "@/components/article/article-form";
|
||||
|
||||
async function Page({ params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params;
|
||||
@@ -13,7 +13,7 @@ async function Page({ params }: { params: Promise<{ slug: string }> }) {
|
||||
: false;
|
||||
const article = await api.article.get({ slug: slug });
|
||||
if (!article || !isEditor) return notFound();
|
||||
return <Editor server_article={article} />;
|
||||
return <ArticleEditor server_article={article} />;
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -1,4 +1,7 @@
|
||||
import RenderArticle from "@/components/article/render-article";
|
||||
import BreadNavigator from "@/components/bread-navigator";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { appRoutes } from "@/config";
|
||||
import { hasPermission, Role } from "@/lib/validation/permissions";
|
||||
import { auth } from "@/server/auth";
|
||||
import { api } from "@/trpc/server";
|
||||
@@ -16,13 +19,28 @@ async function Page({ params }: { params: Promise<{ slug: string }> }) {
|
||||
? hasPermission(session.user.role, Role.EDITOR)
|
||||
: false;
|
||||
return (
|
||||
<div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<h1 className="text-4xl font-bold">{article.title}</h1>
|
||||
<div className="w-full">
|
||||
<BreadNavigator
|
||||
links={[
|
||||
...(article?.category
|
||||
? [
|
||||
{
|
||||
label: article.category.name!,
|
||||
href: appRoutes.category(article.category.slug),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{ label: "Artikel", href: appRoutes.allArticles },
|
||||
{ label: article.title!, href: appRoutes.article(article.slug) },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
{isEditor && (
|
||||
<div className="space-x-2">
|
||||
<div className="flex w-full justify-end space-x-2">
|
||||
<Button asChild variant={"outline"}>
|
||||
<Link href={`/artikel/${article.slug}/edit`}>
|
||||
<Link href={appRoutes.editArticle(article.slug)}>
|
||||
<Edit className="size-4" />
|
||||
<span>Bearbeiten</span>
|
||||
</Link>
|
||||
@@ -33,6 +51,11 @@ async function Page({ params }: { params: Promise<{ slug: string }> }) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-4xl font-bold">{article.title}</h1>
|
||||
|
||||
{article?.content?.length ? (
|
||||
<RenderArticle content={article.content} />
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import { api } from "@/trpc/server";
|
||||
import { Edit } from "lucide-react";
|
||||
import { notFound } from "next/navigation";
|
||||
import React from "react";
|
||||
import ArticleCard from "../../_components/article/article-card";
|
||||
import ArticleCard from "../../../../components/article/article-card";
|
||||
import { appRoutes } from "@/config";
|
||||
|
||||
async function Page({ params }: { params: Promise<{ name: string }> }) {
|
||||
const { name } = await params;
|
||||
@@ -22,10 +23,10 @@ async function Page({ params }: { params: Promise<{ name: string }> }) {
|
||||
<div className="flex items-center justify-between">
|
||||
<BreadNavigator
|
||||
links={[
|
||||
{ label: "Kategorie", href: "/kategorie" },
|
||||
{ label: "Kategorie", href: appRoutes.allCategories },
|
||||
{
|
||||
label: name,
|
||||
href: `/kategorie/${name}`,
|
||||
href: appRoutes.category(name),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { auth } from "@/server/auth";
|
||||
import { api } from "@/trpc/server";
|
||||
import Link from "next/link";
|
||||
import GlobalStats from "./_components/global-stats";
|
||||
import ArticleCard from "./_components/article/article-card";
|
||||
import ArticleCard from "../../components/article/article-card";
|
||||
import CategoryCard from "./_components/category/category-card";
|
||||
|
||||
export default async function Home() {
|
||||
|
||||
@@ -14,7 +14,7 @@ import Link from "next/link";
|
||||
import SidebarLink from "@/components/layout/sidebar-link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { LogOutIcon } from "lucide-react";
|
||||
import { appConfig } from "@/app.config";
|
||||
import { appConfig } from "@/config/app.config";
|
||||
|
||||
const data = {
|
||||
navMain: [
|
||||
|
||||
Reference in New Issue
Block a user