Skip to content

Commit 41134eb

Browse files
authored
Merge pull request #122 from FE9-2/refactor/albaFormDetail
Refactor: ์•Œ๋ฐ”ํผ ์ƒ์„ธํŽ˜์ด์ง€ ์ง€์›์ž/์‚ฌ์žฅ๋‹˜ ๊ฐ™์€ url์—์„œ ๋ถ„๊ธฐ
2 parents c73c5f3 + cecf3e9 commit 41134eb

File tree

15 files changed

+275
-328
lines changed

15 files changed

+275
-328
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"use client";
2+
3+
import { useParams } from "next/navigation";
4+
import React, { useEffect, useState } from "react";
5+
import { useUser } from "@/hooks/queries/user/me/useUser";
6+
import FormHeader from "../components/FormHeader";
7+
import FormDetails from "../components/FormDetail";
8+
import RecruitInformation from "../components/RecruitInfomation";
9+
import ApplicationStatus from "../components/ApplicationStatus";
10+
import { useFormDetail } from "@/hooks/queries/form/detail/useFormDetail";
11+
12+
export default function AlbaFormDetailPage() {
13+
const { formId } = useParams(); // useParams๋กœ formId ์ถ”์ถœ
14+
const [formIdState, setFormIdState] = useState<number>(0);
15+
const { user } = useUser();
16+
const isOwner = user?.role === "OWNER";
17+
18+
useEffect(() => {
19+
// formId๊ฐ€ ๋ฌธ์ž์—ด๋กœ ์ „๋‹ฌ๋˜๋ฏ€๋กœ ์ˆซ์ž๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ƒํƒœ์— ์ €์žฅ
20+
if (formId) {
21+
setFormIdState(Number(formId)); // formId๋ฅผ ์ˆซ์ž๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ƒํƒœ์— ์ €์žฅ
22+
}
23+
}, [formId]);
24+
25+
// formId๊ฐ€ ์„ค์ •๋˜๋ฉด useFormDetail ํ˜ธ์ถœ
26+
const { albaFormDetailData, isLoading, error } = useFormDetail({ formId: formIdState });
27+
28+
if (isLoading) return <div>Loading...</div>;
29+
30+
if (error) return <div>Error: ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.</div>;
31+
32+
if (!albaFormDetailData) return <div>๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</div>;
33+
34+
return (
35+
<div className="container flex min-h-screen flex-col">
36+
<div className="h-[562px] bg-black-100">์‚ฌ์ง„์˜์—ญ</div>
37+
<div className="mt-20 flex justify-between">
38+
{/* ์™ผ์ชฝ ์˜์—ญ */}
39+
<div className="w-[770px] space-y-10">
40+
<FormHeader albaFormDetailData={albaFormDetailData} />
41+
<FormDetails albaFormDetailData={albaFormDetailData} />
42+
{/* ์ง€๋„ ์˜์—ญ */}
43+
<div className="h-[400px] bg-black-100">์นด์นด์˜ค์ง€๋„</div>
44+
</div>
45+
{/* ์˜ค๋ฅธ์ชฝ ์˜์—ญ */}
46+
<div className="flex w-[640px] flex-col space-y-12">
47+
<RecruitInformation albaFormDetailData={albaFormDetailData} />
48+
</div>
49+
</div>
50+
{/* ์ง€์› ํ˜„ํ™ฉ */}
51+
{isOwner && <ApplicationStatus formId={formIdState} />}
52+
</div>
53+
);
54+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import ApplicationStatusCard from "@/app/components/card/cardList/ApplicationStatusCard";
2+
import { useApplicationStatus } from "@/hooks/queries/form/detail/useApplicationStatus";
3+
import React from "react";
4+
5+
interface ApplicationStatusProps {
6+
formId: number;
7+
}
8+
9+
export default function ApplicationStatus({ formId }: ApplicationStatusProps) {
10+
const { applicationStatusData, isLoading, error } = useApplicationStatus({
11+
formId,
12+
limit: 5, // ์š”์ฒญ๋‹น ๋ฐ์ดํ„ฐ ์ˆ˜ ์ œํ•œ
13+
});
14+
15+
if (isLoading) return <div>์ง€์› ํ˜„ํ™ฉ์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค...</div>;
16+
if (error && "status" in error) {
17+
if (error.status === 403) {
18+
return (
19+
<div>
20+
<p>์ง€์› ํ˜„ํ™ฉ์„ ๋ณผ ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค.</p>
21+
<p>{error.message}</p>
22+
</div>
23+
);
24+
}
25+
console.log("์ง€์›ํ˜„ํ™ฉ ์—๋Ÿฌ", error);
26+
}
27+
if (error || !applicationStatusData) return <div>์ง€์› ํ˜„ํ™ฉ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š”๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.</div>;
28+
console.log("applicationStatusData:", applicationStatusData);
29+
30+
return (
31+
<div className="space-y-4 text-2xl">
32+
<p className="text-3xl font-bold">์ง€์› ํ˜„ํ™ฉ</p>
33+
34+
<ApplicationStatusCard applicationStatusData={applicationStatusData.data} />
35+
</div>
36+
);
37+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from "react";
2+
import Button from "@/app/components/button/default/Button";
3+
import { FcEmptyTrash } from "react-icons/fc";
4+
import { FcEditImage } from "react-icons/fc";
5+
import { FcFile } from "react-icons/fc";
6+
import { FcSearch } from "react-icons/fc";
7+
8+
interface FormActionsProps {
9+
isOwner: boolean;
10+
}
11+
12+
export default function FormActions({ isOwner }: FormActionsProps) {
13+
return (
14+
<div className="space-y-4 text-2xl">
15+
<Button className="h-16" width="lg" icon={isOwner ? <FcEditImage /> : <FcFile />}>
16+
{isOwner ? "์ˆ˜์ •ํ•˜๊ธฐ" : "์ง€์›ํ•˜๊ธฐ"}
17+
</Button>
18+
<Button className="h-16" width="lg" icon={isOwner ? <FcEmptyTrash /> : <FcSearch />} variant="outlined">
19+
{isOwner ? "์‚ญ์ œํ•˜๊ธฐ" : "๋‚ด ์ง€์›๋‚ด์—ญ ๋ณด๊ธฐ"}
20+
</Button>
21+
</div>
22+
);
23+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { FormDetailResponse } from "@/types/response/form";
2+
import React from "react";
3+
import toast from "react-hot-toast";
4+
5+
interface FormDetailsProps {
6+
albaFormDetailData: FormDetailResponse;
7+
}
8+
9+
export default function FormDetails({ albaFormDetailData }: FormDetailsProps) {
10+
const handleCopyLocation = () => {
11+
navigator.clipboard.writeText(albaFormDetailData.location);
12+
toast.success("๊ทผ๋ฌด์ง€์—ญ์ด ๋ณต์‚ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
13+
};
14+
15+
return (
16+
<>
17+
<div className="mb-4 flex items-end gap-4">
18+
<span className="text-2xl text-black-400 underline">{albaFormDetailData.storeName || "๊ฐ€๊ฒŒ๋ช…"}</span>
19+
<span className="text-xl text-grayscale-500">
20+
{albaFormDetailData.location || "์œ„์น˜"} ใƒป {"๊ฒฝ๋ ฅ ์ •๋ณด ์—†์Œ"}
21+
</span>
22+
</div>
23+
<p className="text-3xl font-bold">{albaFormDetailData.title}</p>
24+
<div className="space-y-32">
25+
<div className="text-2xl">{albaFormDetailData.description}</div>
26+
<p className="text-3xl font-bold">๊ทผ๋ฌด ์ง€์—ญ</p>
27+
</div>
28+
<div className="flex space-x-5 text-2xl">
29+
<p>{albaFormDetailData.location}</p>
30+
<button className="text-xl text-primary-orange-300" onClick={handleCopyLocation}>
31+
๋ณต์‚ฌ
32+
</button>
33+
</div>
34+
</>
35+
);
36+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from "react";
2+
import Chip from "@/app/components/chip/Chip";
3+
import { FormDetailResponse } from "@/types/response/form";
4+
5+
interface FormHeaderProps {
6+
albaFormDetailData: FormDetailResponse;
7+
}
8+
9+
export default function FormHeader({ albaFormDetailData }: FormHeaderProps) {
10+
const recruitmentStatus = new Date(albaFormDetailData.recruitmentEndDate) > new Date() ? "๋ชจ์ง‘์ค‘" : "๋ชจ์ง‘์™„๋ฃŒ";
11+
return (
12+
<div className="flex items-center">
13+
<Chip
14+
label={albaFormDetailData.isPublic ? "๊ณต๊ฐœ" : "๋น„๊ณต๊ฐœ"}
15+
variant={albaFormDetailData.isPublic ? "positive" : "negative"}
16+
/>
17+
<Chip label={recruitmentStatus} variant="positive" />
18+
<p className="ml-2 text-lg text-grayscale-500">{new Date(albaFormDetailData.createdAt).toLocaleString()} ๋“ฑ๋ก</p>
19+
</div>
20+
);
21+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from "react";
2+
import RecruitDetail from "@/app/components/card/cardList/RecruitDetail";
3+
import RecruitIcon from "@/app/components/card/cardList/RecruitIcon";
4+
import RecruitCondition from "@/app/components/card/cardList/RecruitCondition";
5+
import { FormDetailResponse } from "@/types/response/form";
6+
import FormActions from "./FormActions";
7+
import { useUser } from "@/hooks/queries/user/me/useUser";
8+
9+
interface FormDetailsProps {
10+
albaFormDetailData: FormDetailResponse;
11+
}
12+
13+
export default function RecruitInformation({ albaFormDetailData }: FormDetailsProps) {
14+
const { user } = useUser();
15+
const isOwner = user?.role === "OWNER";
16+
17+
const recruitmentDetails = {
18+
hourlyWage: albaFormDetailData.hourlyWage,
19+
recruitmentStartDate: new Date(albaFormDetailData.recruitmentStartDate),
20+
recruitmentEndDate: new Date(albaFormDetailData.recruitmentEndDate),
21+
isNegotiableWorkDays: albaFormDetailData.isNegotiableWorkDays,
22+
workDays: albaFormDetailData.workDays,
23+
workStartTime: albaFormDetailData.workStartTime,
24+
workEndTime: albaFormDetailData.workEndTime,
25+
};
26+
27+
return (
28+
<>
29+
<RecruitIcon {...recruitmentDetails} />
30+
<RecruitDetail recruitData={albaFormDetailData} />
31+
<FormActions isOwner={isOwner} />
32+
33+
<p className="text-3xl font-bold">๋ชจ์ง‘ ์กฐ๊ฑด</p>
34+
<RecruitCondition recruitData={albaFormDetailData} />
35+
</>
36+
);
37+
}

โ€Žsrc/app/(pages)/albaFormDetail/applicant/[formId]/page.tsxโ€Ž

Lines changed: 0 additions & 74 deletions
This file was deleted.

โ€Žsrc/app/(pages)/albaFormDetail/owner/[id]/page.tsxโ€Ž

Lines changed: 0 additions & 49 deletions
This file was deleted.

โ€Žsrc/app/(pages)/albaList/page.tsxโ€Ž

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ export default function AlbaList() {
149149
<React.Fragment key={page.nextCursor}>
150150
{page.data.map((form) => (
151151
<div key={form.id}>
152-
<AlbaListItem {...form} />
152+
<Link href={`/alba/${form.id}`}>
153+
<AlbaListItem {...form} />
154+
</Link>
153155
</div>
154156
))}
155157
</React.Fragment>

0 commit comments

Comments
ย (0)