diff --git a/package.json b/package.json index 1789fb4..39e62d5 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,15 @@ "preview": "vite preview" }, "dependencies": { + "@reduxjs/toolkit": "^1.9.5", + "@types/react-redux": "^7.1.26", "axios": "^1.5.0", + "moment": "^2.29.4", "preact": "^10.16.0", + "react-redux": "^8.1.2", "react-router-dom": "^6.16.0", + "redux-persist": "^6.0.0", + "redux-thunk": "^2.4.2", "yet-another-react-lightbox": "^3.12.2" }, "devDependencies": { diff --git a/src/app.tsx b/src/app.tsx index c3a199d..fa5c684 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -4,26 +4,36 @@ import './app.css' import { DefaultLayout } from './layouts' import routes from './routes' import "yet-another-react-lightbox/styles.css"; +import { Login } from './pages' +import { Provider } from 'react-redux' +import { persistore, store } from './store/config' +import { PersistGate } from 'redux-persist/integration/react' export function App() { return ( <> - - - }> - {routes.map(({ path, name, element}) => ( - <> - - - ))} - - - + + + + + + } /> + }> + {routes.map(({ path, name, element}) => ( + <> + + + ))} + + + + + ) } diff --git a/src/constants/actions.ts b/src/constants/actions.ts new file mode 100644 index 0000000..f2228ff --- /dev/null +++ b/src/constants/actions.ts @@ -0,0 +1 @@ +export const LOGOUT = 'LOGOUT'; \ No newline at end of file diff --git a/src/features/auth/authSlice/authSlice.ts b/src/features/auth/authSlice/authSlice.ts new file mode 100644 index 0000000..5235731 --- /dev/null +++ b/src/features/auth/authSlice/authSlice.ts @@ -0,0 +1,20 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const initialState = {} + +const authSlice = createSlice({ + name: 'auth', + initialState, + reducers: { + authAdded(state, action) { + const current_user = action.payload; + let newState = { ...state } + newState = current_user + return newState + } + } +}) + +export const { authAdded } = authSlice.actions; + +export default authSlice.reducer; \ No newline at end of file diff --git a/src/features/auth/authSlice/type.ts b/src/features/auth/authSlice/type.ts new file mode 100644 index 0000000..6598389 --- /dev/null +++ b/src/features/auth/authSlice/type.ts @@ -0,0 +1,14 @@ +export interface IUser { + id: Number, + email: String, + username: String, + avatar_picture: String, + banned_at: NullValueRes<"Time", String>, + banned_until: NullValueRes<"Time", String>, + ban_reason: String, + is_permaban: boolean, + is_admin: boolean, + is_critics: boolean, + is_verfied: boolean, + social_media: NullValueRes<"RawMessage", any> +} \ No newline at end of file diff --git a/src/features/index.ts b/src/features/index.ts new file mode 100644 index 0000000..0374f74 --- /dev/null +++ b/src/features/index.ts @@ -0,0 +1,5 @@ +import authSlice from "./auth/authSlice/authSlice"; + +export { + authSlice +} \ No newline at end of file diff --git a/src/reducers/index.ts b/src/reducers/index.ts new file mode 100644 index 0000000..2806075 --- /dev/null +++ b/src/reducers/index.ts @@ -0,0 +1,18 @@ +import { combineReducers } from "@reduxjs/toolkit"; +import { LOGOUT } from "../constants/actions"; +import { authSlice } from "../features"; + +const appReducer = combineReducers({ + auth: authSlice +}); + +const rootReducer = (state: any, action: any) => { + if (action.type === LOGOUT) { + // remove token + state = undefined + } + + return appReducer(state, action); +} + +export default rootReducer; diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 7608f0a..8984274 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -4,7 +4,8 @@ import { Home, LocationDetail, NewsEvent, - Story + Story, + Login } from '../pages'; const routes = [ diff --git a/src/store/config.ts b/src/store/config.ts new file mode 100644 index 0000000..0a77bdd --- /dev/null +++ b/src/store/config.ts @@ -0,0 +1,25 @@ +import { applyMiddleware, createStore, compose } from '@reduxjs/toolkit' +import storage from 'redux-persist/lib/storage' +import persistReducer from 'redux-persist/es/persistReducer'; +import rootReducer from '../reducers'; +import thunk from 'redux-thunk'; +import { persistStore } from 'redux-persist'; + +const composeEnhancers = (window as any)['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] as typeof compose || compose; + +const persistConfig = { + key: 'root', + blacklist: [], + whitelist: [ + "auth" + ], + storage +} + +const persistedReducer = persistReducer(persistConfig, rootReducer); + +export type RootState = ReturnType + +export const store = createStore(persistedReducer, composeEnhancers(applyMiddleware(thunk))) + +export const persistore = persistStore(store) diff --git a/src/store/type.ts b/src/store/type.ts new file mode 100644 index 0000000..8b2dae1 --- /dev/null +++ b/src/store/type.ts @@ -0,0 +1,6 @@ +import { IUser } from "../features/auth/authSlice/type"; +import { RootState } from "./config"; + +export interface UserRootState extends RootState { + auth: IUser +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8e752d9..630a6d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -197,6 +197,13 @@ "@babel/plugin-syntax-jsx" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" + integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" @@ -434,6 +441,16 @@ "@prefresh/utils" "^1.2.0" "@rollup/pluginutils" "^4.2.1" +"@reduxjs/toolkit@^1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.9.5.tgz#d3987849c24189ca483baa7aa59386c8e52077c4" + integrity sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ== + dependencies: + immer "^9.0.21" + redux "^4.2.1" + redux-thunk "^2.4.2" + reselect "^4.1.8" + "@remix-run/router@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.9.0.tgz#9033238b41c4cbe1e961eccb3f79e2c588328cf6" @@ -447,6 +464,48 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#dc1e9ded53375d37603c479cc12c693b0878aa2a" + integrity sha512-YIQtIg4PKr7ZyqNPZObpxfHsHEmuB8dXCxd6qVcGuQVDK2bpsF7bYNnBJ4Nn7giuACZg+WewExgrtAJ3XnA4Xw== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/prop-types@*": + version "15.7.6" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.6.tgz#bbf819813d6be21011b8f5801058498bec555572" + integrity sha512-RK/kBbYOQQHLYj9Z95eh7S6t7gq4Ojt/NT8HTk8bWVhA5DaF+5SMnxHKkP4gPNN3wAZkKP+VjAf0ebtYzf+fxg== + +"@types/react-redux@^7.1.26": + version "7.1.26" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.26.tgz#84149f5614e40274bb70fcbe8f7cae6267d548b1" + integrity sha512-UKPo7Cm7rswYU6PH6CmTNCRv5NYF3HrgKuHEYTK8g/3czYLrUux50gQ2pkxc9c7ZpQZi+PNhgmI8oNIRoiVIxg== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + +"@types/react@*": + version "18.2.22" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.22.tgz#abe778a1c95a07fa70df40a52d7300a40b949ccb" + integrity sha512-60fLTOLqzarLED2O3UQImc/lsNRgG0jE/a1mPW9KjMemY0LMITWEsbS4VvZ4p6rorEHd5YKxxmMKSDK505GHpA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -611,6 +670,11 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + debug@^4.1.0, debug@^4.3.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -788,6 +852,18 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +immer@^9.0.21: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -906,6 +982,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +moment@^2.29.4: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -1055,6 +1136,28 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-redux@^8.1.2: + version "8.1.2" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.2.tgz#9076bbc6b60f746659ad6d51cb05de9c5e1e9188" + integrity sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw== + dependencies: + "@babel/runtime" "^7.12.1" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/use-sync-external-store" "^0.0.3" + hoist-non-react-statics "^3.3.2" + react-is "^18.0.0" + use-sync-external-store "^1.0.0" + react-router-dom@^6.16.0: version "6.16.0" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.16.0.tgz#86f24658da35eb66727e75ecbb1a029e33ee39d9" @@ -1084,6 +1187,33 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +redux-persist@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" + integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ== + +redux-thunk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" + integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== + +redux@^4.0.0, redux@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" + integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== + dependencies: + "@babel/runtime" "^7.9.2" + +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +reselect@^4.1.8: + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== + resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.2: version "1.22.4" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" @@ -1219,6 +1349,11 @@ update-browserslist-db@^1.0.11: escalade "^3.1.1" picocolors "^1.0.0" +use-sync-external-store@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"