Skip to content

Commit

Permalink
Add comment submit form
Browse files Browse the repository at this point in the history
  • Loading branch information
marshallku committed Feb 12, 2024
1 parent 08cf55b commit f23cdcb
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 6 deletions.
2 changes: 1 addition & 1 deletion apps/blog/app/[category]/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default async function Post({ params: { category, slug } }: PostProps) {
</Typography>
</main>
<InteractPost className={cx("__interact")} title={post.data.title} slug={post.slug} />
<Suspense fallback={<p>Loading...</p>}>
<Suspense fallback={<PostComment />}>
<Comments slug={`/${postSlug}`} />
</Suspense>
<PrevNextPost previousPost={posts[postIndex + 1]} nextPost={posts[postIndex - 1]} />
Expand Down
6 changes: 5 additions & 1 deletion apps/blog/src/components/CommentAvatar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useState } from "react";
import { useEffect, useState } from "react";
import { toURL } from "#utils/url";

const AVATAR_SIZE = 40;
Expand Down Expand Up @@ -32,6 +32,10 @@ const getAvatar = (name: string, link?: string) => {
function CommentAvatar({ name, url, postAuthor }: CommentAvatarProps) {
const [src, setSrc] = useState(getAvatar(name, url));

useEffect(() => {
setSrc(getAvatar(name, url));
}, [name, url]);

if (postAuthor) {
return (
<img
Expand Down
75 changes: 75 additions & 0 deletions apps/blog/src/components/CommentForm/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.comment-form {
display: flex;
width: clamp(0px, map-get($container-width, small), 100%);
margin: 24px auto;
padding: 0 12px;

&__avatar {
margin: 12px 12px 0 0;
}

&__form {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
margin-top: 24px;
padding: 12px;
background-color: color(comment-2);
border-radius: 8px;

&::after {
content: "";
box-sizing: content-box;
position: absolute;
width: 17.5px;
height: 25px;
border: 0 solid color(comment-2);
border-width: 0 20px;
border-radius: 50%;
clip: rect(0, 41px, 15px, 28px);
display: block;
z-index: 1;
left: -37.4px;
top: 5px;
}
}

&__input {
@include typography(b2);
margin-bottom: 12px;
padding: 4px 12px;
background-color: color(comment);
border-radius: 4px;
}

&__textarea {
@include typography(b1);
height: 7em;
margin-top: 12px;
padding: 8px 12px;
background-color: color(comment);
border-radius: 4px;
resize: none;
}

&__buttons {
margin-top: 24px;
text-align: right;
}

&__submit {
display: inline-flex;
padding: 8px;
justify-content: center;
align-items: center;
border-radius: 50%;
color: color(comment-2);
background-color: color(theme);
transition: background-color 0.3s $ease-in-out-cubic;

&:disabled {
background-color: color(comment);
}
}
}
65 changes: 65 additions & 0 deletions apps/blog/src/components/CommentForm/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"use client";

import { useFormState } from "react-dom";
import { classNames } from "@marshallku/utils";
import { submitComment } from "app/[category]/[...slug]/action";
import Button from "#components/Button";
import styles from "./index.module.scss";
import Typography from "#components/Typography";
import CommentAvatar from "#components/CommentAvatar";
import { useState } from "react";
import { Icon } from "@marshallku/icon";

const cx = classNames(styles, "comment-form");

const initialState = {
message: "",
};

function CommentForm() {
const [state, formAction] = useFormState(submitComment, initialState);
const [name, setName] = useState("");
const [body, setBody] = useState("");

return (
<div className={cx()}>
<figure className={cx("__avatar")}>
<CommentAvatar name={name} />
</figure>
<form action={formAction} className={cx("__form")}>
<Typography variant="c1" marginBottom={16}>
댓글을 남겨주세요. (이메일 주소는 공개되지 않습니다.)
</Typography>
<input
className={cx("__input")}
name="name"
placeholder="이름 (미입력시 '익명')"
value={name}
onChange={({ currentTarget: { value } }) => {
setName(value);
}}
/>
<input className={cx("__input")} name="url" inputMode="url" placeholder="주소" />
<input className={cx("__input")} name="email" inputMode="email" placeholder="이메일 (비공개)" />
<textarea
className={cx("__textarea")}
name="body"
value={body}
placeholder="댓글을 입력해 주세요."
onChange={({ currentTarget: { value } }) => {
setBody(value);
}}
/>
{state.message && <Typography variant="c2">{state.message}</Typography>}
<div className={cx("__buttons")}>
<button type="submit" disabled={!body} className={cx("__submit")}>
<Icon name="arrow-downward" size={24} />
<span className="sr-only">댓글 남기기</span>
</button>
</div>
</form>
</div>
);
}

export default CommentForm;
2 changes: 1 addition & 1 deletion apps/blog/src/components/CommentList/index.module.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.comment-list {
width: clamp(0px, map-get($container-width, small), 100%);
margin: 24px auto 36px;
margin: 24px auto;
padding: 0 12px;
}
2 changes: 2 additions & 0 deletions apps/blog/src/components/PostComment/index.module.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.post-comment {
border-top: 2px solid color(main);
border-bottom: 2px solid color(main);
}
6 changes: 4 additions & 2 deletions apps/blog/src/components/PostComment/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { classNames } from "@marshallku/utils";
import { type CommentListResponse } from "#api";
import CommentForm from "#components/CommentForm";
import CommentList from "#components/CommentList";
import styles from "./index.module.scss";

export interface PostCommentProps {
data: CommentListResponse;
data?: CommentListResponse;
}

const cx = classNames(styles, "post-comment");

function PostComment({ data }: PostCommentProps) {
return (
<div className={cx()}>
<CommentList data={data} />
<CommentForm />
{data && <CommentList data={data} />}
</div>
);
}
Expand Down
5 changes: 4 additions & 1 deletion apps/blog/src/styles/reset.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ caption,
tbody,
tfoot,
thead,
textarea,
tr,
th,
td,
Expand Down Expand Up @@ -94,7 +95,9 @@ video {
vertical-align: baseline;
}

html {
html,
input,
textarea {
font-family:
"Pretendard Variable",
Pretendard,
Expand Down

0 comments on commit f23cdcb

Please sign in to comment.