diff --git a/src/app/(pages)/(albaform)/addform/RecruitCondition.tsx b/src/app/(pages)/(albaform)/addform/RecruitConditionSection.tsx similarity index 97% rename from src/app/(pages)/(albaform)/addform/RecruitCondition.tsx rename to src/app/(pages)/(albaform)/addform/RecruitConditionSection.tsx index 4678d3a2..29f5dd5b 100644 --- a/src/app/(pages)/(albaform)/addform/RecruitCondition.tsx +++ b/src/app/(pages)/(albaform)/addform/RecruitConditionSection.tsx @@ -4,7 +4,7 @@ import Label from "../Label"; import InputDropdown from "@/app/components/button/dropdown/InputDropdown"; // 알바폼 만들기 - 사장님- 2-모집조건 -export default function RecruitCondition() { +export default function RecruitConditionSection() { const { register, formState: { errors }, diff --git a/src/app/(pages)/(albaform)/addform/RecruitContent.tsx b/src/app/(pages)/(albaform)/addform/RecruitContentSection.tsx similarity index 92% rename from src/app/(pages)/(albaform)/addform/RecruitContent.tsx rename to src/app/(pages)/(albaform)/addform/RecruitContentSection.tsx index 9f02d4e0..f1f7ee33 100644 --- a/src/app/(pages)/(albaform)/addform/RecruitContent.tsx +++ b/src/app/(pages)/(albaform)/addform/RecruitContentSection.tsx @@ -7,11 +7,10 @@ import DatePickerInput from "@/app/components/input/dateTimeDaypicker/DatePicker import { cn } from "@/lib/tailwindUtil"; import { useFormContext } from "react-hook-form"; import { useEffect, useState } from "react"; -import { useSearchParams } from "next/navigation"; // 알바폼 만들기 - 사장님 - 1-모집내용 -export default function RecruitContent() { +export default function RecruitContentSection() { // 이미지 파일을 로컬 상태에 저장 const [initialImageList, setInitialImageList] = useState<{ file: File; url: string; id: string }[]>([]); @@ -41,12 +40,9 @@ export default function RecruitContent() { ]); }; - const searchParams = useSearchParams(); - const currentParam = searchParams.get("tab"); - const initialLoad = currentParam === null; // 초기 로딩 여부 확인 // 컴포넌트가 마운트될 때 이미지 초기값 설정 (초기로딩 제외) useEffect(() => { - if (!initialLoad && currentValue.imageFiles?.length > 0) { + if (currentValue.imageFiles?.length > 0) { handleChangeImages(currentValue.imageFiles); } }, []); diff --git a/src/app/(pages)/(albaform)/addform/WorkCondition.tsx b/src/app/(pages)/(albaform)/addform/WorkConditionSection.tsx similarity index 99% rename from src/app/(pages)/(albaform)/addform/WorkCondition.tsx rename to src/app/(pages)/(albaform)/addform/WorkConditionSection.tsx index ce3e957e..669e8720 100644 --- a/src/app/(pages)/(albaform)/addform/WorkCondition.tsx +++ b/src/app/(pages)/(albaform)/addform/WorkConditionSection.tsx @@ -12,7 +12,7 @@ import BaseInput from "@/app/components/input/text/BaseInput"; import CheckBtn from "@/app/components/button/default/CheckBtn"; // 알바폼 만들기 - 사장님 - 3-근무조건 -export default function WorkCondition() { +export default function WorkConditionSection() { const { register, setValue, diff --git a/src/app/(pages)/(albaform)/addform/page.tsx b/src/app/(pages)/(albaform)/addform/page.tsx index 24254bac..93b1a3bb 100644 --- a/src/app/(pages)/(albaform)/addform/page.tsx +++ b/src/app/(pages)/(albaform)/addform/page.tsx @@ -4,13 +4,13 @@ import { useRouter, useSearchParams } from "next/navigation"; import { FormProvider, useForm } from "react-hook-form"; import axios from "axios"; import TabMenuDropdown from "@/app/components/button/dropdown/TabMenuDropdown"; -import RecruitCondition from "./RecruitCondition"; import Button from "@/app/components/button/default/Button"; import { toast } from "react-hot-toast"; import { useMutation } from "@tanstack/react-query"; import { useUpdateProfile } from "@/hooks/queries/user/me/useUpdateProfile"; -import RecruitContent from "./RecruitContent"; -import WorkCondition from "./WorkCondition"; +import RecruitContentSection from "./RecruitContentSection"; +import RecruitConditionSection from "./RecruitConditionSection"; +import WorkConditionSection from "./WorkConditionSection"; interface SubmitFormDataType { isPublic: boolean; @@ -66,13 +66,12 @@ export default function AddFormPage() { const { setValue, - getValues, handleSubmit, formState: { isDirty, isValid }, } = methods; // 훅폼에서 관리하는 전체 데이터를 가져오는 함수 - const currentValues: SubmitFormDataType = getValues(); + const currentValues: SubmitFormDataType = methods.watch(); // 이미지 업로드 api 처리를 위해 별도 변수에 할당 const imageFiles = currentValues.imageFiles; @@ -135,17 +134,17 @@ export default function AddFormPage() { "모집 조건": "recruit-condition", "근무 조건": "work-condition", }[option]; - router.replace(`/addform?tab=${params}`); + router.push(`/addform?tab=${params}`); }; const renderChildren = () => { switch (selectedOption) { case "모집 내용": - return ; + return ; case "모집 조건": - return ; + return ; case "근무 조건": - return ; + return ; default: return <>; } @@ -204,33 +203,27 @@ export default function AddFormPage() { window.localStorage.setItem("tempAddFormData", JSON.stringify(currentValues)); } toast.success("임시 저장되었습니다."); - // console.log("임시저장 데이터", currentValues); + console.log("임시저장 데이터", currentValues); }; // 각각의 탭 작성중 여부 const isEditingRecruitContent = - currentValues.title !== "" || - currentValues.description !== "" || - currentValues.recruitmentStartDate !== "" || - currentValues.imageUrls + currentValues.title !== "" || currentValues.description !== "" || currentValues.recruitmentStartDate !== undefined ? true : false; const isEditingRecruitCondition = - currentValues.gender || - currentValues.numberOfPositions || - currentValues.education || - currentValues.age || - currentValues.preferred + currentValues.gender !== "" || + currentValues.numberOfPositions !== 0 || + currentValues.education !== "" || + currentValues.age !== "" || + currentValues.preferred !== "" ? true : false; const isEditingWorkCondition = - currentValues.location || - currentValues.workDays || - currentValues.workStartTime || - currentValues.workStartDate || - currentValues.hourlyWage || - currentValues.isNegotiableWorkDays || - currentValues.isPublic + currentValues.location !== "" || + currentValues.workStartTime !== "" || + currentValues.workStartDate !== "" || + currentValues.hourlyWage > 0 ? true : false; @@ -242,7 +235,7 @@ export default function AddFormPage() { options={[ { label: "모집 내용", - isEditing: isEditingRecruitContent || initialLoad || currentParam === "recruit-condition", + isEditing: isEditingRecruitContent || initialLoad || currentParam === "recruit-content", }, { label: "모집 조건", isEditing: isEditingRecruitCondition || currentParam === "recruit-condition" }, { label: "근무 조건", isEditing: isEditingWorkCondition || currentParam === "work-condition" }, diff --git a/src/app/api/forms/[formId]/applications/route.ts b/src/app/api/forms/[formId]/applications/route.ts index 53c274aa..733d5fd5 100644 --- a/src/app/api/forms/[formId]/applications/route.ts +++ b/src/app/api/forms/[formId]/applications/route.ts @@ -20,9 +20,10 @@ export async function POST(req: NextRequest, { params }: { params: { formId: str "Content-Type": "application/json", }, }); - + console.log(response.data); return NextResponse.json(response.data); } catch (error: unknown) { + console.error(error); if (error instanceof AxiosError) { console.error(`POST /api/forms/${params.formId}/applications error:`, error); if (error.response) { diff --git a/src/app/components/input/file/ImageInput/ImageInput.tsx b/src/app/components/input/file/ImageInput/ImageInput.tsx index c80f7f60..f73f737e 100644 --- a/src/app/components/input/file/ImageInput/ImageInput.tsx +++ b/src/app/components/input/file/ImageInput/ImageInput.tsx @@ -17,7 +17,7 @@ interface ImageInputProps { } const ImageInput = forwardRef((props, ref) => { - const [imageList, setImageList] = useState(props.initialImageList || []); // 단순히 이미지 프리뷰를 위한 상태 관리 + const [imageList, setImageList] = useState([]); // 단순히 이미지 프리뷰를 위한 상태 관리 const handleFileChange = (selectedFile: File | null) => { if (selectedFile) { @@ -42,6 +42,7 @@ const ImageInput = forwardRef((props, ref) => props.onChange?.(newImageList.map((img) => img.file).filter((file) => file !== null)); } }; + const handleOpenFileSelecter = () => { if (typeof ref === "function") { // input 요소를 찾아서 클릭 @@ -55,6 +56,10 @@ const ImageInput = forwardRef((props, ref) => }; const handleDeleteImage = (targetId: string) => { + const targetImage = imageList.find((image) => image.id === targetId); + if (targetImage) { + URL.revokeObjectURL(targetImage.url); // URL 객체 해제 + } const newImageList = imageList.filter((image) => image.id !== targetId); setImageList(newImageList); props.onChange?.(newImageList.map((img) => img.file).filter((file) => file !== null)); diff --git a/src/app/components/layout/addFormLayout/ApplyHeader.tsx b/src/app/components/layout/addFormLayout/ApplyHeader.tsx index 11ecc82e..460a9107 100644 --- a/src/app/components/layout/addFormLayout/ApplyHeader.tsx +++ b/src/app/components/layout/addFormLayout/ApplyHeader.tsx @@ -2,7 +2,7 @@ import Button from "@/app/components/button/default/Button"; const ApplyHeader = ({ title, onCancel }: { title: string; onCancel: () => void }) => { return ( -
+

{title}