diff --git a/src/app/(pages)/(albaform)/addform/page.tsx b/src/app/(pages)/(albaform)/addform/page.tsx index 45a7f6ae..66f9728e 100644 --- a/src/app/(pages)/(albaform)/addform/page.tsx +++ b/src/app/(pages)/(albaform)/addform/page.tsx @@ -14,6 +14,7 @@ import WorkConditionSection from "./section/WorkConditionSection"; import useEditing from "@/hooks/useEditing"; import { SubmitFormDataType } from "@/types/addform"; import CustomFormModal from "@/app/components/modal/modals/confirm/CustomFormModal"; +import DotLoadingSpinner from "@/app/components/loading-spinner/DotLodingSpinner"; export default function AddFormPage() { const router = useRouter(); @@ -61,6 +62,7 @@ export default function AddFormPage() { // 폼 제출 리액트쿼리 const mutation = useMutation({ mutationFn: async () => { + setLoading(true); // 이미지 필수 체크 if (!imageFiles || imageFiles.length === 0) { toast.error("이미지를 첨부해주세요."); @@ -110,11 +112,12 @@ export default function AddFormPage() { if (typeof window !== "undefined") { window.localStorage.removeItem("tempAddFormData"); } + setLoading(false); toast.success("알바폼을 등록했습니다."); // if (formId) router.push(`/alba/${formId}`); }, onError: (error) => { - console.error("에러가 발생했습니다.", error); + setLoading(false); toast.error("에러가 발생했습니다."); onTempSave(); }, @@ -131,6 +134,7 @@ export default function AddFormPage() { const currentParam = searchParams.get("tab"); const [prevOption, setPrevOption] = useState(null); const initialLoad = currentParam === null; // 초기 로딩 여부 확인 + const [loading, setLoading] = useState(false); const handleOptionChange = async (option: string) => { setSelectedOption(option); @@ -313,7 +317,7 @@ export default function AddFormPage() { disabled={!isValid} onClick={handleSubmit(() => mutation.mutate())} > - 작성 완료 + {loading ? : "작성 완료"} diff --git a/src/app/(pages)/(albaform)/alba/[formId]/components/FormActions.tsx b/src/app/(pages)/(albaform)/alba/[formId]/components/FormActions.tsx index e598eab8..6e7cd314 100644 --- a/src/app/(pages)/(albaform)/alba/[formId]/components/FormActions.tsx +++ b/src/app/(pages)/(albaform)/alba/[formId]/components/FormActions.tsx @@ -1,9 +1,17 @@ -import React from "react"; -import Button from "@/app/components/button/default/Button"; -import { FcEmptyTrash, FcEditImage, FcFile, FcSearch } from "react-icons/fc"; +"use client"; +import React, { useState } from "react"; // useState 추가 import Link from "next/link"; import { useUser } from "@/hooks/queries/user/me/useUser"; import { FormDetailResponse } from "@/types/response/form"; +import FloatingBtn from "@/app/components/button/default/FloatingBtn"; +import { FaEdit } from "react-icons/fa"; +import { MdDeleteForever } from "react-icons/md"; +import { VscGitStashApply } from "react-icons/vsc"; +import { CiMemoPad } from "react-icons/ci"; +import axios from "axios"; +import toast from "react-hot-toast"; +import { useRouter } from "next/navigation"; +import DotLoadingSpinner from "@/app/components/loading-spinner/DotLodingSpinner"; interface FormActionsProps { formId: string | number; @@ -12,24 +20,27 @@ interface FormActionsProps { export default function FormActions({ formId, albaFormDetailData }: FormActionsProps) { const { user } = useUser(); + const router = useRouter(); const isMyAlbaForm = user?.id === albaFormDetailData.ownerId; const isOwnerRole = user?.role === "OWNER"; - const buttonStyle = "h-10 lg:h-16"; + const buttonStyle = "h-10 lg:h-16 w-full rounded-lg font-bold "; + const [loading, setLoading] = useState(false); + if (!user) return null; - // 사장님이 아니면 지원하기/내 지원내역 보기 버튼 - if (!isOwnerRole) { - return ( -
- - -
- ); - } + + const handleDelete = async () => { + setLoading(true); + try { + await axios.delete(`/api/forms/${formId}`); + toast.success("성공적으로 삭제되었습니다."); + router.push(`/albalist`); + } catch (error) { + toast.error("삭제 중 오류가 발생했습니다."); + } finally { + setLoading(false); + } + }; // 사장님이면 수정하기/삭제하기 버튼 if (isOwnerRole) { @@ -37,13 +48,33 @@ export default function FormActions({ formId, albaFormDetailData }: FormActionsP return (
- + - + } + onClick={handleDelete} + disabled={loading} + > + {loading ? : "삭제하기"} + +
+ ); + } + + // 사장님이 아니면 지원하기/내 지원내역 보기 버튼 + if (!isOwnerRole) { + return ( +
+ }> + 지원하기 + + }> + 내 지원내역 보기 +
); } diff --git a/src/app/(pages)/(albaform)/alba/[formId]/components/FormImage.tsx b/src/app/(pages)/(albaform)/alba/[formId]/components/FormImage.tsx index 94900de1..b8a9a9c4 100644 --- a/src/app/(pages)/(albaform)/alba/[formId]/components/FormImage.tsx +++ b/src/app/(pages)/(albaform)/alba/[formId]/components/FormImage.tsx @@ -1,5 +1,6 @@ import Image from "next/image"; import Indicator from "@/app/components/pagination/Indicator"; +import { isValidS3Url } from "@/utils/checkS3Url"; interface FormImageProps { imageUrls: string[]; @@ -30,9 +31,11 @@ export default function FormImage({ imageUrls, currentPage, onPageChange }: Form ))} {/* 인디케이터 */} -
- -
+ {imageUrls.filter((url) => isValidS3Url(url)).length > 1 && ( +
+ +
+ )} ); } diff --git a/src/app/(pages)/(albaform)/alba/[formId]/components/RecruitInformation.tsx b/src/app/(pages)/(albaform)/alba/[formId]/components/RecruitInformation.tsx index e8dbf311..ecb250cb 100644 --- a/src/app/(pages)/(albaform)/alba/[formId]/components/RecruitInformation.tsx +++ b/src/app/(pages)/(albaform)/alba/[formId]/components/RecruitInformation.tsx @@ -25,9 +25,14 @@ export default function RecruitInformation({ albaFormDetailData, formId }: Recru <> -

모집 조건

+
+ +
+
+ +
); } diff --git a/src/app/components/card/cardList/AlbaListItem.tsx b/src/app/components/card/cardList/AlbaListItem.tsx index 33a62e36..b1b324cc 100644 --- a/src/app/components/card/cardList/AlbaListItem.tsx +++ b/src/app/components/card/cardList/AlbaListItem.tsx @@ -10,8 +10,8 @@ import Indicator from "../../pagination/Indicator"; import { FormListType } from "@/types/response/form"; import { useFormScrap } from "@/hooks/queries/form/useFormScap"; import { MdOutlineImage } from "react-icons/md"; -import { S3_URL } from "@/constants/config"; import DotLoadingSpinner from "../../loading-spinner/DotLodingSpinner"; +import { isValidS3Url } from "@/utils/checkS3Url"; /** * 알바폼 리스트 아이템 컴포넌트 @@ -125,11 +125,6 @@ const AlbaListItem = ({ }); }; - // S3 URL 체크 함수 - const isValidS3Url = (url: string) => { - return url.startsWith(S3_URL); - }; - return (
{/* 이미지 슬라이더 영역 */} diff --git a/src/app/components/card/cardList/RecruitCondition.tsx b/src/app/components/card/cardList/RecruitCondition.tsx index 629539c6..a1ac33bc 100644 --- a/src/app/components/card/cardList/RecruitCondition.tsx +++ b/src/app/components/card/cardList/RecruitCondition.tsx @@ -9,9 +9,9 @@ interface RecruitConditionProps { // 모집조건 카드 컴포넌트 const RecruitCondition = ({ recruitData }: RecruitConditionProps) => { - const titleStyle = "text-black-200 min-w-[64px] lg:min-w-[120px]"; + const titleStyle = "text-black-200 min-w-28 lg:min-w-[120px]"; return ( -
+
모집 인원
diff --git a/src/app/components/card/cardList/RecruitIconItem.tsx b/src/app/components/card/cardList/RecruitIconItem.tsx index e195be57..f0877e43 100644 --- a/src/app/components/card/cardList/RecruitIconItem.tsx +++ b/src/app/components/card/cardList/RecruitIconItem.tsx @@ -22,8 +22,8 @@ const RecruitIconItem = ({ icon, label, value }: RecruitIconItemProps) => {
-
{label}
-
{value}
+
{label}
+
{value}
); diff --git a/src/app/components/loading-spinner/DotLodingSpinner.tsx b/src/app/components/loading-spinner/DotLodingSpinner.tsx index f50c1bdc..749e0a14 100644 --- a/src/app/components/loading-spinner/DotLodingSpinner.tsx +++ b/src/app/components/loading-spinner/DotLodingSpinner.tsx @@ -1,23 +1,16 @@ "use client"; +import { cn } from "@/lib/tailwindUtil"; import React from "react"; export default function DotLoadingSpinner() { + const dotStyle = "h-2 w-2 animate-bounce rounded-full "; return (
-
-
-
+
{/* 연한 오렌지 */} +
{/* 연한 그린 */} +
{/* 연한 블루 */}
); diff --git a/src/app/components/pagination/Indicator.tsx b/src/app/components/pagination/Indicator.tsx index 965b4a4d..21af1c25 100644 --- a/src/app/components/pagination/Indicator.tsx +++ b/src/app/components/pagination/Indicator.tsx @@ -9,8 +9,8 @@ interface IndicatorProps { } const Indicator = ({ imageCount, currentPage, onPageChange }: IndicatorProps) => { - const activeStyle = "size-4 text-grayscale-300 opacity-60"; - const defaultStyle = "size-3 text-grayscale-50 opacity-60"; + const activeStyle = "lg:size-5 text-primary-orange-300 opacity-60 size:3"; + const defaultStyle = "lg:size-3 text-primary-orange-100 opacity-60 size:1"; // 이미지 개수 만큼 동적으로 생성 const indicators = Array(imageCount) @@ -24,7 +24,10 @@ const Indicator = ({ imageCount, currentPage, onPageChange }: IndicatorProps) => )); return ( - ); diff --git a/src/utils/checkS3Url.ts b/src/utils/checkS3Url.ts new file mode 100644 index 00000000..00db4372 --- /dev/null +++ b/src/utils/checkS3Url.ts @@ -0,0 +1,6 @@ +import { S3_URL } from "@/constants/config"; + +// S3 URL 체크 함수 +export const isValidS3Url = (url: string) => { + return url.startsWith(S3_URL); +};