added deleted comment indicator
This commit is contained in:
parent
4a67f1f94b
commit
b2cd0fc560
@ -60,7 +60,6 @@
|
|||||||
"lucide-react": "^0.477.0",
|
"lucide-react": "^0.477.0",
|
||||||
"next": "^15.0.1",
|
"next": "^15.0.1",
|
||||||
"next-auth": "5.0.0-beta.25",
|
"next-auth": "5.0.0-beta.25",
|
||||||
"next-safe-action": "^7.10.4",
|
|
||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.4",
|
||||||
"novel": "^1.0.2",
|
"novel": "^1.0.2",
|
||||||
"postgres": "^3.4.4",
|
"postgres": "^3.4.4",
|
||||||
|
|||||||
48
pnpm-lock.yaml
generated
48
pnpm-lock.yaml
generated
@ -122,9 +122,6 @@ importers:
|
|||||||
next-auth:
|
next-auth:
|
||||||
specifier: 5.0.0-beta.25
|
specifier: 5.0.0-beta.25
|
||||||
version: 5.0.0-beta.25(next@15.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 5.0.0-beta.25(next@15.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
next-safe-action:
|
|
||||||
specifier: ^7.10.4
|
|
||||||
version: 7.10.4(next@15.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@3.24.2)
|
|
||||||
next-themes:
|
next-themes:
|
||||||
specifier: ^0.4.4
|
specifier: ^0.4.4
|
||||||
version: 0.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 0.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@ -3572,27 +3569,6 @@ packages:
|
|||||||
nodemailer:
|
nodemailer:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
next-safe-action@7.10.4:
|
|
||||||
resolution: {integrity: sha512-rZE89DTNgiTJ8oPQBOZm+jd0Uf/pLkN+GE3PndER6vWqHGYGN7HMLvhpggkbE8W4TGp+qM7CPyrXye1wCjZLVg==}
|
|
||||||
engines: {node: '>=18.17'}
|
|
||||||
peerDependencies:
|
|
||||||
'@sinclair/typebox': '>= 0.33.3'
|
|
||||||
next: '>= 14.0.0'
|
|
||||||
react: '>= 18.2.0'
|
|
||||||
react-dom: '>= 18.2.0'
|
|
||||||
valibot: '>= 0.36.0'
|
|
||||||
yup: '>= 1.0.0'
|
|
||||||
zod: '>= 3.0.0'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@sinclair/typebox':
|
|
||||||
optional: true
|
|
||||||
valibot:
|
|
||||||
optional: true
|
|
||||||
yup:
|
|
||||||
optional: true
|
|
||||||
zod:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
next-themes@0.4.4:
|
next-themes@0.4.4:
|
||||||
resolution: {integrity: sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==}
|
resolution: {integrity: sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -7182,8 +7158,8 @@ snapshots:
|
|||||||
'@typescript-eslint/parser': 8.26.0(eslint@8.57.1)(typescript@5.8.2)
|
'@typescript-eslint/parser': 8.26.0(eslint@8.57.1)(typescript@5.8.2)
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.1)
|
||||||
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
|
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
|
||||||
eslint-plugin-react: 7.37.4(eslint@8.57.1)
|
eslint-plugin-react: 7.37.4(eslint@8.57.1)
|
||||||
eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1)
|
eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1)
|
||||||
@ -7202,7 +7178,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1):
|
eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nolyfill/is-core-module': 1.0.39
|
'@nolyfill/is-core-module': 1.0.39
|
||||||
debug: 4.4.0(supports-color@5.5.0)
|
debug: 4.4.0(supports-color@5.5.0)
|
||||||
@ -7213,18 +7189,18 @@ snapshots:
|
|||||||
stable-hash: 0.0.4
|
stable-hash: 0.0.4
|
||||||
tinyglobby: 0.2.12
|
tinyglobby: 0.2.12
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
|
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/parser': 8.26.0(eslint@8.57.1)(typescript@5.8.2)
|
'@typescript-eslint/parser': 8.26.0(eslint@8.57.1)(typescript@5.8.2)
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@ -7232,7 +7208,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
|
|
||||||
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
|
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rtsao/scc': 1.1.0
|
'@rtsao/scc': 1.1.0
|
||||||
array-includes: 3.1.8
|
array-includes: 3.1.8
|
||||||
@ -7243,7 +7219,7 @@ snapshots:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.1)
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
is-core-module: 2.16.1
|
is-core-module: 2.16.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@ -8260,14 +8236,6 @@ snapshots:
|
|||||||
next: 15.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
next: 15.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
next-safe-action@7.10.4(next@15.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@3.24.2):
|
|
||||||
dependencies:
|
|
||||||
next: 15.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
|
||||||
react: 18.3.1
|
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
|
||||||
optionalDependencies:
|
|
||||||
zod: 3.24.2
|
|
||||||
|
|
||||||
next-themes@0.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
next-themes@0.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import {
|
|||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { commentSchema } from "@/lib/validation/zod/comment";
|
import { commentSchema } from "@/lib/validation/zod/comment";
|
||||||
import CommentEditor from "../editor/comment-editor";
|
import CommentEditor from "../editor/comment-editor";
|
||||||
import { createComment } from "@/server/actions/comment";
|
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { EditorInstance } from "novel";
|
import { EditorInstance } from "novel";
|
||||||
import { XIcon } from "lucide-react";
|
import { XIcon } from "lucide-react";
|
||||||
@ -39,8 +38,15 @@ function CommentForm({
|
|||||||
onSuccess: (comment) => {
|
onSuccess: (comment) => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
socket?.emit(ADD_COMMENT_EVENT, comment);
|
socket?.emit(ADD_COMMENT_EVENT, comment);
|
||||||
|
|
||||||
toast.success("Kommentar hinzugefügt.");
|
toast.success("Kommentar hinzugefügt.");
|
||||||
|
setTimeout(() => {
|
||||||
|
const el = commentRefs.current.get(comment?.id!);
|
||||||
|
el?.scrollIntoView({
|
||||||
|
behavior: "smooth",
|
||||||
|
block: "start",
|
||||||
|
});
|
||||||
|
el?.classList.add("animate-fade-in");
|
||||||
|
}, 500);
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@ -65,15 +71,6 @@ function CommentForm({
|
|||||||
form.reset();
|
form.reset();
|
||||||
editor?.commands?.clearContent();
|
editor?.commands?.clearContent();
|
||||||
removeReplyComment();
|
removeReplyComment();
|
||||||
// setTimeout(() => {
|
|
||||||
// const el = commentRefs.current.get(res?.data?.data!);
|
|
||||||
// console.log("el", el);
|
|
||||||
// el?.scrollIntoView({
|
|
||||||
// behavior: "smooth",
|
|
||||||
// block: "start",
|
|
||||||
// });
|
|
||||||
// el?.classList.add("animate-fade-in");
|
|
||||||
// }, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -116,6 +113,7 @@ function CommentForm({
|
|||||||
type="submit"
|
type="submit"
|
||||||
className="ml-auto h-max py-1"
|
className="ml-auto h-max py-1"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
disabled={loading || !form.formState.isDirty}
|
||||||
>
|
>
|
||||||
Absenden
|
Absenden
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { buildCommentTree } from "@/lib/utils/comments";
|
|||||||
import Comment from "./comment";
|
import Comment from "./comment";
|
||||||
import { useSession } from "../session-provider";
|
import { useSession } from "../session-provider";
|
||||||
|
|
||||||
function CommentList({
|
export const CommentList = React.memo(function ({
|
||||||
comments,
|
comments,
|
||||||
setReplyComment,
|
setReplyComment,
|
||||||
commentRefs,
|
commentRefs,
|
||||||
@ -29,5 +29,5 @@ function CommentList({
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
export default CommentList;
|
export default CommentList;
|
||||||
|
|||||||
@ -19,32 +19,22 @@ const Comment = React.memo(
|
|||||||
level?: number;
|
level?: number;
|
||||||
}) => {
|
}) => {
|
||||||
const { comment, setReplyComment, setRef, session, level = 0 } = props;
|
const { comment, setReplyComment, setRef, session, level = 0 } = props;
|
||||||
const isAuthor = session?.user?.id === comment.author?.id;
|
|
||||||
|
const isAuthor = session?.user?.id === comment?.author?.id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// <div className="">
|
|
||||||
|
|
||||||
// </div>
|
|
||||||
// <div className="comment-replies" style={{ marginLeft: "20px" }}>
|
|
||||||
// {comment.children.map((child) => (
|
|
||||||
// <Comment
|
|
||||||
// key={child.id}
|
|
||||||
// comment={child}
|
|
||||||
// setReplyComment={setReplyComment}
|
|
||||||
// setRef={(el) => setRef(el)} // Ensure this is stable
|
|
||||||
// session={session}
|
|
||||||
// level={level + 1}
|
|
||||||
// />
|
|
||||||
// ))}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
level > 0 && "ml-4 border-l",
|
level > 0 && "ml-4 border-l",
|
||||||
comment.children.length && "border-l",
|
comment?.children?.length && "border-l",
|
||||||
|
comment?.missingParent && "border-l",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
{comment.missingParent && (
|
||||||
|
<div className="p-4 pt-0 text-sm italic text-muted-foreground">
|
||||||
|
Antwort auf: Kommentar wurde gelöscht
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className="flex items-start gap-2 pl-2 hover:bg-muted"
|
className="flex items-start gap-2 pl-2 hover:bg-muted"
|
||||||
ref={setRef}
|
ref={setRef}
|
||||||
@ -57,7 +47,7 @@ const Comment = React.memo(
|
|||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex w-full items-center gap-2">
|
<div className="flex w-full items-center gap-2">
|
||||||
<h5 className="text-lg font-medium capitalize">
|
<h5 className="text-lg font-medium capitalize">
|
||||||
{comment.author?.name} {level}
|
{comment.author?.name}
|
||||||
</h5>
|
</h5>
|
||||||
{isAuthor && (
|
{isAuthor && (
|
||||||
<Badge variant={"outline"} className="text-xs">
|
<Badge variant={"outline"} className="text-xs">
|
||||||
@ -85,39 +75,21 @@ const Comment = React.memo(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{comment.children && comment.children.length > 0 && (
|
{comment?.children && comment.children.length > 0 && (
|
||||||
<div className="pl-4">
|
<div className="pl-4">
|
||||||
{comment.children.map((child) => (
|
{comment.children.map((child, idx) => (
|
||||||
<Comment
|
<Comment
|
||||||
key={child.id}
|
key={child?.id ?? idx}
|
||||||
{...props}
|
{...props}
|
||||||
comment={child}
|
comment={child as CommentNode}
|
||||||
level={level + 1}
|
level={level + 1}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
// <div className={`flex ${level > 0 ? "ml-4" : ""} w-full`}>
|
|
||||||
// <div
|
|
||||||
// className={`${comment.children?.length || level > 0 ? "border-l" : ""} w-full pl-2`}
|
|
||||||
// >
|
|
||||||
|
|
||||||
// {comment.children && comment.children.length > 0 && (
|
|
||||||
// <div className="pl-4">
|
|
||||||
// {comment.children.map((child) => (
|
|
||||||
// <Comment
|
|
||||||
// key={child.id}
|
|
||||||
// {...props}
|
|
||||||
// comment={child}
|
|
||||||
// level={level + 1}
|
|
||||||
// />
|
|
||||||
// ))}
|
|
||||||
// </div>
|
|
||||||
// )}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Comment;
|
export default Comment;
|
||||||
|
|||||||
@ -9,28 +9,32 @@ export function buildCommentTree(comments: Comment[]): Array<CommentNode> {
|
|||||||
commentMap[comment.id] = {
|
commentMap[comment.id] = {
|
||||||
...comment,
|
...comment,
|
||||||
children: [],
|
children: [],
|
||||||
|
missingParent: false,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Second pass: Build the tree by connecting children to parents
|
// Second pass: Build the tree by connecting children to parents
|
||||||
const rootComments: CommentNode[] = [];
|
const rootComments: Array<CommentNode> = [];
|
||||||
|
|
||||||
comments.forEach((comment) => {
|
comments.forEach((comment) => {
|
||||||
const node = commentMap[comment.id];
|
const node = commentMap[comment.id]!;
|
||||||
|
|
||||||
// If parentId is null or empty string, it's a root comment
|
// If parentId is null or empty string, it's a root comment
|
||||||
if (!comment.parentId) {
|
if (!comment.parentId) {
|
||||||
rootComments.push(node!);
|
rootComments.push(node);
|
||||||
} else {
|
} else {
|
||||||
// Add as a child to its parent if parent exists
|
|
||||||
const parent = commentMap[comment.parentId];
|
const parent = commentMap[comment.parentId];
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent.children.push(node!);
|
// Add as a child to its parent if parent exists
|
||||||
|
parent.children.push(node);
|
||||||
} else {
|
} else {
|
||||||
// Parent doesn't exist, treat as root comment
|
// Parent doesn't exist, treat as root comment
|
||||||
|
// Mark that the parent is missing
|
||||||
|
node.missingParent = true;
|
||||||
rootComments.push(node!);
|
rootComments.push(node!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return rootComments;
|
return rootComments;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,48 +0,0 @@
|
|||||||
"use server";
|
|
||||||
|
|
||||||
import { appRoutes } from "@/config";
|
|
||||||
import { commentSchema } from "@/lib/validation/zod/comment";
|
|
||||||
import { api } from "@/trpc/server";
|
|
||||||
import { revalidatePath } from "next/cache";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { actionClient } from ".";
|
|
||||||
|
|
||||||
export const createComment = actionClient
|
|
||||||
.schema(
|
|
||||||
z.object({
|
|
||||||
comment: commentSchema,
|
|
||||||
articleId: z.string(),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.action(async ({ parsedInput: { comment, articleId } }) => {
|
|
||||||
const commentId = await api.comment.create({
|
|
||||||
comment,
|
|
||||||
articleId,
|
|
||||||
});
|
|
||||||
if (!commentId)
|
|
||||||
return {
|
|
||||||
failure: "Incorrect credentials",
|
|
||||||
};
|
|
||||||
revalidatePath(appRoutes.article(articleId));
|
|
||||||
return {
|
|
||||||
data: commentId,
|
|
||||||
success: true,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
export async function deleteComment(commentId: string) {
|
|
||||||
const articleId = (
|
|
||||||
await api.comment.delete({
|
|
||||||
commentId,
|
|
||||||
})
|
|
||||||
)?.articleId;
|
|
||||||
if (!articleId)
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
message: "Error deleting comment",
|
|
||||||
};
|
|
||||||
revalidatePath(appRoutes.article(articleId));
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import { createSafeActionClient } from "next-safe-action";
|
|
||||||
|
|
||||||
export const actionClient = createSafeActionClient();
|
|
||||||
@ -60,7 +60,8 @@ export type Comment = typeof comments.$inferSelect & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type CommentNode = Comment & {
|
export type CommentNode = Comment & {
|
||||||
children: CommentNode[];
|
children: Array<CommentNode | DeletedNode>;
|
||||||
|
missingParent: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const commentVotes = createTable(
|
export const commentVotes = createTable(
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const createSocketServer = () => {
|
|||||||
if (!global.io) {
|
if (!global.io) {
|
||||||
global.io = new Server(server, {
|
global.io = new Server(server, {
|
||||||
cors: {
|
cors: {
|
||||||
origin,
|
origin: "*",
|
||||||
methods: ["GET", "POST"],
|
methods: ["GET", "POST"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user