design: 블랙 테마 스타일 작업
This commit is contained in:
+10
@@ -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} />;
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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],
|
||||
|
||||
Generated
+7
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user