diff --git a/.eslintrc.js b/.eslintrc.js index 3e0ddea..8c2376f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,9 +26,10 @@ module.exports = { 'quotes': ['error', 'single'] }, ignorePatterns: [ - "packages/client/dist", - "packages/server/dist", - "packages/server/db.js", - "packages/server/index.js" + 'packages/client/dist', + 'packages/server/dist', + 'packages/server/db.js', + 'packages/server/index.js', + 'packages/server/ts-dist/*', ] } diff --git a/packages/client/index.html b/packages/client/index.html index 848a49d..f40ac59 100644 --- a/packages/client/index.html +++ b/packages/client/index.html @@ -11,6 +11,8 @@ href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet" /> + + Falcon Tanks diff --git a/packages/client/package.json b/packages/client/package.json index 80bc5d0..7441cd3 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -21,6 +21,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-toastify": "^10.0.5", + "sass": "^1.81.0", "serialize-javascript": "^6.0.2" }, "devDependencies": { @@ -41,7 +42,6 @@ "prettier": "^2.7.1", "react-redux": "^9.1.2", "react-router-dom": "^6.26.2", - "sass": "^1.79.1", "ts-jest": "^28.0.8", "typescript": "^4.8.2", "vite": "^3.0.7" diff --git a/packages/client/public/styles.css b/packages/client/public/styles.css new file mode 100644 index 0000000..ca91f6c --- /dev/null +++ b/packages/client/public/styles.css @@ -0,0 +1,52 @@ +body { + background-color: #242424; +} + +.preloader { + position: fixed; + display: none; + align-items: center; + justify-content: center; + inset: 0; + z-index: 10; + background-color: rgb(0, 0, 0); +} +.preloader_show { + display: flex; +} +.preloader__road { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 150px; + height: 150px; + background-color: #2c414c; + background-image: url('@/assets/images/ground.png'); + background-size: 50px 50px; + border-radius: 20px; + animation: moveRoad 2s linear infinite; +} +.preloader__image { + width: 60px; +} +.preloader__close-btn { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, 100px); + cursor: pointer; + background: none; + border: none; + outline: none; + color: #f8f8f8; + font-size: 14px; +} +.preloader__close-btn:hover { + text-decoration: underline; +} +@keyframes moveRoad { + 100% { + background-position: 0px 50px; + } +} diff --git a/packages/client/src/components/common/Reaction/Reaction.scss b/packages/client/src/components/common/Reaction/Reaction.scss index 6a4b141..b7899b6 100644 --- a/packages/client/src/components/common/Reaction/Reaction.scss +++ b/packages/client/src/components/common/Reaction/Reaction.scss @@ -1,4 +1,4 @@ -@import "../../../scss/vars.scss"; +@import '../../../scss/vars.scss'; @keyframes fadeIn { from { diff --git a/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.scss b/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.scss index f2638f0..5a3b0a0 100644 --- a/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.scss +++ b/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.scss @@ -1,44 +1,44 @@ .christmas-toggle { - width: 46px; - height: 24px; - background-color: #e5e5e5; - border-radius: 50px; - position: relative; - overflow: hidden; - cursor: pointer; - transition: background-color 0.3s ease-in-out; + width: 46px; + height: 24px; + background-color: #e5e5e5; + border-radius: 50px; + position: relative; + overflow: hidden; + cursor: pointer; + transition: background-color 0.3s ease-in-out; + + &::before { + content: ''; + position: absolute; + inset: 0; + opacity: 1; + background-image: url('https://media.istockphoto.com/id/1181274264/vector/christmas-backgrounds-seamless-pattern-vector-illustration.jpg?s=612x612&w=0&k=20&c=qjaiUif53nf-OjYeLwgOgtmoPlhoqFNpiN9Xw1PHY50='); + background-size: 350%; + transition: opacity 0.3s ease-in-out; + } + + &.checked { + background-color: #839d22; &::before { - content: ''; - position: absolute; - inset: 0; - opacity: 1; - background-image: url('https://media.istockphoto.com/id/1181274264/vector/christmas-backgrounds-seamless-pattern-vector-illustration.jpg?s=612x612&w=0&k=20&c=qjaiUif53nf-OjYeLwgOgtmoPlhoqFNpiN9Xw1PHY50='); - background-size: 350%; - transition: opacity 0.3s ease-in-out; + opacity: 0; } - - &.checked { - background-color: #839d22; + } - &::before { - opacity: 0; - } - } - - &__slider { - width: 20px; - height: 20px; - background-color: #fff; - border-radius: 50%; - position: absolute; - top: 2px; - left: 2px; - transition: transform 0.3s ease-in-out; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - } - - &.checked .christmas-toggle__slider { - transform: translateX(22px); - } - } \ No newline at end of file + &__slider { + width: 20px; + height: 20px; + background-color: #fff; + border-radius: 50%; + position: absolute; + top: 2px; + left: 2px; + transition: transform 0.3s ease-in-out; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + } + + &.checked .christmas-toggle__slider { + transform: translateX(22px); + } +} diff --git a/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.tsx b/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.tsx index d860fbf..a05f1bd 100644 --- a/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.tsx +++ b/packages/client/src/components/ui/ChristmasToggle/ChristmasToggle.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import './ChristmasToggle.scss' interface IosToggleProps { @@ -10,7 +10,7 @@ export const ChristmasToggle: React.FC = ({ checked = false, onChange, }) => { - const [isChecked, setIsChecked] = useState(checked) + const [isChecked, setIsChecked] = useState(false) const handleToggle = () => { const newChecked = !isChecked @@ -18,6 +18,10 @@ export const ChristmasToggle: React.FC = ({ if (onChange) onChange(newChecked) } + useEffect(() => { + setIsChecked(checked) + }, [checked]) + return (
diff --git a/packages/client/src/layouts/PrivateLayout/PrivateLayout.tsx b/packages/client/src/layouts/PrivateLayout/PrivateLayout.tsx index 0df66c3..658c10c 100644 --- a/packages/client/src/layouts/PrivateLayout/PrivateLayout.tsx +++ b/packages/client/src/layouts/PrivateLayout/PrivateLayout.tsx @@ -24,9 +24,11 @@ export function PrivateLayout() { .then(data => { dispatch(actions.setUser(data)) window.sessionStorage.setItem('userIsLogged', '1') // 0 + window.sessionStorage.setItem('userId', data.id.toString()) }) .catch(() => { window.sessionStorage.setItem('userIsLogged', '0') // 0 + window.sessionStorage.setItem('userId', '') toast.error('Необходимо авторизоваться', { autoClose: 1500, diff --git a/packages/client/src/layouts/PublicLayout/PublicLayout.scss b/packages/client/src/layouts/PublicLayout/PublicLayout.scss index 166c805..4acebe4 100644 --- a/packages/client/src/layouts/PublicLayout/PublicLayout.scss +++ b/packages/client/src/layouts/PublicLayout/PublicLayout.scss @@ -10,5 +10,6 @@ &__body { flex: 1 1 100%; padding-top: $layout_body-m-top; + padding-bottom: calc($layout_body-m-top + $layout_body-m-top); } } diff --git a/packages/client/src/layouts/RootLayout/RootLayout.tsx b/packages/client/src/layouts/RootLayout/RootLayout.tsx index 186d0e1..27d02a6 100644 --- a/packages/client/src/layouts/RootLayout/RootLayout.tsx +++ b/packages/client/src/layouts/RootLayout/RootLayout.tsx @@ -11,7 +11,20 @@ export default function RootLayout() { ) useEffect(() => { - document.body.classList.add('custom-theme__' + themeAlias) + const bodyEl = document?.body + const bodyClassname = bodyEl?.getAttribute('class') || '' + + if (typeof bodyClassname === 'string') { + const classListString = bodyClassname + .replace(/\bcustom-theme__\S*/g, '') + .replace(/\btypescript\b/g, '') + .trim() + + bodyEl.setAttribute( + 'class', + `${classListString} custom-theme__${themeAlias}` + ) + } }) return ( diff --git a/packages/client/src/pages/Game/Game.scss b/packages/client/src/pages/Game/Game.scss index 8ce909d..4476290 100644 --- a/packages/client/src/pages/Game/Game.scss +++ b/packages/client/src/pages/Game/Game.scss @@ -10,6 +10,8 @@ $border-color: #70842f; .game-page { + padding-bottom: 80px; + &__container { margin: 0 auto; max-width: 1400px !important; diff --git a/packages/client/src/pages/Leaderboard/components/User/User.scss b/packages/client/src/pages/Leaderboard/components/User/User.scss index e0c0435..57d0250 100644 --- a/packages/client/src/pages/Leaderboard/components/User/User.scss +++ b/packages/client/src/pages/Leaderboard/components/User/User.scss @@ -2,9 +2,11 @@ // Константы для медалей $medal-colors: ( - 1: #ffd700, // Gold - 2: #c0c0c0, // Silver - 3: #cd7f32 // Bronze + 1: #ffd700, + // Gold + 2: #c0c0c0, + // Silver + 3: #cd7f32 // Bronze, ); $c_item-border-main-color: #9d9b9b; @@ -15,14 +17,22 @@ $c_item-border-secondary-color: #474747; &__item-wrapper { position: relative; border-radius: 16px; - background: linear-gradient(90deg, $c_item-border-main-color 52.5%, $c_item-border-secondary-color 100%); + background: linear-gradient( + 90deg, + $c_item-border-main-color 52.5%, + $c_item-border-secondary-color 100% + ); margin: 5px 0; padding: 2px; // Медальные рамки @each $rank, $color in $medal-colors { &__rank-#{$rank} { - background: linear-gradient(90deg, $color 52.5%, darken($color, 20%) 100%); + background: linear-gradient( + 90deg, + $color 52.5%, + darken($color, 20%) 100% + ); } } } @@ -124,4 +134,4 @@ $c_item-border-secondary-color: #474747; &__load-more { margin: 48px auto 0 auto; } -} \ No newline at end of file +} diff --git a/packages/client/src/pages/Profile/Profile.scss b/packages/client/src/pages/Profile/Profile.scss index 86a137c..ba61a34 100644 --- a/packages/client/src/pages/Profile/Profile.scss +++ b/packages/client/src/pages/Profile/Profile.scss @@ -36,6 +36,7 @@ align-items: center; min-height: 100vh; box-sizing: border-box; + padding-bottom: 40px; &__title { margin-bottom: 48px; diff --git a/packages/client/src/scss/styles.scss b/packages/client/src/scss/styles.scss index 5822926..2e86e48 100644 --- a/packages/client/src/scss/styles.scss +++ b/packages/client/src/scss/styles.scss @@ -3,4 +3,4 @@ @import './base.scss'; @import './grid-system.scss'; -@import './themes/christmas.scss'; \ No newline at end of file +@import './themes/christmas.scss'; diff --git a/packages/client/src/scss/themes/christmas.scss b/packages/client/src/scss/themes/christmas.scss index 2b7afc3..ed8c2f8 100644 --- a/packages/client/src/scss/themes/christmas.scss +++ b/packages/client/src/scss/themes/christmas.scss @@ -1,75 +1,75 @@ .custom-theme__christmas { - .main-nav { - position: relative; + .main-nav { + position: relative; - &:after { - content: ''; - position: absolute; - left: 0; - right: 0; - bottom: -8px; - height: 40px; - background: url('@/assets/images/themes/christmas/garland.png') repeat-x; - background-size: contain; - } + &:after { + content: ''; + position: absolute; + left: 0; + right: 0; + bottom: -8px; + height: 40px; + background: url('@/assets/images/themes/christmas/garland.png') repeat-x; + background-size: contain; } - - .logo-block { - position: relative; + } - &__image { - filter: grayscale(1); - } + .logo-block { + position: relative; - &::before { - content: ''; - position: absolute; - z-index: 1; - left: 16px; - top: 4px; - width: 44px; - height: 32px; - background: url('@/assets/images/themes/christmas/head.png'); - background-size: contain; - background-repeat: no-repeat; - } + &__image { + filter: grayscale(1); } - - .custom-page-title__content { - position: relative; - overflow: hidden; - z-index: 1; - background-image: url("@/assets/images/themes/christmas/titlebar__bg.jpg"); - background-size: cover; - &::before { - content: ''; - position: absolute; - inset: 0; - background: rgba(0, 0, 0, 0.5); - z-index: -1; - } + &::before { + content: ''; + position: absolute; + z-index: 1; + left: 16px; + top: 4px; + width: 44px; + height: 32px; + background: url('@/assets/images/themes/christmas/head.png'); + background-size: contain; + background-repeat: no-repeat; } + } - .preloader__road { - background-image: url("@/assets/images/themes/christmas/christmas-ground.png"); + .custom-page-title__content { + position: relative; + overflow: hidden; + z-index: 1; + background-image: url('@/assets/images/themes/christmas/titlebar__bg.jpg'); + background-size: cover; + + &::before { + content: ''; + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.5); + z-index: -1; } + } + + .preloader__road { + background-image: url('@/assets/images/themes/christmas/christmas-ground.png'); + } - .custom-button{ - position: relative; - z-index: 1; + .custom-button { + position: relative; + z-index: 1; - &::before { - content: ''; - position: absolute; - inset: 0; - background-image: url("@/assets/images/themes/christmas/snow.png"); - background-position: -60% 24%; - background-size: 60%; - background-repeat: no-repeat; - z-index: -1; - border-radius: 6px; - opacity: 0.3; - } + &::before { + content: ''; + position: absolute; + inset: 0; + background-image: url('@/assets/images/themes/christmas/snow.png'); + background-position: -60% 24%; + background-size: 60%; + background-repeat: no-repeat; + z-index: -1; + border-radius: 6px; + opacity: 0.3; } -} \ No newline at end of file + } +} diff --git a/packages/client/src/store/reducers/theme-reducer.ts b/packages/client/src/store/reducers/theme-reducer.ts index 9c2d305..9a2bef4 100644 --- a/packages/client/src/store/reducers/theme-reducer.ts +++ b/packages/client/src/store/reducers/theme-reducer.ts @@ -32,8 +32,6 @@ const slice = createSlice({ initialState, reducers: { setTheme(state, action: PayloadAction) { - console.log('setTheme', action.payload) - state.themeAlias = action.payload }, }, @@ -101,12 +99,11 @@ export const updateTheme = createAsyncThunk< { rejectValue: string } >('UserTheme/updateTheme', async (newThemeAlias: string, thunkAPI) => { try { - const state = thunkAPI.getState() as RootState - const user = state.authReducer.user + const userId = window.sessionStorage.getItem('userId') - if (user && user.id) { + if (userId) { const response = await userThemeApi.setTheme( - parseFloat(user.id), + parseFloat(userId), newThemeAlias ) diff --git a/packages/server/tsconfig.server.json b/packages/server/tsconfig.server.json index 96d7850..56c10ab 100644 --- a/packages/server/tsconfig.server.json +++ b/packages/server/tsconfig.server.json @@ -1,13 +1,15 @@ { "compilerOptions": { "outDir": "ts-dist", + "rootDir": "./", "composite": true, "target": "es2019", "module": "commonjs", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "lib": ["es2019", "DOM"], - "skipLibCheck": true + "skipLibCheck": true, + "types": ["node"] }, "include": [ "index.ts", @@ -20,5 +22,6 @@ "routes/**/*.ts", "utils/**/*.ts", "types/**/*.ts" - ] + ], + "exclude": ["ts-dist"] }