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

Feature/#160 해커톤 단건 조회 페이지 구현 #167

Merged
merged 42 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
492dea9
feat: 클라이언트 서비스의 페이지네이션 컴포넌트 구현
Aug 13, 2024
dcc23ec
feat: 학생의 마일스톤 획득내역, 실적 목록 페이지네이션 처리
Aug 13, 2024
7d85a78
feat: 나의 마일스톤 획득 내역에 페이지네이션 처리
Aug 13, 2024
8127d7a
fix: 학생의 실적 목록 조회 api의 totalElements가 제대로 불러와지지 않는 문제 해결
Aug 13, 2024
3c4c210
feat: Title 컴포넌트 구현
Aug 14, 2024
9b5c366
Merge branch 'Feature/#150-학생의_마일스톤_획득내역_실적목록_페이지네이션_처리' of https://g…
Aug 14, 2024
107df9d
feat: 해커톤 목록 페이지 구현
Aug 14, 2024
11608ee
refactor: 불필요한 styled comopnent 삭제
Aug 14, 2024
ee540ba
refactor: 파일 다운로드 기능 deprecated
Aug 14, 2024
89625bc
feat: 외부에서 파일 리소스에 직접 접근할 수 있도록 설정
Aug 14, 2024
1747e11
feat: 외부에서 파일 리소스에 직접 접근할 수 있도록 설정
Aug 14, 2024
2a3af0a
Merge branch 'Feature/#155-url로_파일_리소스에_접근할_수_있도록_설정' of https://gith…
Aug 14, 2024
8ebef38
fix: 파일 다운로드 테스트 삭제
Aug 15, 2024
b15dc48
Merge branch 'Feature/#155-url로_파일_리소스에_접근할_수_있도록_설정' of https://gith…
Aug 15, 2024
a589b4f
feat: 해커톤 단건 페이지 중 공고 섹션 구현
Aug 19, 2024
39ffda2
build: Tiptap 라이브러리 설치
Aug 19, 2024
772ac60
feat: 마크다운 뷰어 컴포넌트 구현
Aug 19, 2024
7de3a0b
feat: 해커톤 공고 섹션 완성
Aug 19, 2024
eccf12e
feat: 해커톤 정보 페이지의 타이틀, 전환 버튼을 레이아웃으로 분리
Aug 19, 2024
56815d2
feat: 투표 페이지 내 팀 목록 UI 구현
Aug 19, 2024
891758b
feat: 모달 바깥 요소의 스크롤을 막는 커스텀 훅 구현
Aug 20, 2024
173e2c0
feat: 모달 바깥 영역 클릭 시 모달을 닫는 커스텀 훅 구현
Aug 20, 2024
6649efb
build: classname 라이브러리 설치
Aug 20, 2024
25b905e
build: react-markdown 라이브러리 설치
Aug 20, 2024
6df5b80
build: tiptap 커스텀에 필요한 라이브러리 설치
Aug 21, 2024
cce5f79
feat: 해커톤 팀 조회 모달 구현
Aug 21, 2024
2a987e1
design: 팀 정보 조회 모달 반응형 처리
Aug 21, 2024
5032f3c
feat: 해커톤 수상 내역 조회 페이지 구현
Aug 21, 2024
9432a4c
feat: 드래그&드랍 이미지 업로더 컴포넌트 구현
Aug 25, 2024
a152aef
build: 드래그&드랍 라이브러리 설치
Aug 25, 2024
7ff2687
refactor: 해커톤의 thumbnailImageName을 bannerImageName으로 변경
Aug 25, 2024
d0c29f8
fix: dropdown 컴포넌트의 옵션 목록의 위치가 요소 위치에 맞춰 변경되도록 수정
Aug 25, 2024
f6ffde7
feat: 해커톤 팀 등록 모달 구현
Aug 25, 2024
d7f33a5
feat: 디바운싱 기능을 제공하는 커스텀 훅 구현
Aug 25, 2024
518cbab
feat: 팀원 학번 입력 시 팀원의 정보를 검색하는 기능 구현
Aug 25, 2024
91eee22
design: 해커톤 팀 생성 모달 반응형 처리
Aug 25, 2024
3537b57
fix: 목데이터에 누락된 속성값 추가
Aug 25, 2024
a4f63cd
Merge branch 'main' into Feature/#160-해커톤_단건_조회_페이지_구현
amaran-th Aug 25, 2024
96a2eb8
fix: 중복된 import문 삭제
Aug 25, 2024
98a4ab1
fix: 중복된 api 호출 함수 정의 삭제
Aug 25, 2024
3e6a415
fix: 자잘한 오류 해결
Aug 25, 2024
0e2bd89
feat: 원활한 테스트를 위한 테스트 데이터 추가
Aug 25, 2024
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 frontend/.babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"presets": ["next/babel"],
"presets": ["next/babel","@babel/preset-env" ],
"plugins": [["styled-components", { "ssr": true }]]
}
8 changes: 7 additions & 1 deletion frontend/babel.config.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-private-methods"]
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-private-methods"],
"overrides": [
{
"include": "./node_modules/linkifyjs",
"presets": ["@babel/preset-env"]
}
]
}
4,109 changes: 3,405 additions & 704 deletions frontend/package-lock.json

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,63 @@
"lint": "next lint"
},
"dependencies": {
"@babel/runtime": "^7.25.0",
"@react-icons/all-files": "^4.1.0",
"@reduxjs/toolkit": "^2.2.5",
"@tanstack/react-query": "^5.48.0",
"@tanstack/react-query-devtools": "^5.48.0",
"@tanstack/react-query-next-experimental": "^5.48.0",
"@tiptap/extension-blockquote": "^2.6.4",
"@tiptap/extension-code": "^2.6.4",
"@tiptap/extension-code-block-lowlight": "^2.6.4",
"@tiptap/extension-highlight": "^2.6.4",
"@tiptap/extension-image": "^2.6.4",
"@tiptap/extension-link": "^2.6.4",
"@tiptap/extension-table": "^2.6.4",
"@tiptap/extension-table-cell": "^2.6.4",
"@tiptap/extension-table-header": "^2.6.4",
"@tiptap/extension-table-row": "^2.6.4",
"@tiptap/extension-task-item": "^2.6.4",
"@tiptap/extension-task-list": "^2.6.4",
"@tiptap/extension-typography": "^2.6.4",
"@tiptap/pm": "^2.6.4",
"@tiptap/react": "^2.6.4",
"@tiptap/starter-kit": "^2.6.4",
"axios": "^1.7.2",
"babel-plugin-styled-components": "^2.1.4",
"classnames": "^2.5.1",
"formik": "^2.4.6",
"lowlight": "^3.1.0",
"luxon": "^3.4.4",
"marked": "^14.0.0",
"next": "14.2.3",
"react": "^18",
"react-cookies": "^0.1.1",
"react-dom": "^18",
"react-dropzone": "^14.2.3",
"react-redux": "^9.1.2",
"react-toastify": "^10.0.5",
"redux": "^5.0.1",
"redux-persist": "^6.0.0",
"rss-parser": "^3.13.0",
"styled-components": "^6.1.11",
"swiper": "^11.1.4",
"tiptap-markdown": "^0.8.10",
"yup": "^1.4.0"
},
"devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@babel/preset-env": "^7.25.3",
"@tailwindcss/typography": "^0.5.14",
"@types/classnames": "^2.3.1",
"@types/luxon": "^3.4.2",
"@types/node": "^20",
"@types/prismjs": "^1.26.4",
"@types/react": "^18",
"@types/react-cookies": "^0.1.3",
"@types/react-dom": "^18",
"@types/react-syntax-highlighter": "^15.5.13",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';

import { hackathonInformationTypes } from '@/data/hackathon';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
interface HackathonInformationTypeButtonsProps {
slug: number;
}
const HackathonInformationTypeButtons = ({ slug }: HackathonInformationTypeButtonsProps) => {
const pathname = usePathname();

return (
<div className="flex flex-wrap border-b border-border">
{hackathonInformationTypes.map((type) => (
<Link
href={type.path(slug)}
className={`h-[30px] border-0 bg-white px-4 ${pathname === type.path(slug) ? 'border-b-2 font-bold text-black' : 'text-comment'} border-black hover:border-b-2 hover:text-black`}
key={type.name}
>
{type.name}
</Link>
))}
</div>
);
};

export default HackathonInformationTypeButtons;
19 changes: 19 additions & 0 deletions frontend/src/app/(withSidebar)/hackathon/[slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Title from '@/components/Title';
import { getHackathonInformation } from '@/lib/api/server.api';
import HackathonInformationTypeButtons from './components/HackathonInformationTypeButtons';

const Layout = async ({
children,
params: { slug },
}: Readonly<{ children: React.ReactNode; params: { slug: number } }>) => {
const hackathonInformation = await getHackathonInformation(slug);
return (
<div className="flex w-full flex-col gap-4 rounded-sm bg-white p-5">
<Title title={hackathonInformation.name} />
<div className="h-0 w-full border border-border" />
<HackathonInformationTypeButtons slug={slug} />
<div>{children}</div>
</div>
);
};
export default Layout;
34 changes: 34 additions & 0 deletions frontend/src/app/(withSidebar)/hackathon/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import MarkdownViewer from '@/components/MarkdownViewer';
import { getHackathonInformation } from '@/lib/api/server.api';
import Image from 'next/image';

interface HackathonDetailPageProps {
params: {
slug: number;
};
}

const Page = async ({ params: { slug } }: HackathonDetailPageProps) => {
const hackathonInformation = await getHackathonInformation(slug);
return (
<div>
<div className="relative h-60 w-full">
<Image
src={process.env.NEXT_PUBLIC_FILE_URL + '/' + hackathonInformation.bannerImageName}
alt="해커톤 섬네일"
className="rounded-t-sm"
layout="fill"
objectFit="cover"
objectPosition="center"
quality={100}
/>
</div>
<div className="m-2 flex flex-col justify-center gap-2">
<div className="text-xl font-bold">{hackathonInformation.name} 참가자 모집 안내</div>
<MarkdownViewer content={hackathonInformation.content} />
</div>
</div>
);
};

export default Page;
53 changes: 53 additions & 0 deletions frontend/src/app/(withSidebar)/hackathon/[slug]/prize/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { getHackathonPrize } from '@/lib/api/server.api';

interface HackathonPrizePageProps {
params: {
slug: number;
};
}

const Page = async ({ params: { slug } }: HackathonPrizePageProps) => {
const prizes = await getHackathonPrize(slug);
if (!prizes || prizes.length == 0)
return (
<div className="flex h-40 w-full items-center justify-center text-comment">수상 결과가 공개되지 않았습니다.</div>
);
return (
<div className="flex w-full flex-col gap-4 rounded-sm bg-white">
<table className="border-collapse text-center">
<thead>
<tr className="border-y-2 border-primary-main bg-primary-light text-primary-main">
<th className="py-2">상훈</th>
<th>수상팀(팀원수)</th>
<th>수상 작품</th>
</tr>
</thead>
<tbody>
{prizes.map((prize) => (
<>
<tr className="border-y border-border">
<td rowSpan={prize.teams.length} className="py-2">
{prize.name}
</td>
<td className="py-2">
{prize.teams[0].name}({prize.teams[0].memberCount})
</td>
<td>{prize.teams[0].work}</td>
</tr>
{prize.teams.slice(1).map((team) => (
<tr key={team.name} className="border-y border-border">
<td className="py-2">
{team.name}({team.memberCount})
</td>
<td>{team.work}</td>
</tr>
))}
</>
))}
</tbody>
</table>
</div>
);
};

export default Page;
Loading