diff --git a/packages/client/src/assets/RU.svg b/packages/client/src/assets/RU.svg
new file mode 100644
index 0000000..efd6300
--- /dev/null
+++ b/packages/client/src/assets/RU.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/client/src/assets/ya-btn.png b/packages/client/src/assets/ya-btn.png
new file mode 100644
index 0000000..b23370d
Binary files /dev/null and b/packages/client/src/assets/ya-btn.png differ
diff --git a/packages/client/src/components/YandexIcon/YandexIcon.tsx b/packages/client/src/components/YandexIcon/YandexIcon.tsx
new file mode 100644
index 0000000..dc33183
--- /dev/null
+++ b/packages/client/src/components/YandexIcon/YandexIcon.tsx
@@ -0,0 +1,5 @@
+import icon from '@assets/RU.svg'
+export const YandexIcon = () => {
+ return
+
+}
\ No newline at end of file
diff --git a/packages/client/src/entry-client.tsx b/packages/client/src/entry-client.tsx
index 0e7b0b5..574f034 100644
--- a/packages/client/src/entry-client.tsx
+++ b/packages/client/src/entry-client.tsx
@@ -14,21 +14,21 @@ declare global {
}
}
-// window.addEventListener('load', () => {
-// if ('serviceWorker' in navigator) {
-// navigator.serviceWorker
-// .register('/sw.js')
-// .then(registration => {
-// console.log(
-// 'ServiceWorker registration successful with scope: ',
-// registration.scope
-// )
-// })
-// .catch((error: string) => {
-// console.log('ServiceWorker registration failed: ', error)
-// })
-// }
-// })
+window.addEventListener('load', () => {
+ if ('serviceWorker' in navigator) {
+ navigator.serviceWorker
+ .register('/sw.js')
+ .then(registration => {
+ console.log(
+ 'ServiceWorker registration successful with scope: ',
+ registration.scope
+ )
+ })
+ .catch((error: string) => {
+ console.log('ServiceWorker registration failed: ', error)
+ })
+ }
+})
ReactDOM.hydrateRoot(
document.getElementById('root') as HTMLElement,
diff --git a/packages/client/src/hooks/useAuth.ts b/packages/client/src/hooks/useAuth.ts
index 8d0ab63..0289463 100644
--- a/packages/client/src/hooks/useAuth.ts
+++ b/packages/client/src/hooks/useAuth.ts
@@ -11,9 +11,9 @@ export const useAuth = () => {
user.id
? navigate('/game/start')
: dispatch(fetchUser()).then(res => {
- if (res.type === 'auth/fetch/rejected') {
- return navigate('/auth')
- }
- })
+ if (res.type === 'auth/fetch/rejected') {
+ return navigate('/auth')
+ }
+ })
}
}
diff --git a/packages/client/src/hooks/useOAuth.ts b/packages/client/src/hooks/useOAuth.ts
new file mode 100644
index 0000000..4ee93e4
--- /dev/null
+++ b/packages/client/src/hooks/useOAuth.ts
@@ -0,0 +1,23 @@
+import { oauthYandex, fetchUser } from '@store/actions/AuthActionCreators'
+import { useAppDispatch } from '@store/index'
+import { OauthData } from '@store/types'
+
+export const useOAuth = () => {
+ const REDIRECT_URI = 'http://localhost:3000'
+ const dispatch = useAppDispatch()
+ const url = document.location.href
+ const code = url.split('=').pop();
+ return () => {
+ if (/code/.test(url)) {
+ dispatch(oauthYandex({
+ code: code,
+ redirect_uri: REDIRECT_URI
+ } as OauthData))
+ .then(res => {
+ if (res.payload === 'OK') {
+ dispatch(fetchUser())
+ }
+ })
+ }
+ }
+}
diff --git a/packages/client/src/hooks/useRegister.ts b/packages/client/src/hooks/useRegister.ts
index f112654..87ace58 100644
--- a/packages/client/src/hooks/useRegister.ts
+++ b/packages/client/src/hooks/useRegister.ts
@@ -1,4 +1,4 @@
-import { register } from '../store/actions/AuthActionCreators'
+import { register } from '../store/actions/AuthActionCreators'
import { useAppDispatch } from '../store/index'
import { UserData } from '../store/types'
import { useNavigate } from 'react-router-dom'
diff --git a/packages/client/src/hooks/useServiceId.tsx b/packages/client/src/hooks/useServiceId.tsx
new file mode 100644
index 0000000..c6fdb00
--- /dev/null
+++ b/packages/client/src/hooks/useServiceId.tsx
@@ -0,0 +1,17 @@
+import { getServiceId } from "@store/actions/AuthActionCreators"
+import { useAppDispatch } from "@store/index"
+
+export const useServiceId = () => {
+ const dispatch = useAppDispatch()
+ const REDIRECT_URI = 'http://localhost:3000';
+ // const REDIRECT_URI =`http://localhost:${__CLIENT_PORT__}`
+
+ return () => {
+ dispatch(getServiceId())
+ .then(res => {
+ if (res.payload.service_id) {
+ document.location = `https://oauth.yandex.ru/authorize?response_type=code&client_id=${res.payload.service_id}&redirect_uri=${REDIRECT_URI}`
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/packages/client/src/pages/LoginPage/Login.tsx b/packages/client/src/pages/LoginPage/Login.tsx
index 2bad7ca..3d912a2 100644
--- a/packages/client/src/pages/LoginPage/Login.tsx
+++ b/packages/client/src/pages/LoginPage/Login.tsx
@@ -13,19 +13,35 @@ import { useLogin } from '../../hooks/useLogin'
import { useUser } from '../../hooks/useUser'
import { fetchUser } from '../../store/actions/UserActionCreators'
import { useAppDispatch } from '../../store/index'
+import { styled } from '@mui/material/styles'
+import { useServiceId } from '../../hooks/useServiceId'
export default function Login() {
const user = useUser()
const dispatch = useAppDispatch()
const navigate = useNavigate()
const login = useLogin()
+ const location = useServiceId()
+
+ const YandexIdButton = styled(Button)({
+ color: ' white',
+ width: '100%',
+ height: '44px',
+ backgroundColor: 'black',
+ textTransform: 'none',
+ '&:hover': {
+ backgroundColor: 'black',
+ borderColor: '#0062cc',
+ boxShadow: 'none',
+ },
+ })
useEffect(() => {
- dispatch(fetchUser())
if (user.id) {
navigate('/game/start')
}
- }, [navigate, user])
+ dispatch(fetchUser())
+ }, [user.id])
const handleLogin = (event: React.FormEvent) => {
event.preventDefault()
@@ -36,6 +52,7 @@ export default function Login() {
} as LoginData
login(authData)
}
+
return (
@@ -83,6 +100,13 @@ export default function Login() {
{' '}
Войти
+
+ или
+
+ location()}
+ // startIcon={}
+ >Войти c Яндекс ID
Еще не зарегистрированы?
{
+ const dispatch = useAppDispatch()
+ const user = useAppSelector(selectUserData)
+ const ratingData = selectRatingData()
+
const [sunkenShipsPlayer, setSunkenShipsPlayer] = useState([]) //затонувшие корабли player
const [sunkenShipsComp, setSunkenShipsComp] = useState([]) //затонувшие корабли comp
@@ -54,6 +77,56 @@ const Board = ({
const [countPlayerShips, setCountPlayerShips] = useState(allPlayerShips) //Количество кораблей для уничтожения
const [countCompShips, setCountCompShips] = useState(allCompShips) //Количество кораблей для уничтожения
+ const [playerIsWin, setPlayerIsWin] = useState(false)
+
+ useEffect(() => {
+ dispatch(fetchLeaderboard())
+ }, [])
+
+ useEffect(() => {
+ startTime = Date.now(); //время на старте игры
+ }, []);
+
+
+ useEffect(() => {
+ //для изме-я шага по времени для игрока
+ if (timeHandlePlayer === undefined || timeDraw === undefined) return;
+ if (name === "computer") return;
+
+ pausePlayer = getStepTimeGame(Date.now() - startTime);
+ pauseWorkFunPlayer = getStepTimeWorkFun(timeHandlePlayer, timeDraw);
+
+ startTime = startTimeGame; //для нового отсчета с функции клика компа в конце
+ }, [timeHandlePlayer, name, timeDraw]);
+
+ useEffect(() => {
+ //для изме-я шага по времени для компа
+ if (timeHandleComp === undefined || timeDraw === undefined) return;
+ if (name === "player") return;
+
+ pauseComp = getStepTimeGame(timeClickComp);
+ pauseWorkFunСomp = getStepTimeWorkFun(timeHandleComp, timeDraw);
+ }, [timeHandleComp, name, timeDraw]);
+
+ useEffect(() => {
+ if (playerIsWin && user) {
+ const currentUser = ratingData.find(({ data: { id } }) => id === user.id)
+ const score = (currentUser && currentUser.data.score + 1) ?? 1
+
+ const { avatar, id, display_name } = user
+ dispatch(
+ sendDataToLeaderboard({
+ avatar,
+ id,
+ name: display_name ?? 'anonymous',
+ score,
+ })
+ )
+
+ setPlayerIsWin(false)
+ }
+ }, [playerIsWin, user, ratingData])
+
const canvasRef: RefObject =
useRef(null)
@@ -70,6 +143,8 @@ const Board = ({
if (countCompShips === 0 || countPlayerShips === 0) return
if (currentPlayer === name) return //если текущий ход равен глобальному currentPlayer(тек. ход), то ничего не делаем
+ const firstNow = performance.now();
+
if (currentPlayer === 'computer') {
const cell = generateRandomCompShot() as CellArgs //рандомная ячейка компа
@@ -92,6 +167,12 @@ const Board = ({
currentPlayer = 'player' //т к ход мимо переход стрельбы
}
}
+
+ const secondNow = performance.now();
+ timeHandleComp = secondNow - firstNow; //время работы функции клика компа
+
+ startTimeGame = Date.now(); //начало нового отсчета
+
}, [
countPlayerShips,
countCompShips,
@@ -106,13 +187,30 @@ const Board = ({
const drawGrid = (context: CanvasRenderingContext2D) => {
//отрисовка сетки, краблей, клеток попадания, клеток мимо
+
+ const firstNow = performance.now();
+
context.clearRect(0, 0, size, size)
drawCells({ context, cellSize, dimMatr })
- drawNameBoard(context, nameBoard) //отрисовка названия доски
+ drawNameBoard(
+ context,
+ nameBoard,
+ name,
+ pausePlayer,
+ pauseComp,
+ pauseWorkFunPlayer,
+ pauseWorkFunСomp
+ ); //отрисовка названия доски с добавлением временных шагов
drawLatterCoords(context, coords.letterCoords) //отрисовка координат букв доски
drawNumberCoords(context, coords.numberCoords) //отрисовка координат чисел доски
- drawWhoWin(context, name, countCompShips, countPlayerShips) //who win
+ drawWhoWin(
+ context,
+ name,
+ setPlayerIsWin,
+ countCompShips,
+ countPlayerShips
+ ) //who win
drawStatusShips(context, name, countCompShips, countPlayerShips) // кол-о к уничтож клеток
drawShips(context, cellSize, playerShips!) //отрисовка караблей
@@ -123,6 +221,9 @@ const Board = ({
drawPastCells(context, cellSize, pastCellsPlayer) //отрис клетки мимо игрока
drawPastCells(context, cellSize, pastCellsComp) //отрис клетки мимо компа
+
+ const secondNow = performance.now();
+ timeDraw = secondNow - firstNow; //время работы функции draw
}
if (canvasRef.current) localRef = canvasRef.current
@@ -171,6 +272,8 @@ const Board = ({
if (countCompShips === 0 || countPlayerShips === 0) return
if (currentPlayer === name) return //если текущий ход равен глобальному currentPlayer(тек. ход), то ничего не делаем
+ const firstNow = performance.now();
+
if (currentPlayer === 'player') {
const { offsetX, offsetY } = event.nativeEvent //определяется ячейка по которой кликнул игрок
@@ -190,6 +293,9 @@ const Board = ({
currentPlayer = 'computer' // т к ход мимо переход стрельбы к компу
}
}
+
+ const secondNow = performance.now();
+ timeHandlePlayer = secondNow - firstNow; //время работы функции клика игрока
}
useEffect(
diff --git a/packages/client/src/pages/game/GamePlay/helper.ts b/packages/client/src/pages/game/GamePlay/helper.ts
index 87250e8..d38ff85 100644
--- a/packages/client/src/pages/game/GamePlay/helper.ts
+++ b/packages/client/src/pages/game/GamePlay/helper.ts
@@ -1,3 +1,4 @@
+import React from 'react'
import {
ShipsSet,
CellArgs,
@@ -6,6 +7,7 @@ import {
GeneratedCoords,
CellIsEngagedArgs,
CellIsWithinArgs,
+ Winner,
} from './types'
export enum DirectionsOfGeneration {
@@ -22,6 +24,19 @@ export const scaleBoard = 1 //масшатаб игрового поля
export const canvasWidth = size + 70 //ширина всего канваса
export const canvasHeight = size + 100 //высота всего канваса
+//время неспешного решения о возможном клике
+export const getStepTimeGame = (x: number): string => {
+ const y = (x / 1000).toFixed(2);
+ return y;
+};
+
+//время отработки функций
+export const getStepTimeWorkFun = (tHandle: number, tDraw: number): string => {
+ const y = ((tHandle + tDraw) / 1000).toFixed(4);
+
+ return y;
+};
+
export const shipsSet: ShipsSet[] = [
//размеры кораблей и их количество на доске
// последовательность строго c size =3 и на уменьшение!!!!
@@ -47,7 +62,12 @@ const drawCell = ({ context, cellSize, x, y }: DrawCellArgs): void => {
//рисовать имя доски
export const drawNameBoard = (
context: CanvasRenderingContext2D,
- font: string
+ font: string,
+ name: string,
+ pausePlayer?: string,
+ pauseComp?: string,
+ pauseWorkFunPlayer?: string,
+ pauseWorkFunСomp?: string
): void => {
context.beginPath()
context.clearRect(0, 340, 300, 60)
@@ -125,23 +145,27 @@ export const drawStatusShips = (
export const drawWhoWin = (
context: CanvasRenderingContext2D,
name: string,
+ setPlayerIsWin: React.Dispatch>,
countCompShips?: number,
countPlayerShips?: number
): void => {
const str =
name === 'computer'
- ? countCompShips === 0 && 'Вы победитель!!!'
- : countPlayerShips === 0 && 'Компутер красавчик!!!'
+ ? countCompShips === 0 && Winner.PLAYER_IS_WIN
+ : countPlayerShips === 0 && Winner.COMP_IS_WIN
+
+ if (str === Winner.PLAYER_IS_WIN) setPlayerIsWin(true)
+
if (!str) return
- context.beginPath()
- context.clearRect(0, 340, 300, 60)
- context.rect(0, 340, 300, 60)
- context.fillStyle = 'burlywood'
- context.fill()
- context.fillStyle = 'rgb(158, 0, 0)'
- context.font = 'italic ' + 20 + 'pt Arial'
- context.fillText(`${str}`, 10, 370)
- context.closePath()
+ context.beginPath();
+ context.clearRect(0, 340, 330, 60);
+ context.rect(0, 340, 330, 60);
+ context.fillStyle = "burlywood";
+ context.fill();
+ context.fillStyle = "rgb(158, 0, 0)";
+ context.font = "italic " + 20 + "pt Arial";
+ context.fillText(`${str}`, 10, 370);
+ context.closePath();
}
// рисовать ячейки
diff --git a/packages/client/src/pages/game/GamePlay/types.ts b/packages/client/src/pages/game/GamePlay/types.ts
index 45ae84e..9cccbba 100644
--- a/packages/client/src/pages/game/GamePlay/types.ts
+++ b/packages/client/src/pages/game/GamePlay/types.ts
@@ -49,3 +49,8 @@ export type CellIsWithinArgs = {
cell: CellArgs
dimMatr: number
}
+
+export enum Winner {
+ PLAYER_IS_WIN = 'Вы победитель!!!',
+ COMP_IS_WIN = 'Компутер красавчик!!!',
+}
diff --git a/packages/client/src/pages/game/GameStart/MenuList/MenuList.tsx b/packages/client/src/pages/game/GameStart/MenuList/MenuList.tsx
index c08ade8..e1ce16f 100644
--- a/packages/client/src/pages/game/GameStart/MenuList/MenuList.tsx
+++ b/packages/client/src/pages/game/GameStart/MenuList/MenuList.tsx
@@ -1,9 +1,6 @@
import React from 'react'
-import { Box, Button } from '@mui/material'
+import { Box } from '@mui/material'
import MenuItem from '../MenuItem'
-import { logout } from '../../../../store/actions/AuthActionCreators'
-import { useAppDispatch } from '../../../../store'
-import { useNavigate } from 'react-router-dom'
import PersonIcon from '@mui/icons-material/Person'
import StarOutlineIcon from '@mui/icons-material/StarOutline'
import ForumIcon from '@mui/icons-material/Forum'
@@ -37,8 +34,6 @@ const links = [
]
export default function MenuList() {
- const dispatch = useAppDispatch()
- const navigate = useNavigate()
return (
{
+ getOAuth()
dispatch(fetchUser())
}, [])
- const isAuth = useAuth()
- const handleClick = () => {
- isAuth()
- }
return (
-
-
-
-
-
+ Для игры требуется регистрация
+
-
-
+
-
-
-
- История игры
-
-
-
- Считается, что игра Морской бой берет свое начало от французской
- игры L'Attaque, в которую играли во время Первой мировой войны,
- хотя параллели также были проведены с игрой Э.И. офицеров перед
- Первой мировой войной. Первой коммерческой версией игры была
- Salvo, изданная в 1931 году в США компанией Starex. Другие версии
- игры были напечатаны в 1930-х и 1940-х годах, в том числе Combat:
- The Battleship Game от Strathmore Company, Broadsides: A Game of
- Naval Strategy Милтона Брэдли и «Морской бой Мориса Л. Фридмана».
- Компания Strategy Games выпустила версию под названием Wings, в
- которой были изображены самолеты, летящие над Колизеем
- Лос-Анджелеса. Все эти ранние выпуски игры состояли из
- предварительно напечатанных листов бумаги.
+
+
+
+ История игры
+
+
+ Считается, что игра Морской бой берет свое начало от французской
+ игры L'Attaque, в которую играли во время Первой мировой войны,
+ хотя параллели также были проведены с игрой Э.И. офицеров перед
+ Первой мировой войной. Первой коммерческой версией игры была
+ Salvo, изданная в 1931 году в США компанией Starex. Другие
+ версии игры были напечатаны в 1930-х и 1940-х годах, в том числе
+ Combat: The Battleship Game от Strathmore Company, Broadsides: A
+ Game of Naval Strategy Милтона Брэдли и «Морской бой Мориса Л.
+ Фридмана». Компания Strategy Games выпустила версию под
+ названием Wings, в которой были изображены самолеты, летящие над
+ Колизеем Лос-Анджелеса. Все эти ранние выпуски игры состояли из
+ предварительно напечатанных листов бумаги.
+
+
@@ -113,33 +108,56 @@ export default function Intro() {
то есть расстояние между ними должно быть не менее одной клетки.
- ❗️ Переставлять свои корабли после начала игры категорически
- запрещено.
+ Правила
+
+
+ В игре принимают участие один игрок и компьютер. Корабли игрока
+ располагаются рандомно. При этом корабли не должны
+ соприкасаться, то есть расстояние между ними должно быть не
+ менее одной клетки.
+
+
+ ❗️ Переставлять свои корабли после начала игры категорически
+ запрещено.
+
-
- Стрельба по мишеням ведется до первого промаха, то есть если игрок
- попал в корабль противника, он производит следующий выстрел, и
- только после его промаха ход переходит к компьютеру. На поле и на
- экране промах обозначается точкой, а попадание — красным крестом в
- квадрате. Каждый выстрел имеет свои координаты. Победитель тот,
- кто первым уничтожит все корабли противника.
-
+
+ Стрельба по мишеням ведется до первого промаха, то есть если
+ игрок попал в корабль противника, он производит следующий
+ выстрел, и только после его промаха ход переходит к компьютеру.
+ На поле и на экране промах обозначается точкой, а попадание —
+ красным крестом в квадрате. Каждый выстрел имеет свои
+ координаты. Победитель тот, кто первым уничтожит все корабли
+ противника.
+
+
+
+
+
+ Проект команды Praga курса Мидл-Фронтенд Разработчик
+ Яндекс.Практикум 2022
+
+
+
-
-
-
- Проект команды Praga курса Мидл-Фронтенд Разработчик
- Яндекс.Практикум 2022
-
-
-
-
+
)
}
diff --git a/packages/client/src/pages/profile/Profile.tsx b/packages/client/src/pages/profile/Profile.tsx
index 528e3c0..c19c29f 100644
--- a/packages/client/src/pages/profile/Profile.tsx
+++ b/packages/client/src/pages/profile/Profile.tsx
@@ -205,8 +205,8 @@ const Profile = () => {
marginTop: 1,
}}
onClick={() => {
- dispatch(logout())
- navigate('/auth')
+ dispatch(logout()).then(()=>navigate('/auth'))
+
}}>
Выйти из профиля
diff --git a/packages/client/src/pages/ranking/Ranking.tsx b/packages/client/src/pages/ranking/Ranking.tsx
index 0103710..34a8817 100644
--- a/packages/client/src/pages/ranking/Ranking.tsx
+++ b/packages/client/src/pages/ranking/Ranking.tsx
@@ -1,4 +1,5 @@
-import React, { useEffect, useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
+import { useNavigate } from 'react-router-dom'
import {
Box,
TableRow,
@@ -11,13 +12,18 @@ import {
TablePagination,
Paper,
Typography,
+ Button,
} from '@mui/material'
-import avatarStub from '../../assets/avatar-stub.svg'
-import { useAppDispatch } from '../../store/index'
-import { fetchLeaderboard } from '../../store/actions/RatingActionCreators'
-import { selectRatingData } from '../../store/slices/RatingSlice'
+import ArrowBackIcon from '@mui/icons-material/ArrowBack'
+import avatarStub from '@assets/avatar-stub.svg'
+import { useAppDispatch } from '@store/index'
+import { fetchLeaderboard } from '@store/actions/RatingActionCreators'
+import { selectRatingData } from '@store/slices/RatingSlice'
+import { avatarContainer, container } from './styles'
export default function Ranking() {
+ const navigate = useNavigate()
+
const dispatch = useAppDispatch()
const ratingData = selectRatingData()
@@ -42,76 +48,83 @@ export default function Ranking() {
setPage(0)
}
+ const tableData = useMemo(
+ () =>
+ [...ratingData]
+ .sort((a, b) => b.data.score - a.data.score)
+ .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage),
+ [ratingData, page, rowsPerPage]
+ )
+
return (
-
+
+ navigate('/game/start')}
+ startIcon={}
+ sx={{ alignSelf: 'flex-start' }}>
+ Назад
+
Таблица лидеров
-
-
-
-
- Место
- Игрок
- Побед
-
-
-
- {ratingData
- .sort((a, b) => a.data.score - b.data.score)
- .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
- .map(({ data: { score, id, name } }, index) => (
+ {ratingData.length ? (
+
+
+
+
+ Место
+ Игрок
+ Побед
+
+
+
+ {tableData.map(({ data: { score, id, name } }, index) => (
- {index + 1}
-
-
- {name}
+ {index + 1}
+
+
+ {name}
- {score}
+ {score}
))}
-
-
-
-
- from + ' - ' + to + ' из ' + count
- }
- labelRowsPerPage={Игроков на странице}
- onPageChange={handleChangePage}
- onRowsPerPageChange={handleChangeRowsPerPage}
- />
-
-
-
-
+
+
+
+
+ `${from} - ${to} из ${count}`
+ }
+ labelRowsPerPage={Игроков на странице}
+ onPageChange={handleChangePage}
+ onRowsPerPageChange={handleChangeRowsPerPage}
+ />
+
+
+
+
+ ) : (
+ Пока никого нет, будь первым! :-)
+ )}
)
}
diff --git a/packages/client/src/pages/ranking/styles.ts b/packages/client/src/pages/ranking/styles.ts
new file mode 100644
index 0000000..e6f27e8
--- /dev/null
+++ b/packages/client/src/pages/ranking/styles.ts
@@ -0,0 +1,15 @@
+export const container = {
+ margin: '24px auto',
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '24px',
+ alignItems: 'center',
+}
+
+export const avatarContainer = {
+ display: 'grid',
+ gridTemplateColumns: '1fr 1fr',
+ gridGap: '16px',
+ alignItems: 'center',
+ justifyItems: 'center',
+}
diff --git a/packages/client/src/store/actions/AuthActionCreators.ts b/packages/client/src/store/actions/AuthActionCreators.ts
index fd5ff9e..f5cf390 100644
--- a/packages/client/src/store/actions/AuthActionCreators.ts
+++ b/packages/client/src/store/actions/AuthActionCreators.ts
@@ -1,6 +1,6 @@
import { createAsyncThunk } from '@reduxjs/toolkit'
-import { LoginData, UserData } from '../types'
import { axiosInstance } from '../../services/BaseApi'
+import { LoginData, OauthData, UserData } from '@store/types'
export const register = createAsyncThunk(
'auth/register',
@@ -45,3 +45,27 @@ export const logout = createAsyncThunk('auth/logout', async (_, thunkApi) => {
return thunkApi.rejectWithValue('Не удалось выйти из приложения')
}
})
+
+export const getServiceId = createAsyncThunk(
+ 'auth/serviceid',
+ async (_, thunkApi) => {
+ try {
+ const response = await axiosInstance.get('oauth/yandex/service-id')
+ return response.data
+ } catch (e) {
+ return thunkApi.rejectWithValue('No such redirect_uri refistered')
+ }
+ }
+)
+
+export const oauthYandex = createAsyncThunk(
+ 'auth/yandex',
+ async (data: OauthData, thunkApi) => {
+ try {
+ const response = await axiosInstance.post('oauth/yandex', data)
+ return response.data
+ } catch (e) {
+ return thunkApi.rejectWithValue('Пользователь не авторизован в системе')
+ }
+ }
+)
diff --git a/packages/client/src/store/actions/RatingActionCreators.ts b/packages/client/src/store/actions/RatingActionCreators.ts
index 911f916..b6abff3 100644
--- a/packages/client/src/store/actions/RatingActionCreators.ts
+++ b/packages/client/src/store/actions/RatingActionCreators.ts
@@ -3,7 +3,7 @@ import { Ranking } from '../types'
import { axiosInstance } from '../../services/BaseApi'
-const teamName = 'praga'
+const teamName = 'praga-v2'
const ratingFieldName = 'score'
export const fetchLeaderboard = createAsyncThunk(
diff --git a/packages/client/src/store/slices/AuthSlice.ts b/packages/client/src/store/slices/AuthSlice.ts
index 5be606b..3eadbf6 100644
--- a/packages/client/src/store/slices/AuthSlice.ts
+++ b/packages/client/src/store/slices/AuthSlice.ts
@@ -1,11 +1,19 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { fetchUser } from '../actions/UserActionCreators'
-import { logout, register, login } from '../actions/AuthActionCreators'
+import {
+ register,
+ login,
+ logout,
+ getServiceId,
+ oauthYandex,
+} from '@store/actions/AuthActionCreators'
+import { RootState } from '../index'
import {
StatusLoading,
RequestDataState,
RequestData,
UserData,
+ OauthData,
} from '../types'
export interface AuthState {
@@ -28,6 +36,8 @@ const initialState: AuthState = {
signIn: {} as RequestDataState,
getUserInfo: {} as RequestDataState,
logout: {} as RequestDataState,
+ getServiceId: {} as RequestDataState,
+ oauth: {} as RequestDataState,
},
}
@@ -81,7 +91,35 @@ export const authSlice = createSlice({
state.requestData.logout.errorMessage = payload
state.requestData.logout.status = StatusLoading.ERROR
},
+ [getServiceId.fulfilled.type]: state => {
+ state.requestData.getServiceId.status = StatusLoading.SUCCESS
+ },
+ [getServiceId.pending.type]: state => {
+ state.requestData.getServiceId.status = StatusLoading.IN_PROGRESS
+ },
+ [getServiceId.rejected.type]: (
+ state,
+ { payload }: PayloadAction
+ ) => {
+ state.requestData.getServiceId.errorMessage = payload
+ state.requestData.getServiceId.status = StatusLoading.ERROR
+ },
+ [oauthYandex.fulfilled.type]: state => {
+ state.requestData.oauth.status = StatusLoading.SUCCESS
+ },
+ [oauthYandex.pending.type]: state => {
+ state.requestData.oauth.status = StatusLoading.IN_PROGRESS
+ },
+ [oauthYandex.rejected.type]: (
+ state,
+ { payload }: PayloadAction
+ ) => {
+ state.requestData.oauth.errorMessage = payload
+ state.requestData.oauth.status = StatusLoading.ERROR
+ },
},
})
+export const selectUserData = (state: RootState) => state.auth.user
+
export default authSlice.reducer
diff --git a/packages/client/src/store/types.ts b/packages/client/src/store/types.ts
index f48d3f7..45a82f5 100644
--- a/packages/client/src/store/types.ts
+++ b/packages/client/src/store/types.ts
@@ -21,9 +21,9 @@ export interface RankingResponse {
}
export interface Ranking {
- id: number
+ id?: number
name: string
- avatar: string
+ avatar?: string
score: number
}
@@ -74,3 +74,8 @@ export interface PassWord {
oldPassword: string
newPassword: string
}
+
+export interface OauthData {
+ code: string
+ redirect_uri: string
+}
\ No newline at end of file
diff --git a/packages/client/sw.js b/packages/client/sw.js
index bb98549..1698cc0 100644
--- a/packages/client/sw.js
+++ b/packages/client/sw.js
@@ -1,7 +1,6 @@
const CACHE_NAME = 'my-site-cache-v1'
const URLS = [
- // '/',
'./src/main.tsx',
]
diff --git a/packages/client/vite.config.ts.timestamp-1670430434783.mjs b/packages/client/vite.config.ts.timestamp-1670430434783.mjs
new file mode 100644
index 0000000..95c4af9
--- /dev/null
+++ b/packages/client/vite.config.ts.timestamp-1670430434783.mjs
@@ -0,0 +1,32 @@
+// vite.config.ts
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import dotenv from "dotenv";
+import path from "path";
+var __vite_injected_original_dirname = "C:\\Users\\Michael\\Desktop\\work\\praga\\packages\\client";
+dotenv.config();
+var vite_config_default = defineConfig({
+ server: {
+ port: Number(process.env.CLIENT_PORT) || 3e3
+ },
+ define: {
+ __SERVER_PORT__: process.env.SERVER_PORT
+ },
+ ssr: {
+ target: "node",
+ format: "cjs"
+ },
+ plugins: [react()],
+ resolve: {
+ alias: {
+ "@assets": path.resolve(__vite_injected_original_dirname, "./src/assets"),
+ "@pages": path.resolve(__vite_injected_original_dirname, "./src/pages"),
+ "@components": path.resolve(__vite_injected_original_dirname, "./src/components"),
+ "@store": path.resolve(__vite_injected_original_dirname, "./src/store")
+ }
+ }
+});
+export {
+ vite_config_default as default
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxVc2Vyc1xcXFxNaWNoYWVsXFxcXERlc2t0b3BcXFxcd29ya1xcXFxwcmFnYVxcXFxwYWNrYWdlc1xcXFxjbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXFVzZXJzXFxcXE1pY2hhZWxcXFxcRGVza3RvcFxcXFx3b3JrXFxcXHByYWdhXFxcXHBhY2thZ2VzXFxcXGNsaWVudFxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovVXNlcnMvTWljaGFlbC9EZXNrdG9wL3dvcmsvcHJhZ2EvcGFja2FnZXMvY2xpZW50L3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5pbXBvcnQgZG90ZW52IGZyb20gJ2RvdGVudidcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcclxuZG90ZW52LmNvbmZpZygpXHJcblxyXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xyXG4gIHNlcnZlcjoge1xyXG4gICAgcG9ydDogTnVtYmVyKHByb2Nlc3MuZW52LkNMSUVOVF9QT1JUKSB8fCAzMDAwLFxyXG4gIH0sXHJcbiAgZGVmaW5lOiB7XHJcbiAgICBfX1NFUlZFUl9QT1JUX186IHByb2Nlc3MuZW52LlNFUlZFUl9QT1JULFxyXG4gIH0sXHJcbiAgc3NyOiB7XHJcbiAgICB0YXJnZXQ6ICdub2RlJyxcclxuICAgIGZvcm1hdDogJ2NqcydcclxuICB9LFxyXG4gIHBsdWdpbnM6IFtyZWFjdCgpXSxcclxuICByZXNvbHZlOiB7XHJcbiAgICBhbGlhczoge1xyXG4gICAgICAnQGFzc2V0cyc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9hc3NldHMnKSxcclxuICAgICAgJ0BwYWdlcyc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9wYWdlcycpLFxyXG4gICAgICAnQGNvbXBvbmVudHMnOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9zcmMvY29tcG9uZW50cycpLFxyXG4gICAgICAnQHN0b3JlJzogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vc3JjL3N0b3JlJyksXHJcbiAgICB9LFxyXG4gIH0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBMlYsU0FBUyxvQkFBb0I7QUFDeFgsT0FBTyxXQUFXO0FBQ2xCLE9BQU8sWUFBWTtBQUNuQixPQUFPLFVBQVU7QUFIakIsSUFBTSxtQ0FBbUM7QUFJekMsT0FBTyxPQUFPO0FBR2QsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsUUFBUTtBQUFBLElBQ04sTUFBTSxPQUFPLFFBQVEsSUFBSSxXQUFXLEtBQUs7QUFBQSxFQUMzQztBQUFBLEVBQ0EsUUFBUTtBQUFBLElBQ04saUJBQWlCLFFBQVEsSUFBSTtBQUFBLEVBQy9CO0FBQUEsRUFDQSxLQUFLO0FBQUEsSUFDSCxRQUFRO0FBQUEsSUFDUixRQUFRO0FBQUEsRUFDVjtBQUFBLEVBQ0EsU0FBUyxDQUFDLE1BQU0sQ0FBQztBQUFBLEVBQ2pCLFNBQVM7QUFBQSxJQUNQLE9BQU87QUFBQSxNQUNMLFdBQVcsS0FBSyxRQUFRLGtDQUFXLGNBQWM7QUFBQSxNQUNqRCxVQUFVLEtBQUssUUFBUSxrQ0FBVyxhQUFhO0FBQUEsTUFDL0MsZUFBZSxLQUFLLFFBQVEsa0NBQVcsa0JBQWtCO0FBQUEsTUFDekQsVUFBVSxLQUFLLFFBQVEsa0NBQVcsYUFBYTtBQUFBLElBQ2pEO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
diff --git a/packages/client/vite.config.ts.timestamp-1670430456327.mjs b/packages/client/vite.config.ts.timestamp-1670430456327.mjs
new file mode 100644
index 0000000..95c4af9
--- /dev/null
+++ b/packages/client/vite.config.ts.timestamp-1670430456327.mjs
@@ -0,0 +1,32 @@
+// vite.config.ts
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import dotenv from "dotenv";
+import path from "path";
+var __vite_injected_original_dirname = "C:\\Users\\Michael\\Desktop\\work\\praga\\packages\\client";
+dotenv.config();
+var vite_config_default = defineConfig({
+ server: {
+ port: Number(process.env.CLIENT_PORT) || 3e3
+ },
+ define: {
+ __SERVER_PORT__: process.env.SERVER_PORT
+ },
+ ssr: {
+ target: "node",
+ format: "cjs"
+ },
+ plugins: [react()],
+ resolve: {
+ alias: {
+ "@assets": path.resolve(__vite_injected_original_dirname, "./src/assets"),
+ "@pages": path.resolve(__vite_injected_original_dirname, "./src/pages"),
+ "@components": path.resolve(__vite_injected_original_dirname, "./src/components"),
+ "@store": path.resolve(__vite_injected_original_dirname, "./src/store")
+ }
+ }
+});
+export {
+ vite_config_default as default
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxVc2Vyc1xcXFxNaWNoYWVsXFxcXERlc2t0b3BcXFxcd29ya1xcXFxwcmFnYVxcXFxwYWNrYWdlc1xcXFxjbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXFVzZXJzXFxcXE1pY2hhZWxcXFxcRGVza3RvcFxcXFx3b3JrXFxcXHByYWdhXFxcXHBhY2thZ2VzXFxcXGNsaWVudFxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovVXNlcnMvTWljaGFlbC9EZXNrdG9wL3dvcmsvcHJhZ2EvcGFja2FnZXMvY2xpZW50L3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5pbXBvcnQgZG90ZW52IGZyb20gJ2RvdGVudidcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcclxuZG90ZW52LmNvbmZpZygpXHJcblxyXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xyXG4gIHNlcnZlcjoge1xyXG4gICAgcG9ydDogTnVtYmVyKHByb2Nlc3MuZW52LkNMSUVOVF9QT1JUKSB8fCAzMDAwLFxyXG4gIH0sXHJcbiAgZGVmaW5lOiB7XHJcbiAgICBfX1NFUlZFUl9QT1JUX186IHByb2Nlc3MuZW52LlNFUlZFUl9QT1JULFxyXG4gIH0sXHJcbiAgc3NyOiB7XHJcbiAgICB0YXJnZXQ6ICdub2RlJyxcclxuICAgIGZvcm1hdDogJ2NqcydcclxuICB9LFxyXG4gIHBsdWdpbnM6IFtyZWFjdCgpXSxcclxuICByZXNvbHZlOiB7XHJcbiAgICBhbGlhczoge1xyXG4gICAgICAnQGFzc2V0cyc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9hc3NldHMnKSxcclxuICAgICAgJ0BwYWdlcyc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9wYWdlcycpLFxyXG4gICAgICAnQGNvbXBvbmVudHMnOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9zcmMvY29tcG9uZW50cycpLFxyXG4gICAgICAnQHN0b3JlJzogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vc3JjL3N0b3JlJyksXHJcbiAgICB9LFxyXG4gIH0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBMlYsU0FBUyxvQkFBb0I7QUFDeFgsT0FBTyxXQUFXO0FBQ2xCLE9BQU8sWUFBWTtBQUNuQixPQUFPLFVBQVU7QUFIakIsSUFBTSxtQ0FBbUM7QUFJekMsT0FBTyxPQUFPO0FBR2QsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsUUFBUTtBQUFBLElBQ04sTUFBTSxPQUFPLFFBQVEsSUFBSSxXQUFXLEtBQUs7QUFBQSxFQUMzQztBQUFBLEVBQ0EsUUFBUTtBQUFBLElBQ04saUJBQWlCLFFBQVEsSUFBSTtBQUFBLEVBQy9CO0FBQUEsRUFDQSxLQUFLO0FBQUEsSUFDSCxRQUFRO0FBQUEsSUFDUixRQUFRO0FBQUEsRUFDVjtBQUFBLEVBQ0EsU0FBUyxDQUFDLE1BQU0sQ0FBQztBQUFBLEVBQ2pCLFNBQVM7QUFBQSxJQUNQLE9BQU87QUFBQSxNQUNMLFdBQVcsS0FBSyxRQUFRLGtDQUFXLGNBQWM7QUFBQSxNQUNqRCxVQUFVLEtBQUssUUFBUSxrQ0FBVyxhQUFhO0FBQUEsTUFDL0MsZUFBZSxLQUFLLFFBQVEsa0NBQVcsa0JBQWtCO0FBQUEsTUFDekQsVUFBVSxLQUFLLFFBQVEsa0NBQVcsYUFBYTtBQUFBLElBQ2pEO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
diff --git a/packages/client/vite.config.ts.timestamp-1670430526922.mjs b/packages/client/vite.config.ts.timestamp-1670430526922.mjs
new file mode 100644
index 0000000..2dd7292
--- /dev/null
+++ b/packages/client/vite.config.ts.timestamp-1670430526922.mjs
@@ -0,0 +1,32 @@
+// vite.config.ts
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import dotenv from "dotenv";
+import path from "path";
+var __vite_injected_original_dirname = "C:\\Users\\Michael\\Desktop\\work\\Praga\\packages\\client";
+dotenv.config();
+var vite_config_default = defineConfig({
+ server: {
+ port: Number(process.env.CLIENT_PORT) || 3e3
+ },
+ define: {
+ __SERVER_PORT__: process.env.SERVER_PORT
+ },
+ ssr: {
+ target: "node",
+ format: "cjs"
+ },
+ plugins: [react()],
+ resolve: {
+ alias: {
+ "@assets": path.resolve(__vite_injected_original_dirname, "./src/assets"),
+ "@pages": path.resolve(__vite_injected_original_dirname, "./src/pages"),
+ "@components": path.resolve(__vite_injected_original_dirname, "./src/components"),
+ "@store": path.resolve(__vite_injected_original_dirname, "./src/store")
+ }
+ }
+});
+export {
+ vite_config_default as default
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxVc2Vyc1xcXFxNaWNoYWVsXFxcXERlc2t0b3BcXFxcd29ya1xcXFxQcmFnYVxcXFxwYWNrYWdlc1xcXFxjbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXFVzZXJzXFxcXE1pY2hhZWxcXFxcRGVza3RvcFxcXFx3b3JrXFxcXFByYWdhXFxcXHBhY2thZ2VzXFxcXGNsaWVudFxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovVXNlcnMvTWljaGFlbC9EZXNrdG9wL3dvcmsvUHJhZ2EvcGFja2FnZXMvY2xpZW50L3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5pbXBvcnQgZG90ZW52IGZyb20gJ2RvdGVudidcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcclxuZG90ZW52LmNvbmZpZygpXHJcblxyXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xyXG4gIHNlcnZlcjoge1xyXG4gICAgcG9ydDogTnVtYmVyKHByb2Nlc3MuZW52LkNMSUVOVF9QT1JUKSB8fCAzMDAwLFxyXG4gIH0sXHJcbiAgZGVmaW5lOiB7XHJcbiAgICBfX1NFUlZFUl9QT1JUX186IHByb2Nlc3MuZW52LlNFUlZFUl9QT1JULFxyXG4gIH0sXHJcbiAgc3NyOiB7XHJcbiAgICB0YXJnZXQ6ICdub2RlJyxcclxuICAgIGZvcm1hdDogJ2NqcydcclxuICB9LFxyXG4gIHBsdWdpbnM6IFtyZWFjdCgpXSxcclxuICByZXNvbHZlOiB7XHJcbiAgICBhbGlhczoge1xyXG4gICAgICAnQGFzc2V0cyc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9hc3NldHMnKSxcclxuICAgICAgJ0BwYWdlcyc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9wYWdlcycpLFxyXG4gICAgICAnQGNvbXBvbmVudHMnOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9zcmMvY29tcG9uZW50cycpLFxyXG4gICAgICAnQHN0b3JlJzogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vc3JjL3N0b3JlJyksXHJcbiAgICB9LFxyXG4gIH0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBMlYsU0FBUyxvQkFBb0I7QUFDeFgsT0FBTyxXQUFXO0FBQ2xCLE9BQU8sWUFBWTtBQUNuQixPQUFPLFVBQVU7QUFIakIsSUFBTSxtQ0FBbUM7QUFJekMsT0FBTyxPQUFPO0FBR2QsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsUUFBUTtBQUFBLElBQ04sTUFBTSxPQUFPLFFBQVEsSUFBSSxXQUFXLEtBQUs7QUFBQSxFQUMzQztBQUFBLEVBQ0EsUUFBUTtBQUFBLElBQ04saUJBQWlCLFFBQVEsSUFBSTtBQUFBLEVBQy9CO0FBQUEsRUFDQSxLQUFLO0FBQUEsSUFDSCxRQUFRO0FBQUEsSUFDUixRQUFRO0FBQUEsRUFDVjtBQUFBLEVBQ0EsU0FBUyxDQUFDLE1BQU0sQ0FBQztBQUFBLEVBQ2pCLFNBQVM7QUFBQSxJQUNQLE9BQU87QUFBQSxNQUNMLFdBQVcsS0FBSyxRQUFRLGtDQUFXLGNBQWM7QUFBQSxNQUNqRCxVQUFVLEtBQUssUUFBUSxrQ0FBVyxhQUFhO0FBQUEsTUFDL0MsZUFBZSxLQUFLLFFBQVEsa0NBQVcsa0JBQWtCO0FBQUEsTUFDekQsVUFBVSxLQUFLLFFBQVEsa0NBQVcsYUFBYTtBQUFBLElBQ2pEO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
diff --git a/packages/server/index.ts b/packages/server/index.ts
index 28e9179..e38b334 100644
--- a/packages/server/index.ts
+++ b/packages/server/index.ts
@@ -5,12 +5,8 @@ import fs from 'fs'
import path from 'path'
import type { ViteDevServer } from 'vite'
import { createServer as createViteServer } from 'vite'
-// import queryParser from 'search-query-parser'
-// import cookieParser from 'cookie-parser'
-
import sequelize from './sequelize'
import router from './router'
-// import { userThemeRouter } from './controllers/userTheme'
dotenv.config()
@@ -22,11 +18,8 @@ async function createServer(isDev = process.env.NODE_ENV === 'development') {
const app = express()
app.disable('x-powered-by').enable('trust proxy')
- // .set('query parser', queryParser)
- // .use(cookieParser())
- // .use(logger)
- // .use(router)
- // .use(notFound);
+
+
let vite: ViteDevServer
diff --git a/packages/server/package.json b/packages/server/package.json
index e6f7c31..0aecc47 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -6,6 +6,7 @@
"build": "rm -rf ./dist && tsc --p ./tsconfig.prod.json",
"preview": "node ./dist/index.js",
"dev": "cross-env NODE_ENV=development nodemon index.ts",
+ "serve": "yarn build && yarn preview",
"lint": "eslint .",
"format": "prettier --write .",
"test": "jest ."
diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json
index ad2f262..77f7451 100644
--- a/packages/server/tsconfig.json
+++ b/packages/server/tsconfig.json
@@ -21,12 +21,21 @@
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strictPropertyInitialization": false,
- "lib": ["es2019", "esnext.asynciterable", "dom"],
- "types": ["node", "jest"],
+ "lib": [
+ "es2019",
+ "esnext.asynciterable",
+ "dom"
+ ],
+ "types": [
+ "node",
+ "jest"
+ ],
"baseUrl": ".",
"paths": {
- "*": ["types/*"]
+ "*": [
+ "types/*"
+ ]
},
"outDir": "dist"
}
-}
+}
\ No newline at end of file