Skip to content

Commit 1961458

Browse files
authored
Merge pull request #80 from JECT-Study/hotfix/74-Various-fixes
Hotfix/74 various fixes
2 parents 1f6d7f3 + aec7f10 commit 1961458

9 files changed

Lines changed: 118 additions & 112 deletions

File tree

src/app/art/[id]/edit/page.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ function FieldWrapper({ children }: { children: React.ReactNode }) {
2525
return <div className="flex flex-col gap-2">{children}</div>;
2626
}
2727

28-
function toOptionalNumber(value: string) {
29-
return value.trim() === "" ? undefined : Number(value);
28+
function toNullableNumber(value: string) {
29+
const trimmed = value.trim();
30+
return trimmed === "" ? null : Number(trimmed);
3031
}
3132

3233
function toDate(value: string | null) {
@@ -68,9 +69,9 @@ function ArtEditForm({ artwork, artworkId }: { artwork: ArtworkDetail; artworkId
6869
description: description.trim(),
6970
caution: notes.trim(),
7071
sizeType: artwork.sizeType ?? "STANDARD",
71-
widthCm: toOptionalNumber(width),
72-
heightCm: toOptionalNumber(height),
73-
depthCm: toOptionalNumber(depth),
72+
widthCm: toNullableNumber(width),
73+
heightCm: toNullableNumber(height),
74+
depthCm: toNullableNumber(depth),
7475
createdDate: toDateString(date),
7576
isPublic,
7677
availableRegions: selectedRegions,

src/app/art/new/page.tsx

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ function getErrorMessage(error: unknown) {
3131
return error instanceof Error ? error.message : "작품 등록에 실패했습니다.";
3232
}
3333

34+
function toNullableNumber(value: string) {
35+
const trimmed = value.trim();
36+
return trimmed === "" ? null : Number(trimmed);
37+
}
38+
3439
export default function ArtCreatePage() {
3540
const router = useRouter();
3641

@@ -78,28 +83,19 @@ export default function ArtCreatePage() {
7883

7984
try {
8085
const uploadedImages = await Promise.all(images.map(image => uploadImage(image.file)));
81-
8286
await createArtworkMutation({
83-
title,
87+
title: title.trim(),
8488
artworkType: artType,
85-
description,
86-
caution: notes,
87-
88-
sizeType: "STANDARD",
89-
90-
widthCm: Number(width),
91-
heightCm: Number(height),
92-
depthCm: Number(depth),
93-
94-
createdDate: date?.toISOString().split("T")[0],
95-
89+
description: description.trim(),
90+
...(notes.trim() !== "" ? { caution: notes.trim() } : {}),
91+
widthCm: toNullableNumber(width),
92+
heightCm: toNullableNumber(height),
93+
depthCm: toNullableNumber(depth),
94+
...(date ? { createdDate: date.toISOString().split("T")[0] } : {}),
9695
isPublic,
97-
9896
imageIds: uploadedImages.map(image => image.imageId),
99-
10097
thumbnailIndex: 0,
101-
102-
availableRegions: selectedRegions,
98+
...(selectedRegions.length > 0 ? { availableRegions: selectedRegions } : {}),
10399
});
104100

105101
clearImages();

src/app/exhibitions/[exhibitionId]/consent/page.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { Suspense, use, useEffect, useMemo, useRef, useState } from "react";
44

5-
import { useRouter, useSearchParams } from "next/navigation";
5+
import { useRouter } from "next/navigation";
66

77
import Header from "@/components/common/Header";
88
import AgreementContentSection from "@/components/exhibition-consent/AgreementContentSection";
@@ -54,15 +54,12 @@ function ConsentPageFallback() {
5454

5555
function ConsentPageContent({ params }: ConsentPageProps) {
5656
const { exhibitionId } = use(params);
57-
const searchParams = useSearchParams();
5857
const router = useRouter();
5958
const { isAuthReady, isAuthenticated } = useRequireAuth();
6059
const redirectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
6160

6261
const id = Number(exhibitionId);
6362
const isValidId = Number.isFinite(id);
64-
const requestedReadOnly = searchParams.get("mode") === "readonly";
65-
6663
const { data, isLoading, error, refetch } = useExhibitionConsent(id);
6764
const submitMutation = useSubmitExhibitionConsent(id);
6865
const consentData = data;
@@ -76,10 +73,9 @@ function ConsentPageContent({ params }: ConsentPageProps) {
7673
const [toastMessage, setToastMessage] = useState("동의서 작성이 완료되었습니다.");
7774

7875
const mode: ConsentMode = useMemo(() => {
79-
if (requestedReadOnly) return "readonly";
8076
if (consentData?.mode === "READONLY" || consentData?.canSubmit === false) return "readonly";
8177
return "write";
82-
}, [consentData?.canSubmit, consentData?.mode, requestedReadOnly]);
78+
}, [consentData?.canSubmit, consentData?.mode]);
8379

8480
const isReadOnly = mode === "readonly";
8581

src/app/mypage/feed/page.tsx

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -53,50 +53,71 @@ function FeedCard({
5353
}) {
5454
return (
5555
<article className="relative flex h-55.5 min-w-0 flex-col">
56-
<Link href={item.href} className="block min-w-0">
57-
<div className="border-border-primary relative h-33.5 overflow-hidden rounded-lg border">
58-
{item.imageUrl ? (
59-
<Image
60-
src={item.imageUrl}
61-
alt=""
62-
fill
63-
sizes="168px"
64-
className="object-cover"
65-
unoptimized
66-
/>
67-
) : (
68-
<div className="bg-bg-primary-darker text-text-disabled flex size-full items-center justify-center">
69-
<Images size={28} />
70-
</div>
71-
)}
72-
73-
{item.isPrivate && (
74-
<>
75-
<div className="absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-[rgba(26,26,30,0.5)] to-transparent" />
56+
<div className="relative">
57+
<Link href={item.href} className="block min-w-0">
58+
<div className="border-border-primary relative h-33.5 overflow-hidden rounded-lg border">
59+
{item.imageUrl ? (
7660
<Image
77-
src="/icon-private-lock.svg"
61+
src={item.imageUrl}
7862
alt=""
79-
width={14}
80-
height={18}
81-
className="absolute top-3 left-3"
63+
fill
64+
sizes="168px"
65+
className="object-cover"
66+
unoptimized
8267
/>
83-
</>
84-
)}
68+
) : (
69+
<div className="bg-bg-primary-darker text-text-disabled flex size-full items-center justify-center">
70+
<Images size={28} />
71+
</div>
72+
)}
8573

86-
<button
87-
type="button"
88-
aria-label="피드 메뉴"
89-
onClick={event => {
90-
event.preventDefault();
91-
event.stopPropagation();
92-
onMenuToggle();
93-
}}
94-
className="text-text-invert absolute top-2 right-2 z-10 flex h-8 w-8 items-center justify-center rounded-full drop-shadow-[0_1px_2px_rgba(0,0,0,0.55)]"
95-
>
96-
<MoreVertical size={22} strokeWidth={2.4} />
97-
</button>
98-
</div>
99-
</Link>
74+
{item.isPrivate && (
75+
<>
76+
<div className="absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-[rgba(26,26,30,0.5)] to-transparent" />
77+
<Image
78+
src="/icon-private-lock.svg"
79+
alt=""
80+
width={14}
81+
height={18}
82+
className="absolute top-3 left-3"
83+
/>
84+
</>
85+
)}
86+
</div>
87+
</Link>
88+
89+
<button
90+
type="button"
91+
aria-label="피드 메뉴"
92+
onClick={event => {
93+
event.preventDefault();
94+
event.stopPropagation();
95+
onMenuToggle();
96+
}}
97+
className="text-text-invert absolute top-2 right-2 z-10 flex h-8 w-8 items-center justify-center rounded-full drop-shadow-[0_1px_2px_rgba(0,0,0,0.55)]"
98+
>
99+
<MoreVertical size={22} strokeWidth={2.4} />
100+
</button>
101+
102+
{menuOpen && (
103+
<div className="shadow-spread-low absolute top-10 right-2 z-20 w-22 overflow-hidden rounded-lg bg-white">
104+
<button
105+
type="button"
106+
onClick={onEdit}
107+
className="text-body-2 text-text-primary hover:bg-object-primary-light hover:text-text-primary-brand focus-visible:bg-object-primary-light focus-visible:text-text-primary-brand active:bg-object-primary-light h-10 w-full cursor-pointer px-4 text-left font-medium transition-colors outline-none"
108+
>
109+
수정
110+
</button>
111+
<button
112+
type="button"
113+
onClick={onDelete}
114+
className="text-body-2 text-text-primary hover:bg-error-light hover:text-error-default focus-visible:bg-error-light focus-visible:text-error-default active:bg-error-light h-10 w-full cursor-pointer px-4 text-left font-medium transition-colors outline-none"
115+
>
116+
삭제
117+
</button>
118+
</div>
119+
)}
120+
</div>
100121

101122
<Link href={item.href} className="block min-w-0">
102123
<div className="flex w-full flex-col items-start gap-1 pt-2 pr-3.5 pb-3 pl-1">
@@ -110,24 +131,6 @@ function FeedCard({
110131
</div>
111132
</Link>
112133

113-
{menuOpen && (
114-
<div className="shadow-spread-low absolute top-10 right-3 z-20 w-22 overflow-hidden rounded-lg bg-white">
115-
<button
116-
type="button"
117-
onClick={onEdit}
118-
className="text-body-2 text-text-primary hover:bg-object-primary-light hover:text-text-primary-brand focus-visible:bg-object-primary-light focus-visible:text-text-primary-brand active:bg-object-primary-light h-10 w-full cursor-pointer px-4 text-left font-medium transition-colors outline-none"
119-
>
120-
수정
121-
</button>
122-
<button
123-
type="button"
124-
onClick={onDelete}
125-
className="text-body-2 text-text-primary hover:bg-error-light hover:text-error-default focus-visible:bg-error-light focus-visible:text-error-default active:bg-error-light h-10 w-full cursor-pointer px-4 text-left font-medium transition-colors outline-none"
126-
>
127-
삭제
128-
</button>
129-
</div>
130-
)}
131134
</article>
132135
);
133136
}

src/app/space/[id]/edit/page.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ function FieldWrapper({ children }: { children: React.ReactNode }) {
2424
return <div className="flex flex-col gap-2">{children}</div>;
2525
}
2626

27-
function toOptionalNumber(value: string) {
28-
return value.trim() === "" ? undefined : Number(value);
27+
function toNullableNumber(value: string) {
28+
const trimmed = value.trim();
29+
return trimmed === "" ? null : Number(trimmed);
2930
}
3031

3132
function getErrorMessage(error: unknown) {
@@ -54,9 +55,9 @@ function SpaceEditForm({ space, spaceId }: { space: SpaceDetail; spaceId: string
5455
address: address.trim(),
5556
description: description.trim(),
5657
caution: notes.trim(),
57-
widthCm: toOptionalNumber(width),
58-
heightCm: toOptionalNumber(height),
59-
depthCm: toOptionalNumber(depth),
58+
widthCm: toNullableNumber(width),
59+
heightCm: toNullableNumber(height),
60+
depthCm: toNullableNumber(depth),
6061
isPublic,
6162
}),
6263
onSuccess: () => {

src/app/space/new/page.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ function FieldWrapper({ children }: { children: React.ReactNode }) {
2626
return <div className="flex flex-col gap-2">{children}</div>;
2727
}
2828

29-
function toOptionalNumber(value: string) {
30-
return value.trim() === "" ? undefined : Number(value);
29+
function toNullableNumber(value: string) {
30+
const trimmed = value.trim();
31+
return trimmed === "" ? null : Number(trimmed);
3132
}
3233

3334
function getErrorMessage(error: unknown) {
@@ -88,9 +89,9 @@ export default function SpaceCreatePage() {
8889
address,
8990
description,
9091
caution: notes,
91-
widthCm: toOptionalNumber(width),
92-
heightCm: toOptionalNumber(height),
93-
depthCm: toOptionalNumber(depth),
92+
widthCm: toNullableNumber(width),
93+
heightCm: toNullableNumber(height),
94+
depthCm: toNullableNumber(depth),
9495
isPublic,
9596
imageIds: uploadedImages.map(image => image.imageId),
9697
});

src/components/exhibition-consent/SignatureSection.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,22 @@ function formatSignatureDate(value?: string | null) {
2525
return `${year}.${month}.${day}`;
2626
}
2727

28+
function formatTodayDate() {
29+
const date = new Date();
30+
const year = date.getFullYear();
31+
const month = String(date.getMonth() + 1).padStart(2, "0");
32+
const day = String(date.getDate()).padStart(2, "0");
33+
return `${year}.${month}.${day}`;
34+
}
35+
2836
export default function SignatureSection({
2937
mode,
3038
signatureDataUrl,
3139
signedAt,
3240
onSignatureChange,
3341
}: SignatureSectionProps) {
3442
const isReadOnly = mode === "readonly";
35-
const displayDate = formatSignatureDate(signedAt);
43+
const displayDate = isReadOnly ? formatSignatureDate(signedAt) : formatTodayDate();
3644
const displaySignatureUrl = normalizeImageUrl(signatureDataUrl);
3745

3846
const handleClear = () => {

src/services/artworks.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,21 @@ export interface CreateArtworkRequest {
99
description: string;
1010
caution?: string;
1111

12-
sizeType: "STANDARD";
12+
sizeType?: "STANDARD" | "CUSTOM";
1313

14-
widthCm?: number;
15-
heightCm?: number;
16-
depthCm?: number;
14+
widthCm?: number | null;
15+
heightCm?: number | null;
16+
depthCm?: number | null;
1717

1818
createdDate?: string;
1919

2020
isPublic?: boolean;
2121

2222
imageIds: number[];
2323

24-
thumbnailIndex: number;
24+
thumbnailIndex?: number;
2525

26-
availableRegions: string[];
26+
availableRegions?: string[];
2727
}
2828

2929
export interface UpdateArtworkRequest {
@@ -32,9 +32,9 @@ export interface UpdateArtworkRequest {
3232
description?: string;
3333
caution?: string;
3434
sizeType?: "STANDARD" | "CUSTOM";
35-
widthCm?: number;
36-
heightCm?: number;
37-
depthCm?: number;
35+
widthCm?: number | null;
36+
heightCm?: number | null;
37+
depthCm?: number | null;
3838
createdDate?: string;
3939
isPublic?: boolean;
4040
imageIds?: number[];

src/services/spaces.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ export interface CreateSpaceRequest {
99
address: string;
1010
description: string;
1111
caution?: string;
12-
widthCm?: number;
13-
heightCm?: number;
14-
depthCm?: number;
12+
widthCm?: number | null;
13+
heightCm?: number | null;
14+
depthCm?: number | null;
1515
isPublic?: boolean;
1616
imageIds: number[];
1717
}
@@ -22,9 +22,9 @@ export interface UpdateSpaceRequest {
2222
address?: string;
2323
description?: string;
2424
caution?: string;
25-
widthCm?: number;
26-
heightCm?: number;
27-
depthCm?: number;
25+
widthCm?: number | null;
26+
heightCm?: number | null;
27+
depthCm?: number | null;
2828
isPublic?: boolean;
2929
imageIds?: number[];
3030
}

0 commit comments

Comments
 (0)