Skip to content

Commit

Permalink
Merge pull request #172 from yourssu/develop
Browse files Browse the repository at this point in the history
배포
  • Loading branch information
nijuy authored Mar 26, 2024
2 parents f76c158 + c48942c commit abdba81
Show file tree
Hide file tree
Showing 124 changed files with 3,875 additions and 29 deletions.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/refactor-request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Refactor request
about: '리팩토링용 이슈 템플릿 '
title: "[REFACTOR] "
labels: ''
assignees: ''

---

## AS-IS
<!-- 현재 코드에 대한 설명, 문제점 등 -->

## TO-BE
<!-- 어떻게 개선할지에 대한 설명 -->

## TO-DO
<!-- 할 일 -->

## 기타
<!-- 🎻 -->
28 changes: 28 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: build-and-deploy

on:
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout source code.
uses: actions/checkout@v3

- name: install node modules
run: yarn install --immutable --immutable-cache --check-cache

- name: build application
run: yarn build

- name: Deploy to s3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 cp \
--recursive \
--region ap-northeast-2 \
dist s3://ppussung-dating.soomsil.de
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"printWidth": 100,
"semi": false,
"singleQuote": true,
"trailingComma": "es5"
"trailingComma": "es5",
"plugins": ["prettier-plugin-tailwindcss"]
}
92 changes: 74 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,83 @@
# React + TypeScript + Vite
<div align="center">
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/ea8ebc3f-4900-41b6-9e62-9b6b246402fe" />
<h1>뿌슝이의 동물 SSU개팅</h1>
</div>

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:
<h2> 👀 프로젝트 소개 </h2>
<p>뿌슝이의 동물 SSU개팅은 숭실대학교 중앙동아리 YOURSSU에서 제공하는 소개팅 서비스입니다.<br/>
9종의 동물 캐릭터와 자기소개를 통해 나만의 프로필을 등록하여 자신의 매력을 보여줄 수 있습니다.<br/>
다양한 필터로 원하는 조건의 프로필을 찾아보고, 마음에 드는 프로필이 있다면 이용권을 사용해 연락처를 열람할 수 있습니다.<p>
<p>개발 기간: (v1) 2023.09.09-2023.09.20 / (v2) 2023.12.11-2023.12.21</p>
<p>운영 기간: 2023.12.22-(운영 중)</p>

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
<h2> 😎 팀원 </h2>

## Expanding the ESLint configuration
| Jay | [Rozy (@seddong)](https://github.com/seddong) | Kino | Wendy | Hoi |
| :--------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------: |
| <img src="https://cdn.pixabay.com/photo/2017/11/10/05/48/user-2935527_1280.png" width="120" /> | <img src="https://avatars.githubusercontent.com/u/112679635?v=4" width="120" /> | <img src="https://cdn.pixabay.com/photo/2017/11/10/05/48/user-2935527_1280.png" width="120" /> | <img src="https://cdn.pixabay.com/photo/2017/11/10/05/48/user-2935527_1280.png" width="120" /> | <img src="https://cdn.pixabay.com/photo/2017/11/10/05/48/user-2935527_1280.png" width="120" /> |
| 기획 | Design | Design | Contents Marketing | Contents Marketing |

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
| [Jose (@TaeWoonJeong)](https://github.com/TaeWoonJeong) | [Snow (@GGHDMS)](https://github.com/GGHDMS) | [Bori (@nijuy)](https://github.com/nijuy) | [Stella (@intersoom)](https://github.com/intersoom) |
| :---------------------------------------------------------------------------: | :--------------------------------------------------------------------------: | :---------------------------------------------------------------------------: | :---------------------------------------------------------------------------: |
| <img src="https://avatars.githubusercontent.com/u/50254500?v=4" width="120"/> | <img src="https://avatars.githubusercontent.com/u/48712043?v=4" width="120"> | <img src="https://avatars.githubusercontent.com/u/87255462?v=4" width="120"/> | <img src="https://avatars.githubusercontent.com/u/78731710?v=4" width="120"/> |
| (v1) Back-end | (v2) Back-end | Front-end | Front-end |

- Configure the top-level `parserOptions` property like this:
<h2> 💘 기능 소개 </h2>
<h3>회원 가입</h3>
<p>가입하지 않은 사용자는 `내 이상형 찾기` 기능만 이용 가능합니다. 프로필 등록 및 연락처 조회는 회원 전용 기능입니다.<br/>
카카오톡 계정으로 서비스를 이용할 수 있으며, 로그인할 경우 이용약관과 개인정보 처리방침에 동의하는 것으로 간주됩니다.</p>
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/79e1348f-5045-43c8-a22d-9ae10fd25972"/>

```js
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},

<h3>프로필 등록하기</h3>
<p>로그인 이후 프로필을 등록해야 회원가입 절차가 완료됩니다. 프로필에는 성별, 자신을 나타내는 동물, 자기소개가 들어갑니다.<br/>
등록에 실패할 경우 토스트 메시지로 원인을 알 수 있으며, 등록에 성공하면 이용권 2장을 부여합니다.</p>
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/ed293985-16c6-43dc-8012-b81ab3af2b41"/>


<h3>내 이상형 찾기</h3>
<p>성별, 동물 필터를 선택하여 조건에 해당하는 프로필 목록을 볼 수 있습니다.<br/>
한 목록에는 최대 16개의 프로필이 랜덤한 순서로 나타납니다. 우측 하단의 새로고침 버튼으로 새로운 목록을 볼 수 있습니다.<br/>
프로필을 클릭하면 팝업 모달로 전체 내용을 볼 수 있으며, 연락처 열람 시마다 이용권 1장이 차감됩니다.</p>
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/a8193c30-b557-4e33-8b6e-b4dfb4a99e9d" />


<h3>추천인 등록하기</h3>
<p>추천인 등록을 통해 추가 이용권을 획득할 수 있습니다. 추천인을 입력한 사용자와 추천받은 사용자는 각각 1장의 이용권을 받습니다.<br/>
단, 추천인 등록은 계정당 1회만 가능하며 이후에는 `이용권 받기` 버튼이 비활성화됩니다.</p>
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/c9504c23-5ecb-4775-80f1-ab2eb721d81d" />


<h3>마이 페이지</h3>
<p>마이 페이지에서는 프로필 관리, 앱 정보 조회, 계정 관리를 할 수 있습니다.</p>
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/7bfaee6b-6c91-45a1-b471-beb5cdf5d59b" height="844"/>



<h3>내 프로필 수정하기</h3>
<p>프로필 중 닉네임, MBTI, 본인 매력 어필, 연락처 정보를 수정할 수 있습니다. 수정 사항이 있을 때만 `수정 완료` 버튼이 활성화됩니다. </p>
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/9b1ded75-0064-47eb-aafb-93ca6f5016cf" />



<h3>내가 가져온 프로필 보기</h3>
<p>`내 이상형 찾기` 페이지에서 이용권을 사용해 연락처를 조회한 프로필들을 한 곳에서 모아볼 수 있습니다.</p>
<img src="https://github.com/yourssu/autumn-ssu-dating/assets/87255462/7720b680-0fb4-4e7f-82bd-878bae9efeb0" />



<h2> ✨ 실행 </h2>

```
> git clone https://github.com/yourssu/autumn-ssu-dating.git
> cd autumn-ssu-dating
> npm install --global yarn
> yarn install
> yarn dev
```

- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
<h2> 관련 링크 </h2>
💻 뿌슝이의 동물 SSU개팅 서버 저장소: https://github.com/yourssu/SSUDate-Server <br/>
💙 인스타그램 홍보 자료: <a href="https://www.instagram.com/p/C1HAbXzycBU/" target="_blank">릴리즈 예고 영상</a>, <a href="https://www.instagram.com/p/C1JJTzISDVn/?img_index=1" target="_blank">사용 가이드</a>
34 changes: 30 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
<!doctype html>
<html lang="en">
<html lang="ko">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
<link rel="preconnect" href="https://ssudate-server.yourssu.com/" />
<!-- 사진 파일 -->
<link rel="preload" as="image" href="/src/assets/bg.webp" />
<link rel="preload" as="image" href="/src/assets/bg_palePink.webp" />
<link rel="preload" as="image" href="/dogIcon.webp" />
<link rel="preload" as="image" href="/bearIcon.webp" />
<link rel="preload" as="image" href="/foxIcon.webp" />
<link rel="preload" as="image" href="/wolfIcon.webp" />
<link rel="preload" as="image" href="/dinoIcon.webp" />
<link rel="preload" as="image" href="/pussungIcon.webp" />
<link rel="preload" as="image" href="/catIcon.webp" />
<link rel="preload" as="image" href="/rabbitIcon.webp" />
<link rel="preload" as="image" href="/hamsterIcon.webp" />
<!-- 폰트 파일 -->
<link rel="preload" as="font" href="/src/assets/font/PretendardVariable.woff2" crossorigin />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>슈개팅</title>
</head>
<body>

<body class="notranslate">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z3BTZ3PPKJ"></script>
<script>
window.dataLayer = window.dataLayer || []
function gtag() {
dataLayer.push(arguments)
}
gtag('js', new Date())
gtag('config', 'G-Z3BTZ3PPKJ')
</script>
</body>
</html>
14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@
},
"dependencies": {
"@tanstack/react-query": "^4.35.0",
"@types/lodash": "^4.14.202",
"axios": "^1.5.0",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"prettier-plugin-tailwindcss": "^0.5.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0"
"react-infinite-scroller": "^1.2.6",
"react-lottie": "^1.2.4",
"react-router-dom": "^6.15.0",
"recoil": "^0.7.7",
"recoil-persist": "^5.1.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/react-infinite-scroller": "^1.2.3",
"@types/react-lottie": "^1.2.10",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react": "^4.0.3",
Expand All @@ -32,7 +42,9 @@
"eslint-plugin-react-refresh": "^0.4.3",
"postcss": "^8.4.29",
"prettier": "^3.0.3",
"tailwind-scrollbar-hide": "^1.1.7",
"tailwindcss": "^3.3.3",
"tailwindcss-animated": "^1.0.1",
"typescript": "^5.0.2",
"vite": "^4.4.5"
}
Expand Down
6 changes: 6 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Binary file added public/404ppusung.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/bearIcon.webp
Binary file not shown.
Binary file added public/bubble.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/catIcon.webp
Binary file not shown.
Binary file added public/dinoIcon.webp
Binary file not shown.
Binary file added public/dogIcon.webp
Binary file not shown.
Binary file added public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/femaleIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/foxIcon.webp
Binary file not shown.
Binary file added public/hamsterIcon.webp
Binary file not shown.
Binary file added public/maleIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/pussungIcon.webp
Binary file not shown.
Binary file added public/rabbitIcon.webp
Binary file not shown.
Binary file added public/wolfIcon.webp
Binary file not shown.
Empty file removed src/App.css
Empty file.
35 changes: 33 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
import './App.css'
import { BrowserRouter } from 'react-router-dom'
import { Routes, Route } from 'react-router-dom'

import Contact from './components/Contact'
import Explore from './components/Explore'
import Home from './components/Home'
import Layout from './components/Layout'
import NotFound from './components/NotFound'
import Redirect from './components/Redirect'
import Register from './components/Register'
import UpdateProfile from './components/Update'
import UserPage from './components/User'
import AuthRoute from './components/common/AuthRoute'

const App = () => {
return <div> 뿌슝이의 동물 SSU개팅</div>
return (
<>
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route path="" element={<Home />} />
<Route path="/explore" element={<Explore />} />
<Route path="/register" element={<Register />} />
<Route element={<AuthRoute />}>
<Route path="/user" element={<UserPage />} />
<Route path="/user/edit" element={<UpdateProfile />} />
<Route path="/user/contact" element={<Contact />} />
</Route>
</Route>
<Route path="/kakao-redirect" element={<Redirect />} />
<Route path="/*" element={<NotFound />} />
</Routes>
</BrowserRouter>
</>
)
}

export default App
77 changes: 77 additions & 0 deletions src/apis/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import axios, { AxiosRequestConfig } from 'axios'
import { jwtDecode } from 'jwt-decode'

import { refresh } from './refresh'

import { getAccessToken, getRefreshToken, setToken } from '../utils/tokenUtils'

interface AxiosCustomRequestConfig extends AxiosRequestConfig {
retryCount: number
}

const MAX_RETRY_COUNT = 3
const client = axios.create({
baseURL: 'https://ssudate-server.yourssu.com/',
})

client.interceptors.request.use((config) => {
if (config.url === '/refresh') {
const refreshToken = getRefreshToken()
config.headers.Authorization = `Bearer ${refreshToken}`
} else {
const accessToken = getAccessToken()
config.headers.Authorization = `Bearer ${accessToken}`
}

return config
})

client.interceptors.response.use(
(response) => {
return response
},
async (error) => {
const originRequest = error.config as AxiosCustomRequestConfig
originRequest.retryCount = originRequest.retryCount ?? 0

const refreshToken = getRefreshToken()

if (error.response?.status === 401 && originRequest.url === '/refresh') {
return Promise.reject(error)
}

if (error.response?.status === 401 && originRequest.retryCount < MAX_RETRY_COUNT) {
try {
if (verifyRefreshToken(refreshToken)) {
const response = await refresh(refreshToken!)
const newAccessToken = response.accessToken
const newRefreshToken = response.refreshToken

setToken(newAccessToken, newRefreshToken)
originRequest.retryCount += 1

return client(originRequest)
} else {
localStorage.clear()
window.location.assign('/')
}
} catch {
localStorage.clear()
window.location.assign('/')
}
}
return Promise.reject(error)
}
)

const verifyRefreshToken = (token: string | null) => {
if (!token) return false

const currentTime = new Date().getTime()
const expireTime = jwtDecode(token).exp

if (expireTime && expireTime * 1000 < currentTime) return false
return true
}

export default client
13 changes: 13 additions & 0 deletions src/apis/getAnimals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import client from './client'

import { GenderType } from '../types/explore.type'
import { AnimalsResponse } from '../types/getAnimals.type'
import { AnimalServerType } from '../types/register.type'

export const getAnimals = async (
gender: GenderType,
animals: AnimalServerType
): Promise<AnimalsResponse> => {
const response = await client.get(`/search/${gender}/${animals}`)
return response.data
}
8 changes: 8 additions & 0 deletions src/apis/getContact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import client from './client'

import { ContactsResponse } from '../types/getContact.type'

export const getContact = async (): Promise<ContactsResponse> => {
const response = await client.get(`/search/contact`)
return response.data
}
8 changes: 8 additions & 0 deletions src/apis/getMyInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import client from './client'

import { UserInfoResponse } from '../types/user.type'

export const getMyInfo = async (): Promise<UserInfoResponse> => {
const response = await client.get(`/users/my`)
return response.data
}
Loading

0 comments on commit abdba81

Please sign in to comment.