@@ -41,7 +41,7 @@ export default function SignupPage() {
{/* 사장님 회원가입 카드 */}
diff --git a/src/app/(home)/page.tsx b/src/app/(home)/page.tsx
index 97464b5b..ce27314b 100644
--- a/src/app/(home)/page.tsx
+++ b/src/app/(home)/page.tsx
@@ -6,49 +6,85 @@ import Image from "next/image";
import Lenis from "@studio-freight/lenis";
import { useMediaQuery } from "react-responsive";
import TypewriterText from "../components/animation/TypewriterText";
+import { IoIosArrowDown } from "react-icons/io";
+import LeafAnimation from "../components/animation/LeafAnimation";
+import { Player } from "@lottiefiles/react-lottie-player";
+// 버튼 타입 정의
+interface ButtonType {
+ text: string;
+ href: string;
+ primary: boolean;
+ icon?: string; // 선택적 아이콘
+}
+
+// slides 배열 수정
const slides = [
{
id: 1,
title: "쉽고 빨라요",
content: "1분만에 알바폼을 만들어 보세요!\n링크를 복사하여 어디서든지 사용하세요.",
- image: "/images/land/s2.jpg",
+ image: "/images/land/s2.svg",
},
{
id: 2,
title: "한 곳에서 쉽게 관리하세요",
content: "워크폼 관리 페이지에서 지원 현황을 확인하고\n지원자별 상태를 관리할 수 있습니다.",
- image: "/images/land/s3.jpg",
+ image: "/images/land/s3.png",
},
{
id: 3,
title: "쉽고 빠르게 지원하세요",
content: "간단한 정보만 입력해도\n알바 지원이 가능합니다.",
- image: "/images/land/s4.jpg",
+ image: "/images/land/s4.png",
},
{
id: 4,
title: "workroot에 가입하세요",
content: "오늘의 선택이 내일의 열매가 됩니다.",
- image: "/images/land/step1.jpg",
+ image: "/images/land/step1.png",
},
{
id: 5,
title: "지원자 이용 방법",
content: "언제든 다시 볼 수 있게\n공고를 스크랩하세요",
- image: "/images/land/step2-2.jpg",
+ image: "/images/land/step2-2.png",
blackAreaTitle: "사장님 이용 방법",
- blackAreaContent: "워크채널 우의 [폼 만들기] 버튼을 클릭하고\n인재 채용을 시작하세요",
- blackAreaImage: "/images/land/step2-1.jpg",
+ blackAreaContent: "워크채널 우측의 [폼 만들기] 버튼을 클릭하고\n인재 채용을 시작하세요",
+ blackAreaImage: "/images/land/step2-1.png",
},
{
id: 6,
title: "",
- content: "마이페이지에서 스크랩한 공고를 분석하고\n지원 계획을 세우세요",
- image: "/images/land/step3-2.jpg",
+ content: "마이페이지에서 스크랩한 공고를\n분석하고 지원 계획을 세우세요",
+ image: "/images/land/step3-2.png",
blackAreaTitle: "",
blackAreaContent: "내 워크폼에서 작성한 공고를\n손쉽게 수정하고 삭제할 수 있어요",
- blackAreaImage: "/images/land/step3-1.jpg",
+ blackAreaImage: "/images/land/step3-1.png",
+ },
+ {
+ id: 7,
+ title: "쉽고 빨라요",
+ content: "1분만에 알바폼을 만들어 보세요!\n링크를 복사하여 어디서든지 사용하세요.",
+ image: "/images/land/s2.png",
+ },
+ {
+ id: 9,
+ title: "지금 바로 시작하세요",
+ content: "더 나은 채용의 시작,\nWorkroot가 함께합니다",
+ image: "/images/land/start.png",
+ buttons: [
+ {
+ text: "채용 공고 구경하기",
+ href: "/work-list",
+ primary: true,
+ },
+ {
+ text: "서비스 더 알아보기",
+ href: "/signup",
+ primary: false,
+ },
+ ],
},
];
@@ -169,9 +205,7 @@ export default function LandingPage() {
ref={containerRef}
className={`relative h-[400vh] min-h-[768px] overflow-hidden ${isLargeScreen ? "" : "flex flex-col"}`}
>
-
+
+ {/* 내용 섹션에 새로운 스타일 적용 */}
+ {/* 이미지 컨테이너에 새로운 효과 추가 */}
{currentSlide === 0 ? (
) : currentSlide === 4 || currentSlide === 5 ? (
+ {/* 이미지/애니메이션 섹션 */}
+
+
+ {currentSlide === 5 ? (
+
+ ) : (
+
+
+
+ )}
+
+
+
+ {/* 텍스트 섹션 - 장식 요소 제거 */}
+
+
+
+ {slides[currentSlide].blackAreaTitle}
+
+
+
+
+
+
+
+
+
+
+ ) : currentSlide === 7 ? (
+
-
-
-
-
+
+ {slides[currentSlide].title}
+
+
+ {slides[currentSlide].content}
+
+
+
+ {/* 버튼 그룹 */}
+
-
+ {slides[currentSlide].buttons?.map((button: ButtonType, index) => (
+
+ {button.icon && {button.icon}}
+
+ {button.text}
+
+
+
+ ))}
+
+
+ {/* 장식 요소 */}
+
-
-
-
) : (
)}
+
+ {/* 스크롤 인디케이터 개선 */}
{currentSlide === 0 && (
-
- scroll
+
+
+ scroll
+
)}
+
+ {/* 콘텐츠 섹션에 새로운 디자인 요소 추가 */}
- {currentSlide > 0 && (
+ {/* 초록색 영역 - currentSlide가 0이나 7이 아닐 때만 표시 */}
+ {currentSlide !== 0 && currentSlide !== 7 && currentSlide !== 9 && (
-
-
-
+ {/* 이미지/애니메이션 섹션 */}
-
-
+
+ {currentSlide === 1 ? (
+
+ ) : currentSlide === 2 ? (
+
+ ) : currentSlide === 5 ? (
+
+ ) : (
+
+
+
+ )}
-
-
-
+
+ {/* 텍스트 섹션 */}
+
+
+
+ {slides[currentSlide].title}
+
+
+
+
+
+
+
+
+
+ {/* 텍스트 배경 효과 */}
+
+
+
+ {/* 장식적 요소 유지 */}
+
+
@@ -359,37 +579,42 @@ export default function LandingPage() {
+ {/* 네비게이션 도트 선 */}
{currentSlide > 0 && (
{slides.slice(1).map((_, index) => (
- {
- if (!isScrollingRef.current) {
- const targetScroll =
- ((index + 1) / (slides.length - 1)) * (containerRef.current?.scrollHeight || 0);
- lenisRef.current?.scrollTo(targetScroll, {
+
+
+ {
+ const targetSlide = index + 1;
+ const totalSlides = slides.length;
+ const scrollProgress = targetSlide / (totalSlides - 1);
+
+ lenisRef.current?.scrollTo(containerRef.current!.scrollHeight * scrollProgress, {
duration: 1.2,
easing: (t) => t * (2 - t),
});
- }
- }}
- />
+
+ setCurrentSlide(targetSlide);
+ }}
+ />
+
))}
)}
+
)}
diff --git a/src/app/(pages)/(workform)/addform/page.tsx b/src/app/(pages)/(workform)/addform/page.tsx
index 5ebb55e5..ebba23b4 100644
--- a/src/app/(pages)/(workform)/addform/page.tsx
+++ b/src/app/(pages)/(workform)/addform/page.tsx
@@ -1,4 +1,5 @@
"use client";
+
import { useEffect, useMemo, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { FormProvider, useForm } from "react-hook-form";
diff --git a/src/app/(pages)/(workform)/addform/section/RecruitContentSection.tsx b/src/app/(pages)/(workform)/addform/section/RecruitContentSection.tsx
index 1c6f360f..402bc344 100644
--- a/src/app/(pages)/(workform)/addform/section/RecruitContentSection.tsx
+++ b/src/app/(pages)/(workform)/addform/section/RecruitContentSection.tsx
@@ -1,4 +1,5 @@
"use client";
+
import BaseInput from "@/app/components/input/text/BaseInput";
import BaseTextArea from "@/app/components/input/textarea/BaseTextArea";
import DatePickerInput from "@/app/components/input/dateTimeDaypicker/DatePickerInput";
@@ -10,7 +11,6 @@ import { ImageInputType } from "@/types/addform";
import useUploadImages from "@/hooks/queries/user/me/useImageUpload";
import { formatToLocaleDate } from "@/utils/formatters";
import DotLoadingSpinner from "@/app/components/loading-spinner/DotLoadingSpinner";
-import { isDirty } from "zod";
import ImageInput from "@/app/components/input/file/ImageInput/ImageInput";
// 워크폼 만들기 - 사장님 - 1-모집내용
diff --git a/src/app/(pages)/work-talk/[talkId]/edit/page.tsx b/src/app/(pages)/work-talk/[talkId]/edit/page.tsx
index 9d699585..704cbce4 100644
--- a/src/app/(pages)/work-talk/[talkId]/edit/page.tsx
+++ b/src/app/(pages)/work-talk/[talkId]/edit/page.tsx
@@ -1,11 +1,10 @@
"use client";
import React, { useState, useCallback, useEffect } from "react";
-import { useForm, SubmitHandler, Controller } from "react-hook-form";
+import { useForm, SubmitHandler, Controller, FormProvider } from "react-hook-form";
import { useRouter } from "next/navigation";
import Button from "@/app/components/button/default/Button";
import BaseInput from "@/app/components/input/text/BaseInput";
-import ImageInputPlaceHolder from "@/app/components/input/file/ImageInput/ImageInputPlaceHolder";
import { useEditPost } from "@/hooks/queries/post/useEditPost";
import { usePostDetail } from "@/hooks/queries/post/usePostDetail";
import axios from "axios";
@@ -14,29 +13,11 @@ import { PostSchema } from "@/schemas/postSchema";
import toast from "react-hot-toast";
import LoadingSpinner from "@/app/components/loading-spinner/LoadingSpinner";
import { useQueryClient } from "@tanstack/react-query";
-
-interface ImageInputType {
- file: File | null;
- url: string;
- id: string;
-}
+import ImageInput from "@/app/components/input/file/ImageInput/ImageInput";
+import { ImageInputType } from "@/types/addform";
export default function EditTalk({ params }: { params: { talkId: string } }) {
- const [imageList, setImageList] = useState([]);
- const router = useRouter();
- const postId = params.talkId;
-
- const { data: post, isLoading, error } = usePostDetail(postId);
- const { mutate: editPost, isPending } = useEditPost(postId);
- const queryClient = useQueryClient();
-
- const {
- control,
- handleSubmit,
- setValue,
- formState: { errors },
- reset,
- } = useForm({
+ const methods = useForm({
defaultValues: {
title: "",
content: "",
@@ -44,6 +25,23 @@ export default function EditTalk({ params }: { params: { talkId: string } }) {
},
});
+ const {
+ control,
+ handleSubmit,
+ formState: { errors },
+ reset,
+ setValue,
+ } = methods;
+
+ const [isUploading, setIsUploading] = useState(false);
+ const [uploadedImages, setUploadedImages] = useState([]);
+ const router = useRouter();
+ const postId = params.talkId;
+
+ const { data: post, isLoading, error } = usePostDetail(postId);
+ const { mutate: editPost, isPending } = useEditPost(postId);
+ const queryClient = useQueryClient();
+
// 게시글 데이터로 폼 초기화
useEffect(() => {
if (post) {
@@ -53,16 +51,13 @@ export default function EditTalk({ params }: { params: { talkId: string } }) {
imageUrl: post.imageUrl || "",
});
+ // 이미지 초기화
if (post.imageUrl) {
- setImageList([
- {
- file: null,
- url: post.imageUrl,
- id: "initial-image",
- },
- ]);
- } else {
- setImageList([]);
+ const initialImages = post.imageUrl.split(",").map((url) => ({
+ url,
+ id: crypto.randomUUID(),
+ }));
+ setUploadedImages(initialImages);
}
}
}, [post, reset]);
@@ -81,48 +76,31 @@ export default function EditTalk({ params }: { params: { talkId: string } }) {
try {
const response = await axios.post("/api/images/upload", formData, {
- headers: {
- "Content-Type": "multipart/form-data",
- },
+ headers: { "Content-Type": "multipart/form-data" },
});
-
- if (response.status === 201 && response.data?.url) {
- return response.data.url;
- }
-
- throw new Error("이미지 업로드에 실패했습니다.");
+ return response.data.url;
} catch (error) {
- toast.error("이미지 업로드에 실패했습니다.");
console.error("이미지 업로드 실패:", error);
throw error;
}
}, []);
- const handleImagesChange = useCallback(
- (newImages: ImageInputType[]) => {
- setImageList(newImages);
- const imageUrls = newImages.map((img) => img.url).join(",");
- setValue("imageUrl", imageUrls);
- },
- [setValue]
- );
-
const onSubmit: SubmitHandler = async (data) => {
try {
- if (!data.title) {
- toast.error("제목을 입력하세요.");
+ if (!data.title || !data.content) {
+ toast.error("제목과 내용을 입력하세요.");
return;
}
- if (!data.content) {
- toast.error("내용을 입력하세요.");
+ if (isUploading) {
+ toast.error("이미지 업로드가 완료될 때까지 기다려주세요.");
return;
}
const postData: PostSchema = {
title: data.title,
content: data.content,
- imageUrl: imageList.map((img) => img.url).join(","),
+ imageUrl: data.imageUrl,
};
editPost(postData, {
@@ -154,108 +132,160 @@ export default function EditTalk({ params }: { params: { talkId: string } }) {
if (!post) return null;
return (
-
-
-
-
- 게시글 수정하기
-
-
-
-
-
-
-