Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

작품 수상 결과 페이지 API 연결 #117

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/components/common/ProjectCard/ProjectCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function ProjectCard({
}: ProjectCardProps) {
const studentsString = data.studentNames.join(", ");
const professorString = data.professorNames.join(", ");

return (
<Card className={classes.card} w={width} h={height}>
<CardSection className={classes["img-section"]}>
Expand Down
127 changes: 103 additions & 24 deletions src/components/pages/EventAwardView/EventAwardView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,105 @@ import { useEffect, useState } from "react";
import classes from "./EventAwardView.module.css";
import { Text } from "@mantine/core";
import { Carousel, CarouselSlide } from "@mantine/carousel";
import {
years as mock_years,
awards as mock_awards,
projects as mock_projects,
} from "./_mock/mock-awards";
import { getYears } from "@/utils/getYears";
import { CommonAxios } from "@/utils/CommonAxios";
import { AWARD_TYPE_LOOKUP_TABLE } from "@/constants/LookupTables";
import { IProjectContent } from "@/types/project";
import { getFileUrlById } from "@/utils/handleDownloadFile";

export function EventAwardView() {
const [years, setYears] = useState<string[]>([]);
const [selectedYear, setSelectedYear] = useState<string>("");
const [projects, setProjects] = useState<IProjectContent[]>([]);
const [thumbnailUrls, setThumbnailUrls] = useState<string[]>([]);

const years = getYears();

/**
* 가장 최근 연도를 디폴트로 설정
*/
useEffect(() => {
/* TODO: 연도 목록 가져오기 */
setYears(mock_years);
if (mock_years.length > 0) {
// 가장 최근 연도를 디폴트로
setSelectedYear(mock_years[0]);
if (!selectedYear && years && years.length > 0) {
setSelectedYear(years[0]);
}
}, []);
}, [years, selectedYear]);

/**
* 연도 바뀔 때마다 수상작 가져오기
*/
useEffect(() => {
/* TODO: 선택된 연도의 수상 결과 가져오기 */
const fetchAwards = async () => {
try {
const response = await CommonAxios.get(`projects/award?year=${selectedYear}`);
const projectDatas: IProjectContent[] = response.data?.content;
setProjects(projectDatas);
// thumbnail url 가져오기
const promises = projectDatas.map((data) => getFileUrlById(data.thumbnailInfo.id));
const urlResults = await Promise.all(promises);
setThumbnailUrls(urlResults);
} catch (error) {
console.error("Error fetching awards:", error);
} finally {
}
};
fetchAwards();
}, [selectedYear]);

/**
* like 핸들러
*/
const handleClickLike = async (idx: number) => {
const data = projects[idx];
try {
if (data.like) {
await CommonAxios.delete(`/projects/${data.id}/like`);
updateProjectLikeStatus(idx, false);
} else {
await CommonAxios.post(`/projects/${data.id}/like`);
updateProjectLikeStatus(idx, true);
}
} catch (error) {
console.error("Failed to toggle like:", error);
}
};

/**
* bookMark 핸들러
*/
const handleClickBookMark = async (idx: number) => {
const data = projects[idx];
try {
if (data.bookMark) {
await CommonAxios.delete(`/projects/${data.id}/favorite`);
updateProjectBookMarkStatus(idx, false);
} else {
await CommonAxios.post(`/projects/${data.id}/favorite`);
updateProjectBookMarkStatus(idx, true);
}
} catch (error) {
console.error("Failed to toggle bookmark:", error);
}
};

/**
* 프로젝트 like 상태 업데이트
*/
const updateProjectLikeStatus = (idx: number, likeStatus: boolean) => {
setProjects((prevProjects) =>
prevProjects.map((project, i) => (i === idx ? { ...project, like: likeStatus } : project))
);
};

/**
* 프로젝트 bookMark 상태 업데이트
*/
const updateProjectBookMarkStatus = (idx: number, bookMarkStatus: boolean) => {
setProjects((prevProjects) =>
prevProjects.map((project, i) =>
i === idx ? { ...project, bookMark: bookMarkStatus } : project
)
);
};

return (
<div className={classes.container}>
<Dropdown
Expand All @@ -39,17 +115,20 @@ export function EventAwardView() {
></Dropdown>
<Text className={classes.subtitle}>{selectedYear}년도 수상 내역</Text>
<Carousel dragFree slideGap="md" slideSize="20%" align="start" containScroll="trimSnaps">
{mock_projects.map((data, idx) => (
<CarouselSlide key={idx}>
<Text className={classes.awardType}>{mock_awards[idx]}</Text>
<ProjectCard
data={data}
thumbnailUrl={""}
onClickBookmark={() => {}}
onClickLike={() => {}}
/>
</CarouselSlide>
))}
{projects.map((data, idx) => {
const thumbnailUrl = thumbnailUrls[idx];
return (
<CarouselSlide key={idx}>
<Text className={classes.awardType}>{AWARD_TYPE_LOOKUP_TABLE[data.awardStatus]}</Text>
<ProjectCard
data={data}
thumbnailUrl={thumbnailUrl}
onClickLike={() => handleClickLike(idx)}
onClickBookmark={() => handleClickBookMark(idx)}
/>
</CarouselSlide>
);
})}
</Carousel>
</div>
);
Expand Down
10 changes: 10 additions & 0 deletions src/constants/LookupTables.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Role } from "@/types/user";
import { ProjectAwardStatus } from "@/types/project";

export const USER_TYPE_LOOKUP_TABLE: Record<Role, string> = {
STUDENT: "학생",
Expand All @@ -10,3 +11,12 @@ export const USER_TYPE_LOOKUP_TABLE: Record<Role, string> = {
OTHERS: "기타",
TEMP: "임시",
};

export const AWARD_TYPE_LOOKUP_TABLE: Record<ProjectAwardStatus, string> = {
NONE: "미정",
FIRST: "대상",
SECOND: "최우수상",
THIRD: "우수상",
FOURTH: "인기상",
FIFTH: "장려상",
};
12 changes: 8 additions & 4 deletions src/constants/UserNavigations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,18 @@ export const USER_NAVS: INavList[] = [
{
title: "Events",
items: [
{
name: "갤러리",
link: "/event/gallery",
},
{
name: "이벤트 공지사항",
link: "/event/notices",
},
{
name: "작품 수상 결과",
link: "/event/award",
},
{
name: "갤러리",
link: "/event/gallery",
},
],
},
{
Expand Down
Loading