design: 블랙 테마 스타일 작업

This commit is contained in:
2025-05-13 15:09:56 +09:00
parent 7f70811c88
commit c3fc0eb96b
13 changed files with 135 additions and 37 deletions
@@ -0,0 +1,10 @@
import { ModifyPage } from "@/pages/(pst)/image";
export default async function PstBbsImagePostModifyPage({
params,
}: {
params: Promise<{ bbsId: string; pstNo: string }>;
}) {
const { bbsId, pstNo } = await params;
return <ModifyPage bbsId={bbsId} pstNo={pstNo} />;
}
+1
View File
@@ -13,6 +13,7 @@
"@common/components": "workspace:*",
"@common/config": "workspace:*",
"@common/network": "workspace:*",
"@fontsource-variable/noto-sans-kr": "^5.2.5",
"@frontend-opensource/use-react-hooks": "^1.1.4",
"@hookform/resolvers": "^4.1.3",
"@minoru/react-dnd-treeview": "^3.5.0",
+2
View File
@@ -1,5 +1,7 @@
import "./styles/base.css";
import "./styles/components.css";
import "@fontsource-variable/noto-sans-kr";
import { AppProvider } from "./providers";
import { cookies } from "next/headers";
+6 -4
View File
@@ -5,8 +5,10 @@
@tailwind base;
@tailwind utilities;
html,
body {
font-family: "Noto Sans KR", sans-serif;
font-size: 10px;
@layer base {
html,
body {
font-family: "Noto Sans KR", sans-serif;
font-size: 10px;
}
}
@@ -1,3 +1,4 @@
export { CreatePage } from "./ui/create-page";
export { ModifyPage } from "./ui/modify-page";
export { ImagePage } from "./ui/image-page";
export { ImagePost } from "./ui/image-post";
@@ -0,0 +1,53 @@
"use client";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQuery } from "@tanstack/react-query";
import { PostForm } from "@/widgets/post";
import {
PostApi,
postUpdateFormSchema,
type PostUpdateFormData,
} from "@/entities/post";
import { ENDPOINT } from "@/shared/config";
import { useAlertStore, useUserStore } from "@/shared/lib";
function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) {
const router = useRouter();
const { setMessage: alert } = useAlertStore((state) => state);
const { userInfo } = useUserStore((state) => state);
const { data: postInfo } = useQuery({
queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo],
queryFn: () => PostApi.getPostInfo(bbsId, pstNo),
});
const { mutateAsync: updatePost } = useMutation({
mutationFn: (data: PostUpdateFormData) =>
PostApi.updatePost(bbsId, pstNo, data),
onSuccess: () => {
alert("수정되었습니다.", router.back);
},
});
const form = useForm<PostUpdateFormData>({
resolver: zodResolver(postUpdateFormSchema),
values: {
...postInfo,
pstTtl: postInfo?.pstTtl ?? "",
pstPswd: userInfo?.userUnqId ?? "",
},
});
return (
<div className="card card-border !mt-6">
<div className="card-header">
<h3 className="text-2xl font-medium text-label">이미지 게시글 수정</h3>
</div>
<PostForm form={form} handleSave={updatePost} />
</div>
);
}
export { ModifyPage };
@@ -38,9 +38,9 @@ export const createColumns = (
<Badge color="blue">NEW</Badge>
)}
</div>
<div className="flex items-start gap-2 text-left">
<span className="text-3xl font-bold leading-none">{pstTtl}</span>
</div>
<span className="text-3xl font-bold leading-none text-label">
{pstTtl}
</span>
</div>
);
},
@@ -49,7 +49,6 @@ export const createColumns = (
id: "atflCd",
cell: ({ row }) => {
const atflCd = row.original.atflCd;
if (!atflCd) return null;
return (
<ThumbImage
atflCd={atflCd}
@@ -63,13 +62,15 @@ export const createColumns = (
id: "rgtrNm",
cell: ({ row }) => {
const { rgtrNm } = row.original;
return <span className="text-[1.4rem] font-bold">{rgtrNm}</span>;
return (
<span className="text-[1.4rem] font-bold text-label">{rgtrNm}</span>
);
},
},
{
id: "regDt",
cell: ({ row }) => (
<span className="text-[1.2rem]">
<span className="text-[1.2rem] text-label">
{dayjs(row.original.regDt).format("YYYY-MM-DD")}
</span>
),
@@ -102,16 +103,21 @@ const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => {
</div>
);
if (!imageUrl) return null;
if (imageUrl)
return (
<div className="relative my-6 flex h-[16rem] w-full items-center justify-center">
<Image
src={imageUrl}
className="object-contain"
fill
alt="썸네일 이미지"
/>
</div>
);
return (
<div className="relative my-6 flex h-[16rem] w-full items-center justify-center">
<Image
src={imageUrl}
className="object-contain"
fill
alt="썸네일 이미지"
/>
<div className="my-6 flex h-[16rem] w-full items-center justify-center rounded-sm border border-border bg-background">
<i className="diveicon di-image text-3xl" />
</div>
);
};
@@ -125,7 +125,7 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) {
<FormControl>
<Textarea
maxLength={1000}
className="h-[10rem] bg-background p-4 !text-[1.3rem] !leading-6"
className="h-[10rem] bg-background p-4 !text-[1.3rem] !leading-6 text-foreground"
placeholder="댓글을 입력해주세요."
{...field}
/>
@@ -145,7 +145,7 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) {
<Input
{...field}
value={field.value ?? ""}
className="w-[16rem] bg-background !text-[1.3rem]"
className="w-[16rem] bg-background !text-[1.3rem] text-foreground"
placeholder="작성자"
/>
</FormControl>
@@ -164,7 +164,7 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) {
{...field}
type="password"
value={field.value ?? ""}
className="w-[12rem] bg-background !text-[1.3rem]"
className="w-[12rem] bg-background !text-[1.3rem] text-foreground"
placeholder="비밀번호"
/>
</FormControl>
@@ -187,10 +187,10 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) {
>
<div className="flex w-full gap-10">
<div className="flex w-[10rem] shrink-0 flex-col">
<span className="text-[1.4rem] font-bold">
<span className="text-[1.4rem] font-bold text-label">
{comment.wrtrNm}
</span>
<span className="text-[1.2rem] text-gray-500">
<span className="text-[1.2rem] text-label">
{dayjs(comment.regDt).format("YYYY.MM.DD")}
</span>
</div>
@@ -200,7 +200,7 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) {
value={editValue}
onChange={(e) => setEditValue(e.target.value)}
maxLength={1000}
className="h-[10rem] bg-background p-4 !text-[1.3rem] !leading-6"
className="h-[10rem] bg-background p-4 !text-[1.3rem] !leading-6 text-foreground"
/>
<div className="flex gap-2">
<Button
@@ -224,7 +224,9 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) {
</div>
</div>
) : (
<p className="break-all text-[1.4rem]">{comment.cmntCn}</p>
<p className="break-all text-[1.4rem] text-foreground">
{comment.cmntCn}
</p>
)}
</div>
<div className="flex gap-2 whitespace-nowrap">
@@ -155,7 +155,7 @@ function PostForm<T extends PostFormData | PostUpdateFormData>({
{...field}
value={(field.value as string) ?? ""}
onChange={field.onChange}
className="h-[20rem] w-full !text-[1.3rem]"
className="h-[20rem] w-full bg-form !text-[1.3rem] !leading-6"
placeholder="내용을 입력해주세요"
/>
</FormControl>
@@ -106,7 +106,9 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) {
<>
<PostAction bbsId={bbsId} pstNo={pstNo} handleDelete={handleDelete}>
<div className="card card-border !p-8">
<h3 className="text-[2rem] font-bold">{postData?.pstTtl}</h3>
<h3 className="text-[2rem] font-bold text-foreground">
{postData?.pstTtl}
</h3>
<div className="card !m-0 !mt-8 bg-accent">
<ul className="flex gap-8 p-4 text-xl text-label">
<li>
@@ -134,10 +136,9 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) {
)}
</div>
)}
<div
className="min-h-[40rem] p-8"
dangerouslySetInnerHTML={{ __html: postData?.pstCn ?? "" }}
/>
<pre className="font-noto min-h-[40rem] whitespace-pre-wrap p-8 text-2xl tracking-tighter text-foreground">
{postData?.pstCn ?? ""}
</pre>
{isFetching ? (
<div className="p-8">
<Skeleton className="h-[2.5rem] w-[32rem]" />
@@ -147,7 +148,7 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) {
<>
<hr />
<div className="flex items-center gap-4 p-8">
<span className="font-bold">첨부파일</span>
<span className="font-bold text-label">첨부파일</span>
<Button
size="sm"
color="white"
@@ -1,5 +1,5 @@
import Image from "next/image";
import { useState } from "react";
import { useEffect, useState } from "react";
import type { HttpResponse } from "tus-js-client";
import type { FieldPath, UseFormReturn } from "react-hook-form";
import { FileUploader, Label, Progress } from "@common/components";
@@ -10,6 +10,7 @@ import { setCookie, useAlertStore, useMenuStore } from "@/shared/lib";
function WithPreviewFileUploader<T extends PostFormData | PostUpdateFormData>({
form,
attachmentData,
}: {
form: UseFormReturn<T>;
attachmentData?: Attachment[];
@@ -32,7 +33,8 @@ function WithPreviewFileUploader<T extends PostFormData | PostUpdateFormData>({
const { atflCd, atflId } = JSON.parse(fileInfo) ?? {};
if (atflCd) form.setValue("atflCd" as FieldPath<T>, atflCd);
if (atflId) {
setThumbnailUrl(await AttachmentApi.getImageUrl(atflId));
const imageUrl = await AttachmentApi.getImageUrl(atflId);
setThumbnailUrl(imageUrl);
}
};
@@ -41,9 +43,6 @@ function WithPreviewFileUploader<T extends PostFormData | PostUpdateFormData>({
};
const onUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
const atflCd = form.getValues("atflCd" as FieldPath<T>);
if (atflCd) setCookie("atfl-cd-key", atflCd as string);
const files = e.target.files;
if (!files) return;
if (bbsInfo?.atflMaxCnt && files.length > bbsInfo.atflMaxCnt) {
@@ -57,6 +56,7 @@ function WithPreviewFileUploader<T extends PostFormData | PostUpdateFormData>({
alert("첨부파일 최대 크기를 초과했습니다.");
return;
}
setCookie("atfl-cd-key", "");
handleTusUpload(file, {
handleResponse: handleTusResponse,
handleProgress,
@@ -64,6 +64,16 @@ function WithPreviewFileUploader<T extends PostFormData | PostUpdateFormData>({
}
};
useEffect(() => {
if (!attachmentData || attachmentData.length === 0) return;
(async () => {
const imageUrl = await AttachmentApi.getImageUrl(
attachmentData[0]?.atflId as string,
);
setThumbnailUrl(imageUrl);
})();
}, [attachmentData]);
return (
<FileUploader
id="atflCd"
+3
View File
@@ -13,6 +13,9 @@ export default {
boxShadow: {
blur: "0 0 10px -1px rgba(0, 0, 0, 0.06)",
},
fontFamily: {
noto: ['"Noto Sans KR"', "sans-serif"],
},
},
},
plugins: [tailwindcssAnimate],
+7
View File
@@ -51,6 +51,9 @@ importers:
'@common/network':
specifier: workspace:*
version: link:../../../packages/common/network
'@fontsource-variable/noto-sans-kr':
specifier: ^5.2.5
version: 5.2.5
'@frontend-opensource/use-react-hooks':
specifier: ^1.1.4
version: 1.1.4
@@ -1734,6 +1737,10 @@ packages:
resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
dev: false
/@fontsource-variable/noto-sans-kr@5.2.5:
resolution: {integrity: sha512-dIJyVPIBRJXtvaFmQ6GKCV93J9Fx3O2Ym5C3gDRcz5zLpEigrnlEfBnsXBUv4aDBHEF/gm/Q07d40dddGxFytg==}
dev: false
/@frontend-opensource/use-react-hooks@1.1.4:
resolution: {integrity: sha512-otCSyciL5MVCNNYmdDdg2lEL6rbZ3XX1meYQCzapUSC4V6qx2YxMk1kUbhwEM/+vdxhYzBHsVBGD0rZWl5cgrw==}
dependencies: