Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions .storybook/Configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,23 @@ import Accessibility from "./assets/accessibility.png";
import Theming from "./assets/theming.png";
import AddonLibrary from "./assets/addon-library.png";

export const RightArrow = () => <svg
viewBox="0 0 14 14"
width="8px"
height="14px"
style={{
marginLeft: '4px',
display: 'inline-block',
shapeRendering: 'inherit',
verticalAlign: 'middle',
fill: 'currentColor',
'path fill': 'currentColor'
export const RightArrow = () => (
<svg
viewBox="0 0 14 14"
width="8px"
height="14px"
style={{
marginLeft: "4px",
display: "inline-block",
shapeRendering: "inherit",
verticalAlign: "middle",
fill: "currentColor",
"path fill": "currentColor",
}}
>
<path d="m11.1 7.35-5.5 5.5a.5.5 0 0 1-.7-.7L10.04 7 4.9 1.85a.5.5 0 1 1 .7-.7l5.5 5.5c.2.2.2.5 0 .7Z" />
</svg>
>
<path d="m11.1 7.35-5.5 5.5a.5.5 0 0 1-.7-.7L10.04 7 4.9 1.85a.5.5 0 1 1 .7-.7l5.5 5.5c.2.2.2.5 0 .7Z" />
</svg>
);

<Meta title="Configure your project" />

Expand All @@ -39,6 +41,7 @@ export const RightArrow = () => <svg
# Configure your project

Because Storybook works separately from your app, you'll need to configure it for your specific stack and setup. Below, explore guides for configuring Storybook with popular frameworks and tools. If you get stuck, learn how you can ask for help from our community.

</div>
<div className="sb-section">
<div className="sb-section-item">
Expand Down Expand Up @@ -97,6 +100,7 @@ export const RightArrow = () => <svg
# Do more with Storybook

Now that you know the basics, let's explore other parts of Storybook that will improve your experience. This list is just to get you started. You can customise Storybook in many ways to fit your needs.

</div>

<div className="sb-section">
Expand Down Expand Up @@ -234,12 +238,12 @@ export const RightArrow = () => <svg
>Star on GitHub<RightArrow /></a>
</div>
<div className="sb-section-item">
<Image
<Image
width={33}
height={32}
layout="fixed"
src={Discord}
alt="Discord logo"
src={Discord}
alt="Discord logo"
className="sb-explore-image"
/>
<div>
Expand All @@ -252,12 +256,12 @@ export const RightArrow = () => <svg
</div>
</div>
<div className="sb-section-item">
<Image
<Image
width={32}
height={32}
layout="fixed"
src={Youtube}
alt="Youtube logo"
src={Youtube}
alt="Youtube logo"
className="sb-explore-image"
/>
<div>
Expand All @@ -270,12 +274,12 @@ export const RightArrow = () => <svg
</div>
</div>
<div className="sb-section-item">
<Image
<Image
width={33}
height={32}
layout="fixed"
src={Tutorials}
alt="A book"
src={Tutorials}
alt="A book"
className="sb-explore-image"
/>
<p>Follow guided walkthroughs on for key workflows.</p>
Expand All @@ -285,6 +289,7 @@ export const RightArrow = () => <svg
target="_blank"
>Discover tutorials<RightArrow /></a>
</div>

</div>

<style>
Expand Down
7,826 changes: 7,825 additions & 1 deletion public/404.json

Large diffs are not rendered by default.

2,294 changes: 2,293 additions & 1 deletion public/error.json

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions src/app/(pages)/albaTalk/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client";
import { useRouter } from "next/router";

const DetailPage = () => {
const router = useRouter();
const { id } = router.query;

return <div>글 상세 페이지 - ID: {id}</div>;
};

export default DetailPage;
183 changes: 183 additions & 0 deletions src/app/(pages)/albaTalk/addTalk/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
"use client";

import React from "react";
import { useForm, SubmitHandler, Controller } from "react-hook-form";
import { useRouter } from "next/navigation";
import Button from "../../../components/button/default/Button";
import BaseInput from "@/app/components/input/text/BaseInput";
import ImageInputwithPlaceHolder from "../../../components/input/file/ImageInput/ImageInputwithPlaceHolder";
import { usePost } from "../../../../hooks/usePost";

interface FormInputs {
title: string;
content: string;
imageUrl?: string;
}

export default function AddTalk() {
const {
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<FormInputs>({
defaultValues: {
title: "",
content: "",
},
});

const router = useRouter();
const { mutate: createPost, isPending } = usePost();

const onSubmit: SubmitHandler<FormInputs> = (data) => {
if (!data.title || !data.content) {
alert("제목과 내용을 입력해주세요.");
return;
}

createPost(data, {
onSuccess: (response) => {
alert("게시글이 등록되었습니다.");
const boardId = response?.id;
router.push(`/boards/${boardId}`);
},
onError: (err) => {
alert(err.message || "게시글 등록에 실패했습니다.");
},
});
};

const syncImageList = () => {
const images = document.querySelectorAll<HTMLElement>(".image-preview-item");
const urls = Array.from(images).map((img) => img.dataset.url || "");
setValue("imageUrl", urls.filter((url) => url).join(","));
};

return (
<>
<div className="flex min-h-screen w-full items-start justify-center bg-gray-50 py-8 font-nexon">
<div className="w-full max-w-[1480px] rounded-md bg-white px-4 sm:px-6 md:px-8 lg:px-10">
<div className="mb-[40px] flex h-[58px] w-full items-center justify-between border-b border-[#line-100] md:h-[78px] lg:h-[126px]">
<h1 className="flex items-center text-[18px] font-semibold md:text-[20px] lg:text-[32px]">글쓰기</h1>
<div className="hidden space-x-1 md:flex md:space-x-2 lg:space-x-4">
<Button
variant="solid"
className="bg-gray-100 text-gray-50 hover:bg-gray-200 md:h-[46px] md:w-[108px] md:text-[14px] lg:h-[58px] lg:w-[180px] lg:text-[18px]"
onClick={() => router.push("/albaTalk")}
>
취소
</Button>
<Button
variant="solid"
className="bg-primary-orange-300 text-gray-50 hover:bg-orange-400 md:h-[46px] md:w-[108px] md:text-[14px] lg:h-[58px] lg:w-[180px] lg:text-[18px]"
onClick={handleSubmit((data) => {
syncImageList();
onSubmit(data);
})}
disabled={isPending}
>
{isPending ? "등록 중..." : "등록하기"}
</Button>
</div>
</div>

<form
className="mx-auto max-w-[1432px] space-y-6 px-2 sm:px-0 md:space-y-8"
onSubmit={handleSubmit(onSubmit)}
>
<div className="w-full">
<label
htmlFor="title"
className="mb-2 flex items-center text-[16px] font-medium text-black-300 md:text-[18px] lg:text-[20px]"
>
제목<span className="ml-1 text-primary-orange-300">*</span>
</label>
<Controller
name="title"
control={control}
rules={{ required: "제목을 입력하세요." }}
render={({ field }) => (
<BaseInput
{...field}
type="text"
variant="white"
name="title"
size="w-full h-[52px] md:h-[54px] lg:h-[64px]"
placeholder="제목을 입력하세요"
errormessage={errors.title?.message}
/>
)}
/>
</div>

<div className="w-full">
<label
htmlFor="content"
className="mb-2 flex items-center text-[16px] font-medium text-black-300 md:text-[18px] lg:text-[20px]"
>
내용<span className="ml-1 text-primary-orange-300">*</span>
</label>
<Controller
name="content"
control={control}
rules={{ required: "내용을 입력하세요." }}
render={({ field }) => (
<div className="relative w-full">
<BaseInput
{...field}
type="text"
variant="white"
name="content"
size="w-full h-[180px] md:h-[200px] lg:h-[240px]"
placeholder=""
errormessage={errors.content?.message}
wrapperClassName="!items-start"
innerClassName="opacity-0 !h-full"
/>
<textarea
{...field}
className="absolute left-0 top-0 h-full w-full resize-none rounded-lg bg-background-200 p-[14px] placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-primary-orange-300 lg:py-[18px]"
placeholder="내용을 입력하세요"
/>
</div>
)}
/>
</div>

<div className="w-full">
<label
htmlFor="image"
className="mb-2 block text-[16px] font-medium text-black-300 md:text-[18px] lg:text-[20px]"
>
이미지
</label>
<ImageInputwithPlaceHolder />
</div>
</form>
</div>
</div>

{/* 모바일 버전 버튼 */}
<div className="w-full md:hidden">
<div className="fixed bottom-4 left-4 right-4 flex flex-col items-center space-y-2 rounded-t-lg bg-white p-4">
<button
className="mb-2 h-[58px] w-[327px] rounded-[8px] bg-gray-200 text-white hover:bg-gray-300"
onClick={() => router.push("/albaTalk")}
>
취소
</button>
<button
className="h-[58px] w-[327px] rounded-[8px] bg-primary-orange-300 text-white hover:bg-orange-400"
onClick={handleSubmit((data) => {
syncImageList();
onSubmit(data);
})}
>
등록하기
</button>
</div>
</div>
</>
);
}
16 changes: 11 additions & 5 deletions src/app/components/card/board/BoardComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const BoardComment: React.FC<BoardCommentProps> = ({
return (
<div
className={`flex flex-col rounded-[16px] border ${
variant === "primary" ? "border-line-100 bg-primary-orange-50" : "border-line-100 bg-grayscale-50"
variant === "primary" ? "border-line-100 bg-primary-orange-50" : "bg-grayscale-50 border-line-100"
} w-[327px] p-3 sm:w-[477px] sm:p-4`}
style={{ minHeight: "202px" }}
>
Expand All @@ -69,16 +69,22 @@ const BoardComment: React.FC<BoardCommentProps> = ({
{/* Right Content: Kebab */}
<button
onClick={onKebabClick}
className="hover:text-grayscale-700 flex items-center justify-center text-grayscale-500"
className="hover:text-grayscale-700 text-grayscale-500 flex items-center justify-center"
aria-label="Options"
>
<Image src={kebabSrc} alt="Kebab Menu Icon" width={28} height={28} /> {/* 크기 조정 */}
<Image
src={kebabSrc}
alt="Kebab Menu Icon"
width={isLargeScreen ? 28 : 24}
height={isLargeScreen ? 28 : 24}
/>{" "}
{/* 크기 조정 */}
</button>
</div>

{/* Content */}
<p
className="line-clamp-2 flex-1 overflow-hidden text-ellipsis font-nexon text-[14px] font-normal leading-[1.5] text-grayscale-500 sm:text-[16px] sm:leading-[1.75]"
className="text-grayscale-500 line-clamp-2 flex-1 overflow-hidden text-ellipsis font-nexon text-[14px] font-normal leading-[1.5] sm:text-[16px] sm:leading-[1.75]"
style={{
display: "-webkit-box",
WebkitBoxOrient: "vertical",
Expand All @@ -99,7 +105,7 @@ const BoardComment: React.FC<BoardCommentProps> = ({
<span className="font-nexon text-[14px] font-semibold text-black-400 sm:text-[18px]">{comments}</span>
</div>
<div className="mt-1">
<span className="font-nexon text-[12px] font-normal text-grayscale-500 sm:text-[16px]">{date}</span>
<span className="text-grayscale-500 font-nexon text-[12px] font-normal sm:text-[16px]">{date}</span>
</div>
</div>
</div>
Expand Down
Loading
Loading