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"