diff --git a/.prettierrc.yaml b/.prettierrc.yaml index f7433f3..7612d53 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -1,4 +1,4 @@ -printWidth: 80 +printWidth: 100 tabWidth: 2 useTabs: false semi: false diff --git a/src/components/protected-route/index.tsx b/src/components/protected-route/index.tsx index 9544f38..c0d617b 100644 --- a/src/components/protected-route/index.tsx +++ b/src/components/protected-route/index.tsx @@ -1,13 +1,40 @@ import { Navigate, Outlet, useLocation } from "react-router" 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) + + /** + * Retrieves the current location object from React Router. + */ const location = useLocation() 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 } + /** + * Renders the child routes if the user is unauthenticated. + */ return -} \ No newline at end of file +} diff --git a/src/main.tsx b/src/main.tsx index be6c36a..319db61 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,9 +2,9 @@ import { StrictMode } from "react" import { createRoot } from "react-dom/client" import { Provider } from "react-redux" import { BrowserRouter, Route, Routes } from "react-router" -import { store } from "@/store" +import store from "@/store" import "./index.css" -import { ProtectedRoute } from "@/components/protected-route" +import ProtectedRoute from "@/components/protected-route" createRoot(document.getElementById("root")!).render( diff --git a/src/plugin/datetime/index.ts b/src/plugin/datetime/index.ts index 2824e72..fdf3fef 100644 --- a/src/plugin/datetime/index.ts +++ b/src/plugin/datetime/index.ts @@ -3,8 +3,21 @@ import duration from "dayjs/plugin/duration" dayjs.extend(duration) +/** + * Dayjs with `Duration` plugin. + */ 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 } \ No newline at end of file diff --git a/src/store/auth-slice.ts b/src/store/auth-slice.ts index 13114fa..c3dbe08 100644 --- a/src/store/auth-slice.ts +++ b/src/store/auth-slice.ts @@ -1,20 +1,63 @@ import { createSlice } from "@reduxjs/toolkit" +/** + * Defines the structure of the authentication state within the Redux store. + */ interface AuthState { + /** + * Indicates whether a user is currently authenticated. + * @type {boolean} + */ isAuthenticated: boolean } +/** + * The initial state for the authentication slice. + * + * By default, the user is considered unauthenticated. + * + * @constant + * @type {AuthState} + */ const initialState: AuthState = { 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({ + /** + * The name of the slice, used to generate action types. + * @type {string} + */ name: "auth", + /** + * The initial state for this slice. + * @type {AuthState} + */ initialState, + /** + * An object of reducer functions. Currently empty, meaning no actions are explicitly defined for + * state modification within this slice. + * @type {object} + */ reducers: { } }) // 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 \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts index 5817065..7dff401 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -2,15 +2,23 @@ import { configureStore } from "@reduxjs/toolkit" import { useDispatch, useSelector } from "react-redux" 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 @reduxjs/toolkit. It combines various slice reducers into + * a single root redux. + */ +const store = configureStore({ reducer: { auth: authReducer, }, }) +export default store export type RootState = ReturnType export type AppDispatch = typeof store.dispatch export type AppStore = typeof store export const useAppDispatch = useDispatch.withTypes() -export const useAppSelector = useSelector.withTypes() \ No newline at end of file +export const useAppSelector = useSelector.withTypes()