docs: add jsdoc
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
printWidth: 80
|
printWidth: 100
|
||||||
tabWidth: 2
|
tabWidth: 2
|
||||||
useTabs: false
|
useTabs: false
|
||||||
semi: false
|
semi: false
|
||||||
|
|||||||
@@ -1,13 +1,40 @@
|
|||||||
import { Navigate, Outlet, useLocation } from "react-router"
|
import { Navigate, Outlet, useLocation } from "react-router"
|
||||||
import { useAppSelector } from "@/store"
|
import { useAppSelector } from "@/store"
|
||||||
|
|
||||||
export const ProtectedRoute = () => {
|
/**
|
||||||
|
* Renders child routes if the user is unauthenticated, otherwise redirects authenticated users to
|
||||||
|
* the root path.
|
||||||
|
*
|
||||||
|
* This component's logic allows unauthenticated users to access nested routes rendered
|
||||||
|
* via `Outlet`. Conversely, if a user is authenticated, they are redirected to the application's
|
||||||
|
* root path (`""`). This behaviour is inverse to the typical implementation of a 'protected route',
|
||||||
|
* which usually grants access to authenticated users and redirects unauthenticated users to a
|
||||||
|
* login page.
|
||||||
|
*/
|
||||||
|
export default function ProtectedRoute() {
|
||||||
|
/**
|
||||||
|
* Retrieves the authentication status from the Redux store.
|
||||||
|
*/
|
||||||
const isAuthenticated = useAppSelector((state) => state.auth.isAuthenticated)
|
const isAuthenticated = useAppSelector((state) => state.auth.isAuthenticated)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the current location object from React Router.
|
||||||
|
*/
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
|
/**
|
||||||
|
* Redirects authenticated users to the application's root path (`""`).
|
||||||
|
*
|
||||||
|
* The redirection includes the current location's state, allowing the
|
||||||
|
* target route to know where the user was redirected from. The
|
||||||
|
* `replace` prop ensures the current history entry is replaced.
|
||||||
|
*/
|
||||||
return <Navigate to="" state={{ from: location }} replace />
|
return <Navigate to="" state={{ from: location }} replace />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the child routes if the user is unauthenticated.
|
||||||
|
*/
|
||||||
return <Outlet />
|
return <Outlet />
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,9 +2,9 @@ import { StrictMode } from "react"
|
|||||||
import { createRoot } from "react-dom/client"
|
import { createRoot } from "react-dom/client"
|
||||||
import { Provider } from "react-redux"
|
import { Provider } from "react-redux"
|
||||||
import { BrowserRouter, Route, Routes } from "react-router"
|
import { BrowserRouter, Route, Routes } from "react-router"
|
||||||
import { store } from "@/store"
|
import store from "@/store"
|
||||||
import "./index.css"
|
import "./index.css"
|
||||||
import { ProtectedRoute } from "@/components/protected-route"
|
import ProtectedRoute from "@/components/protected-route"
|
||||||
|
|
||||||
createRoot(document.getElementById("root")!).render(
|
createRoot(document.getElementById("root")!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
|
|||||||
@@ -3,8 +3,21 @@ import duration from "dayjs/plugin/duration"
|
|||||||
|
|
||||||
dayjs.extend(duration)
|
dayjs.extend(duration)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dayjs with `Duration` plugin.
|
||||||
|
*/
|
||||||
export default dayjs
|
export default dayjs
|
||||||
|
|
||||||
const formatDatetime = (datetime: string) => dayjs(datetime).format("YYYY-MM-DD HH:mm:ss")
|
/**
|
||||||
|
* Formats a given datetime string into a standardised "YYYY-MM-DD HH:mm:ss" format.
|
||||||
|
*
|
||||||
|
* This function utilises the [dayjs](https://day.js.org/) library for parsing and formatting.
|
||||||
|
*
|
||||||
|
* @param {string} datetime the datetime string to format
|
||||||
|
* @returns {string} the formatted datetime string in `YYYY-MM-DD HH:mm:ss` format
|
||||||
|
*/
|
||||||
|
function formatDatetime (datetime: string): string {
|
||||||
|
return dayjs(datetime).format("YYYY-MM-DD HH:mm:ss")
|
||||||
|
}
|
||||||
|
|
||||||
export { formatDatetime }
|
export { formatDatetime }
|
||||||
@@ -1,20 +1,63 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit"
|
import { createSlice } from "@reduxjs/toolkit"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the structure of the authentication state within the Redux store.
|
||||||
|
*/
|
||||||
interface AuthState {
|
interface AuthState {
|
||||||
|
/**
|
||||||
|
* Indicates whether a user is currently authenticated.
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
isAuthenticated: boolean
|
isAuthenticated: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initial state for the authentication slice.
|
||||||
|
*
|
||||||
|
* By default, the user is considered unauthenticated.
|
||||||
|
*
|
||||||
|
* @constant
|
||||||
|
* @type {AuthState}
|
||||||
|
*/
|
||||||
const initialState: AuthState = {
|
const initialState: AuthState = {
|
||||||
isAuthenticated: false
|
isAuthenticated: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Redux Toolkit slice for managing authentication-related state.
|
||||||
|
*
|
||||||
|
* This slice includes the reducer, actions, and initial state for the authentication feature.
|
||||||
|
* Currently, it only defines the initial state and no specific reducers, meaning it only
|
||||||
|
* holds the `isAuthenticated` flag.
|
||||||
|
*/
|
||||||
const authSlice = createSlice({
|
const authSlice = createSlice({
|
||||||
|
/**
|
||||||
|
* The name of the slice, used to generate action types.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
name: "auth",
|
name: "auth",
|
||||||
|
/**
|
||||||
|
* The initial state for this slice.
|
||||||
|
* @type {AuthState}
|
||||||
|
*/
|
||||||
initialState,
|
initialState,
|
||||||
|
/**
|
||||||
|
* An object of reducer functions. Currently empty, meaning no actions are explicitly defined for
|
||||||
|
* state modification within this slice.
|
||||||
|
* @type {object}
|
||||||
|
*/
|
||||||
reducers: {
|
reducers: {
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// export const { } = authSlice.actions
|
// export const { } = authSlice.actions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reducer function for the authentication slice.
|
||||||
|
*
|
||||||
|
* This is the default export and should be combined with other reducers in the Redux store.
|
||||||
|
*
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
export default authSlice.reducer
|
export default authSlice.reducer
|
||||||
+10
-2
@@ -2,15 +2,23 @@ import { configureStore } from "@reduxjs/toolkit"
|
|||||||
import { useDispatch, useSelector } from "react-redux"
|
import { useDispatch, useSelector } from "react-redux"
|
||||||
import authReducer from "./auth-slice.ts"
|
import authReducer from "./auth-slice.ts"
|
||||||
|
|
||||||
export const store = configureStore({
|
/**
|
||||||
|
* The Redux store instance for the application.
|
||||||
|
*
|
||||||
|
* This store is configured using [`configureStore`](https://redux-toolkit.js.org/api/configureStore)
|
||||||
|
* from <code>@reduxjs/toolkit</code>. It combines various slice reducers into
|
||||||
|
* a single root redux.
|
||||||
|
*/
|
||||||
|
const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
auth: authReducer,
|
auth: authReducer,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export default store
|
||||||
export type RootState = ReturnType<typeof store.getState>
|
export type RootState = ReturnType<typeof store.getState>
|
||||||
export type AppDispatch = typeof store.dispatch
|
export type AppDispatch = typeof store.dispatch
|
||||||
export type AppStore = typeof store
|
export type AppStore = typeof store
|
||||||
|
|
||||||
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
|
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
|
||||||
export const useAppSelector = useSelector.withTypes<RootState>()
|
export const useAppSelector = useSelector.withTypes<RootState>()
|
||||||
|
|||||||
Reference in New Issue
Block a user