-
Notifications
You must be signed in to change notification settings - Fork 2
refactor:비제어 컴포넌트로 변경 #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
502d6ed
0229759
c3597c2
d8bedc4
879332d
3bed9dc
07499d2
ddcf3d6
0be86ef
aabe758
a414197
f51b5bf
312e65e
eb2a364
d7d21c2
e10e718
c01ce14
0d10c60
7e67913
dc61c1d
fe7165a
7bca54c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,15 +1,12 @@ | ||||||||||||||||||||||||||||||||||||||||||
| "use client"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| import { useRef } from "react"; | ||||||||||||||||||||||||||||||||||||||||||
| import { Button } from "@/components/button/Button"; | ||||||||||||||||||||||||||||||||||||||||||
| import { Input } from "@/components/common/input"; | ||||||||||||||||||||||||||||||||||||||||||
| import type { ExperienceFormValues } from "@/types/ExperienceForm.types"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| import { useExperienceForm } from "@/hooks/useExperienceForm"; | ||||||||||||||||||||||||||||||||||||||||||
| import { ImageSection } from "./ImageSection"; | ||||||||||||||||||||||||||||||||||||||||||
| import { ScheduleSection } from "./ScheduleSection"; | ||||||||||||||||||||||||||||||||||||||||||
| import { useScheduleManager } from "@/hooks/useScheduleManager"; | ||||||||||||||||||||||||||||||||||||||||||
| import { useImageManager } from "@/hooks/useImageManager"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| import { ImageSection } from "./ImageSection"; | ||||||||||||||||||||||||||||||||||||||||||
| import { ScheduleSection } from "./ScheduleSection"; | ||||||||||||||||||||||||||||||||||||||||||
| import type { ExperienceFormValues } from "@/types/ExperienceForm.types"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| interface Props { | ||||||||||||||||||||||||||||||||||||||||||
| initialValues?: Partial<ExperienceFormValues>; | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -22,21 +19,25 @@ export default function ExperienceForm({ | |||||||||||||||||||||||||||||||||||||||||
| onSubmit, | ||||||||||||||||||||||||||||||||||||||||||
| submitLabel = "등록하기", | ||||||||||||||||||||||||||||||||||||||||||
| }: Props) { | ||||||||||||||||||||||||||||||||||||||||||
| /** 기본 폼 상태 */ | ||||||||||||||||||||||||||||||||||||||||||
| const { values, handleChange } = useExperienceForm(initialValues); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** 스케줄 관리 */ | ||||||||||||||||||||||||||||||||||||||||||
| const scheduleManager = useScheduleManager( | ||||||||||||||||||||||||||||||||||||||||||
| initialValues?.schedules ?? [] | ||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||
| const titleRef = useRef<HTMLInputElement>(null); | ||||||||||||||||||||||||||||||||||||||||||
| const categoryRef = useRef<HTMLInputElement>(null); | ||||||||||||||||||||||||||||||||||||||||||
| const descriptionRef = useRef<HTMLTextAreaElement>(null); | ||||||||||||||||||||||||||||||||||||||||||
| const priceRef = useRef<HTMLInputElement>(null); | ||||||||||||||||||||||||||||||||||||||||||
| const addressRef = useRef<HTMLInputElement>(null); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const scheduleManager = useScheduleManager(initialValues?.schedules ?? []); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** 이미지 관리 */ | ||||||||||||||||||||||||||||||||||||||||||
| const bannerImages = useImageManager(); | ||||||||||||||||||||||||||||||||||||||||||
| const detailImages = useImageManager(); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const handleSubmit = () => { | ||||||||||||||||||||||||||||||||||||||||||
| onSubmit({ | ||||||||||||||||||||||||||||||||||||||||||
| ...values, | ||||||||||||||||||||||||||||||||||||||||||
| title: titleRef.current?.value ?? "", | ||||||||||||||||||||||||||||||||||||||||||
| category: categoryRef.current?.value ?? "", | ||||||||||||||||||||||||||||||||||||||||||
| description: descriptionRef.current?.value ?? "", | ||||||||||||||||||||||||||||||||||||||||||
| price: Number(priceRef.current?.value ?? 0), | ||||||||||||||||||||||||||||||||||||||||||
| address: addressRef.current?.value ?? "", | ||||||||||||||||||||||||||||||||||||||||||
| schedules: scheduleManager.schedules, | ||||||||||||||||||||||||||||||||||||||||||
| bannerImageUrl: bannerImages.images[0]?.preview ?? "", | ||||||||||||||||||||||||||||||||||||||||||
| subImageUrls: detailImages.images.map((img) => img.preview), | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -55,49 +56,53 @@ export default function ExperienceForm({ | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| {/* 제목 */} | ||||||||||||||||||||||||||||||||||||||||||
| <label>제목</label> | ||||||||||||||||||||||||||||||||||||||||||
| <Input | ||||||||||||||||||||||||||||||||||||||||||
| <input | ||||||||||||||||||||||||||||||||||||||||||
| name="title" | ||||||||||||||||||||||||||||||||||||||||||
| value={values.title} | ||||||||||||||||||||||||||||||||||||||||||
| onChange={handleChange} | ||||||||||||||||||||||||||||||||||||||||||
| defaultValue={initialValues?.title} | ||||||||||||||||||||||||||||||||||||||||||
| placeholder="제목을 입력해 주세요" | ||||||||||||||||||||||||||||||||||||||||||
| ref={titleRef} | ||||||||||||||||||||||||||||||||||||||||||
| className="border p-3 rounded-xl" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
58
to
63
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 웹 접근성을 향상시키기 위해 추가적으로,
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| {/* 카테고리 */} | ||||||||||||||||||||||||||||||||||||||||||
| <label>카테고리</label> | ||||||||||||||||||||||||||||||||||||||||||
| <Input | ||||||||||||||||||||||||||||||||||||||||||
| <input | ||||||||||||||||||||||||||||||||||||||||||
| name="category" | ||||||||||||||||||||||||||||||||||||||||||
| value={values.category} | ||||||||||||||||||||||||||||||||||||||||||
| onChange={handleChange} | ||||||||||||||||||||||||||||||||||||||||||
| defaultValue={initialValues?.category} | ||||||||||||||||||||||||||||||||||||||||||
| placeholder="카테고리를 선택해 주세요" | ||||||||||||||||||||||||||||||||||||||||||
| ref={categoryRef} | ||||||||||||||||||||||||||||||||||||||||||
| className="border p-3 rounded-xl" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| {/* 설명 */} | ||||||||||||||||||||||||||||||||||||||||||
| <label>설명</label> | ||||||||||||||||||||||||||||||||||||||||||
| <textarea | ||||||||||||||||||||||||||||||||||||||||||
| name="description" | ||||||||||||||||||||||||||||||||||||||||||
| value={values.description} | ||||||||||||||||||||||||||||||||||||||||||
| onChange={handleChange} | ||||||||||||||||||||||||||||||||||||||||||
| defaultValue={initialValues?.description} | ||||||||||||||||||||||||||||||||||||||||||
| placeholder="체험에 대한 설명을 입력해 주세요" | ||||||||||||||||||||||||||||||||||||||||||
| ref={descriptionRef} | ||||||||||||||||||||||||||||||||||||||||||
| className="border p-3 rounded-xl" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| {/* 가격 */} | ||||||||||||||||||||||||||||||||||||||||||
| <label>가격</label> | ||||||||||||||||||||||||||||||||||||||||||
| <Input | ||||||||||||||||||||||||||||||||||||||||||
| <input | ||||||||||||||||||||||||||||||||||||||||||
| name="price" | ||||||||||||||||||||||||||||||||||||||||||
| type="number" | ||||||||||||||||||||||||||||||||||||||||||
| value={values.price} | ||||||||||||||||||||||||||||||||||||||||||
| onChange={handleChange} | ||||||||||||||||||||||||||||||||||||||||||
| defaultValue={initialValues?.price} | ||||||||||||||||||||||||||||||||||||||||||
| placeholder="체험 금액을 입력해주세요" | ||||||||||||||||||||||||||||||||||||||||||
| ref={priceRef} | ||||||||||||||||||||||||||||||||||||||||||
| className="border p-3 rounded-xl" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| {/* 주소 */} | ||||||||||||||||||||||||||||||||||||||||||
| <label>주소</label> | ||||||||||||||||||||||||||||||||||||||||||
| <Input | ||||||||||||||||||||||||||||||||||||||||||
| <input | ||||||||||||||||||||||||||||||||||||||||||
| name="address" | ||||||||||||||||||||||||||||||||||||||||||
| value={values.address} | ||||||||||||||||||||||||||||||||||||||||||
| onChange={handleChange} | ||||||||||||||||||||||||||||||||||||||||||
| defaultValue={initialValues?.address} | ||||||||||||||||||||||||||||||||||||||||||
| placeholder="주소를 입력해 주세요" | ||||||||||||||||||||||||||||||||||||||||||
| ref={addressRef} | ||||||||||||||||||||||||||||||||||||||||||
| className="border p-3 rounded-xl" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| {/* 예약 가능한 시간대 */} | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 빈커밋 생성 이유 develop이 아닌 main으로 PR 요청해서 수정했습니다 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사용자가 가격 입력 필드에 숫자가 아닌 값(예: 'abc')을 입력하면
Number()함수가NaN을 반환할 수 있습니다.NaN은number타입이지만, 유효한 가격 값은 아니므로 서버로 전송되기 전에 처리해주는 것이 좋습니다.|| 0을 사용하여NaN일 경우 0으로 대체하도록 수정하는 것을 제안합니다.