Skip to content
Merged
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
159 changes: 134 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,149 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
# 만취
- 만취는 많은 사람들이 함께할 수 있는 취미가 같은 사람들의 자유로운 모임 플랫폼입니다.
<img width="924" alt="스크린샷 2025-02-01 오후 5 03 13" src="https://github.com/user-attachments/assets/ab15a462-651f-44d0-8837-fb53219dcef9" />

## Getting Started
## 소개 및 개요

First, run the development server:
- 프로젝트 기간: 2024.10 ~ 2024.12
- 배포 URL: [🚀 만취](https://manchui.vercel.app/)

### [프로젝트 소개]
- 만취는 많은 사람들이 함께할 수 있는 취미가 같은 사람들의 자유로운 모임 플랫폼입니다.
- 사용자는 9개의 카테고리(개발, 운동, 영화, 공부, 문화/예술, 게임, 여행, 맛집, 음악) 중에서 자신의 취향에 맞는 모임을 선택하고, 인기 모임 목록도 확인할 수 있습니다.
- 각 모임의 상세 페이지에서는 해당 모임의 위치와 지도를 확인할 수 있습니다.
- 실시간 채팅을 통해 모임장과 모임원들 간의 자유로운 소통이 가능하며, 알림 기능으로 모임 관련 업데이트를 확인할 수 있습니다.
- 모임이 끝난 후, 사용자는 직접 별점과 후기를 남길 수 있습니다.


## 협업 팀 소개
### Frontend Dev
| **은동혁** | **이용환** | **소희** | **이인지** |
| :-----------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: |
| <img src="https://github.com/miraclee1226/Fandom-k/assets/96684473/5e912514-8a79-4d3f-b577-eabd703b18bd" height=180 width=180> | <img src="https://github.com/user-attachments/assets/812cd46e-db96-432b-be88-48d0472e9257" height=180 width=180> | <img src="https://github.com/user-attachments/assets/ea7a87eb-712f-449b-a5b0-6fc598780a19" height=180 width=180> | <img src="https://github.com/user-attachments/assets/a072b9c4-fd38-4da2-9353-87bb9d47c240" height=180 width=180> |
| **github**: [edhcoding](https://github.com/edhcoding) | **github**: [Yong Lee](https://github.com/YongLeeCode) | **github**: [han9898](https://github.com/han9898) | **github**: [inji(FE)](https://github.com/inji0212) |

### Backend Dev(2) / Designer(1)
| 김병훈 | 오예령 | 권하은 |
| :-----------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------: |
| <img src="https://github.com/user-attachments/assets/0da27b2a-7740-4b71-ad54-489542fd834d" height=180 width=180> | <img src="https://github.com/user-attachments/assets/06bb3109-5ce3-4f6a-a156-090816ebc542" height=180 width=180> | <img src="https://github.com/user-attachments/assets/0da27b2a-7740-4b71-ad54-489542fd834d" height=180 width=180> |
| **github**: [yosong6729](https://github.com/yosong6729) | **github**: [ohyeryung](https://github.com/ohyeryung) | **github**: [---] |


## 기술 및 개발 환경
#### [기술 스택]
![Next JS](https://img.shields.io/badge/Next-black?style=for-the-badge&logo=next.js&logoColor=white)
![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)
![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white)
![React Query](https://img.shields.io/badge/TanStack%20Query-FF4154?style=for-the-badge&logo=react&logoColor=white)

#### [기술 도구]
![Yarn](https://img.shields.io/badge/yarn-%232C8EBB.svg?style=for-the-badge&logo=yarn&logoColor=white)
![Figma](https://img.shields.io/badge/figma-%23F24E1E.svg?style=for-the-badge&logo=figma&logoColor=white)
![Git](https://img.shields.io/badge/git-%23F05033.svg?style=for-the-badge&logo=git&logoColor=white)

#### [협력 도구]
![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)
![Notion](https://img.shields.io/badge/Notion-%23000000.svg?style=for-the-badge&logo=notion&logoColor=white)
![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white)

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
## 페이지 구성 및 기능
|랜딩 페이지|로그인 페이지|회원가입 페이지|
|:---:|:---:|:---:|
|![image](https://github.com/user-attachments/assets/f14b22b3-0bf6-442e-a701-2015d829a898)|![image](https://github.com/user-attachments/assets/a76558d8-1c7c-4ced-90de-825025e0ae53)|![image](https://github.com/user-attachments/assets/373ce440-944a-4e38-98b3-1767be6bae50)|

You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
|메인 페이지|찜한 모임 페이지|모임 등록 페이지|
|:---:|:---:|:---:|
|![image](https://github.com/user-attachments/assets/f14b878e-92fb-4290-a0c9-796f3b567ced)|![image](https://github.com/user-attachments/assets/aed772ac-bb93-41a9-89b0-b0712d301a97)|![image](https://github.com/user-attachments/assets/b0a0e06b-e0ad-4ac6-a44d-bcbfd03f4837)<br/>![image](https://github.com/user-attachments/assets/f9231f04-ba09-4506-961d-a8cecdb3554c)|

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
|모든 리뷰 페이지|마이 페이지|모임 상세 페이지|
|:---:|:---:|:---:|
|![image](https://github.com/user-attachments/assets/b64aed22-8378-457d-bafd-e31ed868fbd0)|![image](https://github.com/user-attachments/assets/5bc132ab-a49c-4f3b-b597-c1d8a46ef47c)|![image](https://github.com/user-attachments/assets/42476c2c-ecac-439a-91e1-a8d011160005)|

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
|FAQ 및 고객지원 페이지|알림 기능|실시간 채팅 기능|
|:---:|:---:|:---:|
|![image](https://github.com/user-attachments/assets/ecb026b3-de6d-40c8-809d-a322cdf4522b)<br/>![image](https://github.com/user-attachments/assets/ecb45998-31b9-4776-9570-6c96c97ae55a)|![image](https://github.com/user-attachments/assets/d4006d11-4059-4126-b3b9-250fbb7428df)|![image](https://github.com/user-attachments/assets/b43a4854-ee15-49df-9b4b-9f9d5e51742f)|

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More
## 주요 기능 소개
#### ⭐ 메인 페이지: 모임 검색 및 필터링
- 9개의 다양한 카테고리(개발, 운동, 영화, 공부, 문화/예술, 게임, 여행, 맛집, 음악)를 통해 원하는 모임을 찾을 수 있습니다.
- 지역, 날짜, 키워드 검색으로 원하는 모임을 쉽게 찾을 수 있습니다.

To learn more about Next.js, take a look at the following resources:
#### ⭐ 모임 생성 및 관리
- 모임 이름, 카테고리, 설명, 장소, 최소/최대 인원 등을 설정하여 새로운 모임을 만들 수 있습니다.
- 모임 일정과 장소를 지도를 통해 직관적으로 설정할 수 있습니다.

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
#### ⭐ 실시간 채팅 기능
- 모임원들과 실시간으로 소통할 수 있는 채팅방을 제공합니다.
- 모임 관련 문의사항이나 정보를 자유롭게 공유할 수 있습니다.
- 채팅방에서 모임 관련 중요 공지사항을 확인할 수 있습니다.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
#### ⭐ 알림 시스템
- 새로운 참여자 알림, 모임 찜하기, 채팅 메시지 등 중요한 업데이트를 실시간으로 받아볼 수 있습니다.
- 모바일에서는 좌•우 슬라이드로 알림 삭제가 가능합니다.
- 모임 관련 주요 알림을 놓치지 않고 확인할 수 있습니다.

#### ⭐ 리뷰 시스템
- 모임 참여 후 별점과 상세 리뷰를 작성할 수 있습니다.
- 카테고리, 지역, 날짜별로 리뷰를 필터링하여 볼 수 있습니다.
- 다른 사용자들의 경험을 통해 모임의 퀄리티를 미리 확인할 수 있습니다.

#### ⭐ 찜하기 기능
- 관심 있는 모임을 찜하기로 저장할 수 있습니다.
- 찜한 모임 페이지에서 저장한 모임들을 한눈에 확인할 수 있습니다.
- 찜한 모임의 일정과 상태를 쉽게 확인할 수 있습니다.

#### ⭐ 간편한 회원가입/로그인
- 이메일 기반의 간단한 회원가입 절차를 제공합니다.
- 소셜 로그인을 통한 빠른 가입도 지원합니다.

#### ⭐ FAQ 및 고객지원
- 자주 묻는 질문들을 카테고리별로 정리하여 제공합니다.
- 이메일이나 구글 폼을 통한 추가 문의가 가능합니다.
- 서비스 이용에 대한 상세한 가이드를 제공합니다.


## 프로젝트 구조
### [폴더 구조]
- apis/ : 외부 API 통신을 담당하는 함수들을 기능별로 분리
- components/ : 재사용 가능한 컴포넌트들을 기능별로 구분하여 관리
- constants/ : 프로젝트에서 사용되는 상수 값들을 중앙 관리
- hooks/ : 재사용 가능한 로직을 커스텀 훅으로 분리
- libs/ : 프로젝트 전반에서 사용되는 유틸리티 함수들을 관리
- pages/ : 실제 라우팅되는 페이지 컴포넌트들을 관리
- store/ : 전역적으로 관리되어야 하는 상태들을 관리
- types/ : TypeScript 타입 정의 파일들을 중앙 관리

```
📦src
┣ 📂apis
┣ 📂components
┃ ┣ 📂landing
┃ ┣ 📂loginSignup
┃ ┣ 📂main
┃ ┣ 📂mypage
┃ ┣ 📂review
┃ ┗ 📂shared
┣ 📂constants
┣ 📂hooks
┣ 📂libs
┣ 📂pages
┃ ┣ 📂create
┃ ┣ 📂detail
┃ ┣ 📂login
┃ ┣ 📂main
┃ ┣ 📂mypage
┃ ┣ 📂review
┃ ┗ 📂signup
┣ 📂store
┣ 📂types
┗ 📜App.tsx
```

## Deploy on Vercel
## 협업 일정관리
<img width="658" alt="스크린샷 2025-02-04 오후 1 20 35" src="https://github.com/user-attachments/assets/a32647dd-a3bc-4f17-b439-f6d9363b2e1c" />

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
## 협업 회의록
<img width="653" alt="스크린샷 2025-02-04 오후 1 21 19" src="https://github.com/user-attachments/assets/7d8e829d-9425-4d23-b376-0995c5d84494" />

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
23 changes: 0 additions & 23 deletions public/icons/NotificationIcon.tsx

This file was deleted.

3 changes: 3 additions & 0 deletions public/icons/notificationIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 13 additions & 10 deletions src/components/detail/FloatingBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useCallback } from 'react';
import { useRouter } from 'next/router';
import { Toast } from '@/components/shared/Toast';
import { userStore } from '@/store/userStore';
import type { DetailData } from '@/types/detail';

Expand All @@ -14,12 +16,21 @@ export interface DetailPageBaseType {

export function FloatingBar({ gatherings, id }: DetailPageBaseType) {
const router = useRouter();
const isLoggedIn = userStore((state) => state.isLoggedIn);

const myUserName = userStore((state) => state.user.name);
const findUserId = gatherings.usersList.find((user) => user.name === myUserName);
const isDisabled = gatherings.usersList.length === gatherings.maxUsers;
const isClosed = gatherings.closed;

const handleCreateButtonClick = useCallback(() => {
if (isLoggedIn) {
void router.push(`/detail/${id}/chat?roomId=${gatherings.roomId}`);
} else {
Toast('error', '로그인이 필요합니다.');
}
}, [gatherings.roomId, id, isLoggedIn, router]);

return (
<footer className="fixed inset-x-0 bottom-0 flex min-h-[84px] items-center justify-between border-t border-blue-100 bg-white px-10 py-5">
<div className="flex flex-col">
Expand All @@ -32,11 +43,7 @@ export function FloatingBar({ gatherings, id }: DetailPageBaseType) {
<div className="flex gap-2">
<CancelButton gatherings={gatherings} id={id} />
<ShareButton />
<button
type="button"
onClick={() => router.push(`/detail/${id}/chat?roomId=${gatherings.roomId}`)}
className="rounded-xl bg-blue-800 px-5 py-2 text-sm font-bold text-white"
>
<button type="button" onClick={handleCreateButtonClick} className="rounded-xl bg-blue-800 px-5 py-2 text-sm font-bold text-white">
실시간 문의하기
</button>
</div>
Expand All @@ -45,11 +52,7 @@ export function FloatingBar({ gatherings, id }: DetailPageBaseType) {
) : (
<div className="flex gap-2">
<AttendanceButton gatherings={gatherings} id={id} />
<button
type="button"
onClick={() => router.push(`/detail/${id}/chat?roomId=${gatherings.roomId}`)}
className="rounded-xl bg-blue-800 px-5 py-2 text-sm font-bold text-white"
>
<button type="button" onClick={handleCreateButtonClick} className="rounded-xl bg-blue-800 px-5 py-2 text-sm font-bold text-white">
실시간 문의하기
</button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/main/CardSection/CardItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function CardItem({ data }: { data: GetGatheringResponse['data'][
height={200}
priority
sizes="100vw"
className="h-auto w-full object-cover duration-300 group-hover:scale-110"
className="h-[170px] w-full object-cover duration-300 group-hover:scale-110"
/>
<div className="absolute left-0 top-0 h-10 w-full bg-gradient-to-b from-black/50 to-transparent">
<button type="button" className="absolute right-4 top-2" onClick={toggleHeart}>
Expand Down
8 changes: 6 additions & 2 deletions src/components/main/CardSection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ function CardSectionContent() {
return (
<>
<div className="px-5">
<ul className="grid grid-cols-2 gap-5 tablet:grid-cols-3 pc:grid-cols-4">{mainData?.map((data) => <CardItem key={data.gatheringId} data={data} />)}</ul>
<ul className="grid grid-cols-2 gap-5 tablet:grid-cols-3 pc:grid-cols-4">
{mainData
?.filter((data, index, self) => index === self.findIndex((t) => t.gatheringId === data.gatheringId))
.map((data) => <CardItem key={`${data.gatheringId}-${data.createdAt}`} data={data} />)}
</ul>
{mainData?.length === 0 && <NoData use="main" />}
</div>
{hasNextPage && <div ref={sentinelRef} className="h-10 w-full flex-shrink-0 opacity-0" />}
<div ref={sentinelRef} className="h-10 w-full flex-shrink-0 opacity-0" />
</>
);
}
Expand Down
Loading