Skip to content

Commit

Permalink
Merge pull request #114 from prgrms-web-devcourse-final-project/dev
Browse files Browse the repository at this point in the history
DEV MERGE
  • Loading branch information
he2e2 authored Dec 9, 2024
2 parents 0f4318d + 8950d8e commit 88f93e8
Show file tree
Hide file tree
Showing 62 changed files with 971 additions and 186 deletions.
138 changes: 137 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,137 @@
# React + TypeScript + Vite Boilerplate Code
<div align=center>
<img width="336" alt="image" src="https://github.com/user-attachments/assets/7c7f55c9-f4e5-4a9e-ad98-ee54e46303a9">
</div>

<h1 align=center style="text-align: center; font-size: 1.5em">Palette: 팔레트</h3>

<div align=center>

<p>자신만의 경험을 색상과 함께 공유하고,<br>네트워킹을 통해 팔레트를 채워주세요!</p>

https://www.palette.site/

<br>

<p align=center>
<a href="https://lime-mall-d34.notion.site/Road-to-friendly-2d8db233c6da4aaf8c3696a80ec83555?pvs=4">팀 노션</a>
&nbsp; | &nbsp;
<a href="https://www.figma.com/design/9Xf8cDM0jPx0oGNloEkfKa/Palettee?node-id=0-1&node-type=canvas&t=Sk30i83BB7LXRt0w-0">피그마</a>
&nbsp; | &nbsp;
<a href="https://github.com/prgrms-web-devcourse-final-project/WEB1_1_ZeroOne_FE/wiki">위키</a>
</p>
</div>
<br>

<br>

<!-- TOC end -->

<br>

<!-- TOC --><a name="-"></a>

## ✨ 프로젝트 소개

현대 직장인들은 일주일에 평균 25분 이상을 **자기계발**에 투자하고 있으며, 본업 외에도 사이드 프로젝트를 통해 경력을 확장하려는 경향이 증가하고 있습니다. 그러나 자기계발을 하지 않는 사람들은 **'갓생'** 열풍으로 인해 부담을 느끼고 있습니다. 이러한 상황에서 자기계발을 시작하는 사람들은 혼자 독학하기보다는 다른 사람들과 **함께** 성장하기를 원합니다.<br><br>
**팔레트**는 유저가 포트폴리오를 외부 링크로 연결해 유저의 작업물을 공유할 수 있도록 하며, 협업과 네트워킹에도 최적화된 플랫폼입니다. 아카이브 기능을 통해 다른 사용자들의 이야기를 탐색하고, 게더링 기능을 통해 팀원을 모집하거나 프로젝트에 참여할 수 있습니다. 이러한 기능을 통해 팔레트는 자기계발을 시작하는 사람들이 혼자가 아닌 타인과 함께 성장할 수 있는 환경을 제공하고자 합니다. <br><br>
**팔레트**에서 자신의 경험을 공유하고, 팔레트의 색상을 채워주세요!

<br>

<!-- TOC --><a name="--1"></a>
## 🚀 주요 기능

<!-- TOC --><a name="--2"></a>

### 🙋‍♀️ 나만의 포트폴리오 링크를 공유해주세요

> 나만의 포트폴리오 링크가 있다면, 등록해 다른 유저들과 공유하고 의견을 나눌 수 있어요.
<!-- TOC --><a name="--3"></a>

### 🎨 고유한 색상과 함께 경험을 아카이빙 해보세요

> 색상을 통해 고유한 성격이 존재하는 경험들을 아카이빙할 수 있어요. 경험을 나눠 팔레트를 채워주세요.<br>
> 마크다운 에디터를 통해 자유롭게 나만의 경험을 작성할 수 있습니다!
<!-- TOC --><a name="--4"></a>

### 🗣️ 게더링에서 자기계발 팀원들을 모집해보세요

> 혼자 시작하기 어렵다면, 같이 시작할 팀원들을 구해보세요! 다양한 팀원들이 기다리고 있어요 😊
<br>

<!-- TOC --><a name="--8"></a>

## ⚙️ 기술 스택

<table align=center>
<thead>
<tr>
<th>분류</th>
<th>기술 스택</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p align=center>Frontend</p>
</td>
<td>
<img src="https://img.shields.io/badge/Vite-646CFF?logo=Vite&logoColor=ffffff">
<img src="https://img.shields.io/badge/React-61DAFB?logo=React&logoColor=ffffff">
<img src="https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=ffffff">
<img src="https://img.shields.io/badge/Sass-D36AC2?logo=sass&logoColor=ffffff">
<img src="https://img.shields.io/badge/Zustand-443E38?logo=react&logoColor=ffffff">
<img src="https://img.shields.io/badge/React%20Query-FF4154?logo=reactquery&logoColor=ffffff">
</td>
</tr>
<tr>
<td>
<p align=center>Deployment</p>
</td>
<td>
<img src="https://img.shields.io/badge/S3-569A31?logo=amazons3&logoColor=ffffff">
<img src="https://img.shields.io/badge/CloudFront-232F3E?logo=amazonaws&logoColor=ffffff">
<img src="https://img.shields.io/badge/Route%2053-4A154B?logo=amazonaws&logoColor=ffffff">
<img src="https://img.shields.io/badge/Netlify-00C7B7?logo=netlify&logoColor=ffffff">
</td>
</tr>
<tr>
<td>
<p align=center>Collaboration</p>
</td>
<td>
<img src="https://img.shields.io/badge/Notion-000000?logo=Notion">
<img src="https://img.shields.io/badge/Figma-F24E1E?logo=Figma&logoColor=ffffff">
<img src="https://img.shields.io/badge/Slack-4A154B?logo=Slack&logoColor=ffffff">
<img src="https://img.shields.io/badge/Discord-4358D8?logo=Discord&logoColor=ffffff">
</td>
</tr>
</tbody>
</table>

<br>

<!-- TOC --><a name="--9"></a>

## 🎨 팀 소개

<table align="center">
<tr align="center">
<th><a href="https://github.com/joarthvr">조천산</a></th>
<th><a href="https://github.com/he2e2">조희정</a></th>
<th><a href="https://github.com/csk6314">채승규</a></th>
</tr>
<tr>
<td><img src="https://github.com/joarthvr.png" width="120" height="120"></td>
<td><img src="https://github.com/he2e2.png" width="120" height="120"></td>
<td><img src="https://github.com/csk6314.png" width="120" height="120"></td>
</tr>
<tr align="center">
<td>Frontend</td>
<td>Frontend</td>
<td>Frontend</td>
</tr>
</table>
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no"
/>
<title>Palettee</title>
<title>Palette</title>
</head>
<body>
<div id="root"></div>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "palettee",
"name": "palette",
"private": true,
"version": "1.0.1",
"type": "module",
Expand Down
4 changes: 0 additions & 4 deletions src/app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import { createRoot } from 'react-dom/client';
import App from './App';
import './styles/globals.scss';

// if (process.env.NODE_ENV === 'development') {
// void worker.start({ onUnhandledRequest: 'warn' });
// }

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
Expand Down
7 changes: 7 additions & 0 deletions src/features/archive/colors.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface ColorInfo {
description: string;
tag: string;
hex: string;
guide: string;
}

export interface ColorGroup {
Expand All @@ -31,40 +32,46 @@ export const ColorMap: { [key in Color]: ColorInfo } = {
description: '추진력이 돋보이는 기록',
tag: '#주도적인 리더십 #적극적인 행동력',
hex: '#ff5e5e',
guide: '새로운 도전이나 행동력을 보여줄 수 있는 경험을 소개해주세요!',
},
YELLOW: {
label: 'yellow',
name: '노랑',
description: '창의력이 돋보이는 기록',
tag: '#창의적인 아이디어 #자유로운 발상',
hex: '#ffe66b',
guide: '새로운 아이디어나 톡톡 튀는 아이디어를 뽐내주세요!',
},
BLUE: {
label: 'blue',
name: '파랑',
description: '분석력이 돋보이는 기록',
tag: '#논리적 사고 #깊이 있는 연구',
hex: '#8ad0e2',
guide: '논리적인 근거와 통찰력 있는 내용을 모두에게 소개시켜 주세요!',
},
GREEN: {
label: 'green',
name: '초록',
description: '헌신했던 경험이 돋보이는 기록',
tag: '#타인을 위한 봉사 #공동체 기여',
hex: '#b5d681',
guide: '타인을 위한 실용적인 정보나 조언을 제공했던 경험을 적어보는 건 어떨까요?',
},
PURPLE: {
label: 'purple',
name: '보라',
description: '성찰력이 돋보이는 기록',
tag: '#내적 동기 탐구 #가치관 형성',
hex: '#aa8abd',
guide: '내적 성장이나 삶의 의미를 탐구해 보아요!',
},
DEFAULT: {
label: 'default',
name: '기본',
description: '기본 색상',
tag: '#기본 색상',
hex: '#333533',
guide: '',
},
};
52 changes: 52 additions & 0 deletions src/features/gathering/api/gathering.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {

import api from '@/shared/api/baseApi';

// 기본 게더링 API
export const gatheringApi = {
getGatherings: async (params: GatheringListParams): Promise<GatheringPageResponse> => {
// params를 URLSearchParams로 변환
Expand Down Expand Up @@ -41,6 +42,7 @@ export const gatheringApi = {
});
return data;
},

update: async (
gatheringId: string,
data: CreateGatheringRequest,
Expand All @@ -53,10 +55,60 @@ export const gatheringApi = {
const { data } = await api.post<GatheringLikeResponse>(`/gathering/${gatheringId}/like`);
return data;
},

deleteGathering: async (gatheringId: string): Promise<void> => {
await api.delete(`/gathering/${gatheringId}`);
},

completeGathering: async (gatheringId: string): Promise<void> => {
await api.patch(`/gathering/${gatheringId}`);
},

// 좋아요한 게더링 목록 조회 추가
getGatheringLikeList: async (params: {
size: number;
gatheringId?: number;
}): Promise<GatheringPageResponse> => {
const queryString = new URLSearchParams();

Object.entries(params).forEach(([key, value]) => {
if (value !== undefined) {
queryString.append(key, value.toString());
}
});

const { data } = await api.get<GatheringPageResponse>(
`/gathering/my-page?${queryString.toString()}`,
);
return data;
},
};

// 메인 페이지용 게더링 API
export const mainGatheringApi = {
// 메인 페이지용 게더링 목록 조회 (최신 4개)
getMainGatherings: async (): Promise<GatheringPageResponse> => {
const params: GatheringListParams = {
page: 1,
size: 4,
status: '모집중', // 활성화된 게더링만 표시
};

// params를 URLSearchParams로 변환
const queryString = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== 'undefined') {
queryString.append(key, value.toString());
}
});

const { data } = await api.get<GatheringPageResponse>(`/gathering?${queryString.toString()}`);
return data;
},
};

// 두 API 객체를 모두 export
export default {
...gatheringApi,
...mainGatheringApi,
};
5 changes: 3 additions & 2 deletions src/features/gathering/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export * from './lib/hooks';
export * from './model/index';
export * from './model/options';
export * from './model/types';
export * from './ui/GatheringCard';
export { GatheringDatePicker } from './ui/GatheringDatePicker';
export * from './ui/GatheringDetail/index';
export { GatheringLinkInput } from './ui/GatheringLinkInput';
export { GatheringMarkdownEditor } from './ui/GatheringMarkdownEditor';
export { GatheringSelect } from './ui/GatheringSelect';
export { GatheringTagInput } from './ui/GatheringTagInput';
export { GatheringTitleInput } from './ui/GatheringTitIeInput';
export * from './lib/hooks';
export * from './model/index';
3 changes: 3 additions & 0 deletions src/features/gathering/lib/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ export * from './useCreateGathering';
export * from './useDeleteGathering';
export * from './useGatheringDetail';
export * from './useGatheringLike';
export * from './useGatheringLikeList';
export * from './useInfiniteGatheringId';
export * from './useMainGathering';
export * from './useUpdateGathering';

23 changes: 18 additions & 5 deletions src/features/gathering/lib/hooks/useCreateGathering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useNavigate } from 'react-router-dom';
import { gatheringApi } from '../../api/gathering.api';
import type { CreateGatheringRequest, CreateGatheringResponse } from '../../model/dto/request.dto';

import { errorAlert } from '@/shared/ui';
export const useCreateGathering = () => {
const queryClient = useQueryClient();
const navigate = useNavigate();
Expand All @@ -27,18 +28,30 @@ export const useCreateGathering = () => {
alert('게더링은 생성되었으나 추가 처리 중 오류가 발생했습니다.');
}
},
onError: (error: AxiosError) => {
onError: async (error: AxiosError) => {
if (error.response?.status === 401) {
alert('로그인이 필요합니다.');
await errorAlert({
title: '로그인 필요',
text: '로그인이 필요한 서비스입니다. 로그인 페이지로 이동합니다.',
});
navigate('/login');
} else if (error.response?.status === 403) {
alert('권한이 부족합니다. 다시 로그인해주세요.');
await errorAlert({
title: '권한 없음',
text: '권한이 없습니다. 로그인 후 다시 시도해주세요.',
});
navigate('/login');
} else if (error.response?.status === 400) {
alert('입력하신 정보를 다시 확인해주세요.');
await errorAlert({
title: '입력값 오류',
text: '입력값을 확인해주세요',
});
} else {
console.error('게더링 생성 실패:', error);
alert('게더링 생성에 실패했습니다. 잠시 후 다시 시도해주세요.');
await errorAlert({
title: '게더링 생성 실패',
text: '게더링 생성에 실패했습니다.',
});
}
},
});
Expand Down
Loading

0 comments on commit 88f93e8

Please sign in to comment.