Skip to content

Commit

Permalink
feat: 게임 목록 무한 스크롤 구현
Browse files Browse the repository at this point in the history
chore: convertObjectToQS 매개변수 타입 변경
  • Loading branch information
HiimKwak committed Nov 28, 2023
1 parent f950673 commit 700258a
Show file tree
Hide file tree
Showing 114 changed files with 8,088 additions and 0 deletions.
88 changes: 88 additions & 0 deletions output/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
## Getting Started

First, run the development server:

```bash
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

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

## Next.js 사용 팁

1. 페이지 컴포넌트 파일들은 src/app 하위에 생성하면 됨

- 라우팅은 폴더를 생성하면 사용 가능, 동적 라우팅의 경우 `/[파라미터]`로 생성할 것
- 이 밖에도 지정 파일들이 있으니(page.tsx, layout.tsx, error.tsx 등) 공식문서 참고할 것

2. components, utils, assets 등의 파일 폴더들은 src 아래 app 폴더와 동등한 레벨에 생성 및 사용할 것

3. 기본값으로 server component로 사용됨. useState등의 훅을 사용하려면 'use client'를 파일 최상단에 기입할 것

## 간단한 코드 컨벤션

### 커밋 컨벤션

| 태그 이름 | 설명 |
| ---------------- | -------------------------------------------------------------------------------------------------------- |
| Feat | 새로운 기능을 추가할 경우 |
| Fix | 버그를 고친 경우 |
| Design | CSS 등 사용자 UI 디자인 변경 |
| !BREAKING CHANGE | 커다란 API 변경의 경우 |
| !HOTFIX | 급하게 치명적인 버그를 고쳐야하는 경우 |
| Style | 코드 포맷 변경, 세미 콜론 누락, 오타 수정, 탭 사이즈 변경, 변수명 변경 등 코어 로직을 안건드는 변경 사항 |
| Refactor | 프로덕션 코드 리팩토링 |
| Comment | 필요한 주석 추가 및 변경 |
| Docs | 문서(Readme.md)를 수정한 경우 |
| Rename | 파일 혹은 폴더명을 수정하거나 옮기는 작업만인 경우 |
| Remove | 파일을 삭제하는 작업만 수행한 경우 |
| Test | 테스트 추가, 테스트 리팩토링(프로덕션 코드 변경 X) |
| Chore | 빌드 태스트 업데이트, 패키지 매니저를 설정하는 경우(프로덕션 코드 변경 X) |

### 네이밍 컨벤션

1. **\*.tsx** : PascalCase
2. **\*.ts** : camelCase
3. 페이지 폴더 (**pages/**/**\***.tsx\*\*) : index.tsx
4. 나머지 폴더 : **kebab-case**
5. constants : camelCase
6. git branch name : kebab-case

### 폴더 구조

```
├── 📁 node_modules
├── 📁 public
├── 📁 src
│ ├── 📁 assets
│ │ ├── 📁 contants
│ │ ├── 📁 fonts
│ │ └── 📁 images
│ ├── 📁 components
│ │ ├── 📁 layout
│ │ ├── 📁 ...
│ │ └── ...
│ ├── 📁 app
│ │ ├── 📁 home
│ │ ├── 📁 ...
│ │ ├── 📁 ...
│ │ ├── page.tsx
│ │ ├── layout.tsx
│ │ └── global.css
│ └── 📁 utils
│ ├── 📁 hooks
│ ├── 📁 recoil
│ └── 📁 types
├── .eslintrc.json
├── .gitgnore
├── next-env.d.ts
├── next.config.js
├── package.json
├── postcss.config.js
├── README.md
├── tailwind.config.ts
├── tsconfjg.json
└── yarn.lock
```
5 changes: 5 additions & 0 deletions output/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh
cd ../
mkdir output
cp -R ./client/* ./output
cp -R ./output ./client/
47 changes: 47 additions & 0 deletions output/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
domains: [
'hufstreaming.s3.ap-northeast-2.amazonaws.com',
'hufscheer-server.s3.ap-northeast-2.amazonaws.com',
],
},
};

module.exports = nextConfig;

// Injected content via Sentry wizard below

const { withSentryConfig } = require('@sentry/nextjs');

module.exports = withSentryConfig(
module.exports,
{
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options

// Suppresses source map uploading logs during build
silent: true,
org: 'hufs-td',
project: 'hufstreaming',
},
{
// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/

// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,

// Transpiles SDK to be compatible with IE11 (increases bundle size)
transpileClientSDK: true,

// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)
tunnelRoute: '/monitoring',

// Hides source maps from generated client bundles
hideSourceMaps: true,

// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
},
);
57 changes: 57 additions & 0 deletions output/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "hufs-sports-live-client",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prepare": "chmod ug+x .husky/* && husky install"
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": [
"eslint",
"prettier --config ./.prettierrc --write -u"
]
},
"dependencies": {
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-icons": "^1.3.0",
"@sentry/nextjs": "^7.73.0",
"@stomp/stompjs": "^7.0.0",
"@tanstack/react-query": "^5.8.2",
"@tanstack/react-query-devtools": "^5.8.2",
"axios": "^1.5.1",
"clsx": "^2.0.0",
"next": "13.5.4",
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.0.0"
},
"devDependencies": {
"@commitlint/cli": "^18.2.0",
"@commitlint/config-conventional": "^18.1.0",
"@tanstack/eslint-plugin-query": "^5.6.0",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"autoprefixer": "^10",
"eslint": "^8",
"eslint-config-next": "13.5.4",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"husky": "^8.0.3",
"lint-staged": "^15.1.0",
"postcss": "^8",
"prettier": "^3.0.3",
"prettier-plugin-tailwindcss": "^0.5.7",
"tailwindcss": "^3",
"typescript": "^5"
}
}
6 changes: 6 additions & 0 deletions output/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
9 changes: 9 additions & 0 deletions output/public/icon_hufstreaming.svg
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 output/public/images/not-found.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 output/public/logo_hufstreaming.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions output/sentry.client.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// This file configures the initialization of Sentry on the client.
// The config you add here will be used whenever a users loads a page in their browser.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

import * as Sentry from '@sentry/nextjs';

Sentry.init({
dsn: 'https://cc1dcf1845d69a9079c615d462e122b2@o4506026798088192.ingest.sentry.io/4506026816503808',

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 0.2,

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,

replaysOnErrorSampleRate: 1.0,

// This sets the sample rate to be 10%. You may want this to be 100% while
// in development and sample at a lower rate in production
replaysSessionSampleRate: 0.1,

// You can remove this option if you're not planning to use the Sentry Session Replay feature:
integrations: [
new Sentry.Replay({
// Additional Replay configuration goes in here, for example:
maskAllText: true,
blockAllMedia: true,
}),
],
});
16 changes: 16 additions & 0 deletions output/sentry.edge.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).
// The config you add here will be used whenever one of the edge features is loaded.
// Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

import * as Sentry from "@sentry/nextjs";

Sentry.init({
dsn: "https://cc1dcf1845d69a9079c615d462e122b2@o4506026798088192.ingest.sentry.io/4506026816503808",

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1,

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,
});
15 changes: 15 additions & 0 deletions output/sentry.server.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This file configures the initialization of Sentry on the server.
// The config you add here will be used whenever the server handles a request.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

import * as Sentry from '@sentry/nextjs';

Sentry.init({
dsn: 'https://cc1dcf1845d69a9079c615d462e122b2@o4506026798088192.ingest.sentry.io/4506026816503808',

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 0.2,

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,
});
42 changes: 42 additions & 0 deletions output/src/api/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as Sentry from '@sentry/nextjs';
import { AxiosError } from 'axios';

import { GameScorePayload, NewGamePayload } from '@/types/admin';

import { adminInstance } from '.';

export const createNewGame = (body: NewGamePayload) => {
try {
return adminInstance.post('/manage/game/register/', body);
} catch (error) {
const axiosError = error as AxiosError;

Sentry.captureException(axiosError);

if (axiosError.response) {
throw new Error(axiosError.response.statusText);
} else {
throw new Error('경기를 생성하는 데에 실패했습니다!');
}
}
};

export const postGameScore = (id: number, body: GameScorePayload) => {
try {
return adminInstance.post(`/manage/game/score/${id}/`, body);
} catch (error) {
const axiosError = error as AxiosError;

Sentry.captureException(axiosError);

if (axiosError.response) {
throw new Error(axiosError.response.statusText);
} else {
throw new Error('경기 점수를 변경하는 데에 실패했습니다!');
}
}
};

export const postBlockComment = (id: number) => {
return adminInstance.post(`/manage/comments/block/${id}/`);
};
31 changes: 31 additions & 0 deletions output/src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as Sentry from '@sentry/nextjs';
import { AxiosError } from 'axios';

import { AuthPayload, AuthType } from '@/types/auth';

import { adminInstance } from '.';

export const postLogin = async (body: AuthPayload) => {
try {
const response = await adminInstance.post<AuthType>(
'/accounts/login/',
body,
);

return response.data;
} catch (error) {
const axiosError = error as AxiosError;

Sentry.captureException(axiosError);

if (axiosError.response) {
throw new Error(axiosError.response.statusText);
} else {
throw new Error('팀 목록을 불러오는 데에 실패했습니다!');
}
}
};

export const postGameStatus = async (id: number, gameStatus: string) => {
adminInstance.post(`/manage/game/statustype/${id}/`, { gameStatus });
};
24 changes: 24 additions & 0 deletions output/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import axios from 'axios';

const instance = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});

export const adminInstance = axios.create({
baseURL: process.env.NEXT_PUBLIC_BACK_OFFICE_BASE_URL,
headers: {
Authorization: `Bearer `,
'Content-Type': 'application/json',
},
});

adminInstance.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;

return config;
});

export default instance;
Loading

0 comments on commit 700258a

Please sign in to comment.