Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
502d6ed
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
0229759
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
c3597c2
refactor: 비제어 컴포넌트로 변경
seongihun Dec 31, 2025
d8bedc4
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
879332d
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
3bed9dc
refactor: 비제어 컴포넌트로 변경
seongihun Dec 31, 2025
07499d2
Merge branch 'feat/MyExperience' of https://github.com/5team-gn/Globa…
seongihun Jan 6, 2026
ddcf3d6
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
0be86ef
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
aabe758
refactor: 비제어 컴포넌트로 변경
seongihun Dec 31, 2025
a414197
Merge branch 'feat/MyExperience' of https://github.com/5team-gn/Globa…
seongihun Jan 6, 2026
f51b5bf
react-hook-form 라이브러리 적용
seongihun Jan 6, 2026
312e65e
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
eb2a364
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
d7d21c2
refactor: 비제어 컴포넌트로 변경
seongihun Dec 31, 2025
e10e718
리베이스 이후 import문 경로수정
seongihun Dec 30, 2025
c01ce14
refactor: 비제어 컴포넌트로 변경
seongihun Dec 31, 2025
0d10c60
refactor: 비제어 컴포넌트로 변경
seongihun Dec 31, 2025
7e67913
react-hook-form 라이브러리 적용
seongihun Jan 6, 2026
dc61c1d
Merge branch 'feat/MyExperience' of https://github.com/5team-gn/Globa…
seongihun Jan 7, 2026
fe7165a
refactor: react-hook-form을 사용하여 경험 등록 폼 개선
seongihun Jan 7, 2026
7bca54c
Merge branch 'develop' into feat/MyExperience
seongihun Jan 7, 2026
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
63 changes: 34 additions & 29 deletions feature/Experience/ExperienceForm.tsx
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>;
Expand All @@ -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),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

사용자가 가격 입력 필드에 숫자가 아닌 값(예: 'abc')을 입력하면 Number() 함수가 NaN을 반환할 수 있습니다. NaNnumber 타입이지만, 유효한 가격 값은 아니므로 서버로 전송되기 전에 처리해주는 것이 좋습니다. || 0을 사용하여 NaN일 경우 0으로 대체하도록 수정하는 것을 제안합니다.

Suggested change
price: Number(priceRef.current?.value ?? 0),
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),
Expand All @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

웹 접근성을 향상시키기 위해 <label>을 해당 <input> 요소와 연결하는 것이 좋습니다. <label>htmlFor 속성을, <input>id 속성을 추가하여 연결할 수 있습니다. 이렇게 하면 스크린 리더 사용자가 각 입력 필드의 목적을 더 쉽게 파악할 수 있습니다. 이 패턴을 폼 내의 모든 레이블-입력 쌍에 적용해주세요.

추가적으로, className="border p-3 rounded-xl"이 여러 입력 필드에서 반복되고 있습니다. 코드 유지보수성을 높이기 위해 이 클래스명을 상수로 추출하여 재사용하는 것을 고려해볼 수 있습니다.

Suggested change
<label>제목</label>
<Input
<input
name="title"
value={values.title}
onChange={handleChange}
defaultValue={initialValues?.title}
placeholder="제목을 입력해 주세요"
ref={titleRef}
className="border p-3 rounded-xl"
/>
<label htmlFor="title">제목</label>
<input
id="title"
name="title"
defaultValue={initialValues?.title}
placeholder="제목을 입력해 주세요"
ref={titleRef}
className="border p-3 rounded-xl"
/>


{/* 카테고리 */}
<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"
/>

{/* 예약 가능한 시간대 */}
Expand Down
2 changes: 1 addition & 1 deletion feature/Experience/schedule/DateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useState, useRef } from "react";
import CalendarIcon from "@/public/icon_calendar.svg";
import DatePicker from "./Datepicker";
import { Input } from "@/components/common/input";
import { Input } from "@/components/input/Input";
import { useClickOutside } from "@/hooks/useClickOutside";

interface Props {
Expand Down
1 change: 1 addition & 0 deletions 빈커밋생성용.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
빈커밋 생성 이유 develop이 아닌 main으로 PR 요청해서 수정했습니다