mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 20:40:55 +00:00
user management ui
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
ReactNode,
|
||||
} from "react";
|
||||
import Cookies from "js-cookie";
|
||||
import { MeDto } from "@/shared/dto/user/meDto";
|
||||
|
||||
// ----- TYPES -----
|
||||
export interface Role {
|
||||
id: string;
|
||||
key: string;
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
user: MeDto | null;
|
||||
loading: boolean;
|
||||
setUser: (user: MeDto | null) => void;
|
||||
selectedPositionId: string | null;
|
||||
setSelectedPositionId: (id: string | null) => void;
|
||||
showOtpModal: boolean;
|
||||
setShowOtpModal: (show: boolean) => void;
|
||||
rememberMePreference: boolean;
|
||||
setRememberMePreference: (rememberMe: boolean) => void;
|
||||
}
|
||||
|
||||
// ----- CONTEXT -----
|
||||
const AuthContext = createContext<AuthContextType>({
|
||||
user: null,
|
||||
loading: true,
|
||||
setUser: () => {},
|
||||
selectedPositionId: null,
|
||||
setSelectedPositionId: () => {},
|
||||
showOtpModal: false,
|
||||
setShowOtpModal: () => {},
|
||||
rememberMePreference: false,
|
||||
setRememberMePreference: () => {},
|
||||
});
|
||||
|
||||
// ----- PROVIDER -----
|
||||
export const AuthProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [user, setUser] = useState<MeDto | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedPositionId, setSelectedPositionId] = useState<string | null>(
|
||||
null
|
||||
);
|
||||
const [showOtpModal, setShowOtpModal] = useState(false);
|
||||
const [rememberMePreference, setRememberMePreference] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const cookieUser = Cookies.get("auth-user");
|
||||
const positionId = Cookies.get("selected-position-id");
|
||||
|
||||
if (cookieUser) {
|
||||
try {
|
||||
const parsed = JSON.parse(cookieUser);
|
||||
setUser(parsed);
|
||||
if (positionId) setSelectedPositionId(positionId);
|
||||
} catch (e) {
|
||||
console.error("Invalid user cookie");
|
||||
}
|
||||
}
|
||||
setLoading(false);
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// sessionStorage.setItem("tabActive", "true");
|
||||
|
||||
// const handleTabClose = (event: BeforeUnloadEvent) => {
|
||||
// const [nav] = performance.getEntriesByType(
|
||||
// "navigation"
|
||||
// ) as PerformanceNavigationTiming[];
|
||||
|
||||
// // If page was reloaded, don't remove tokens
|
||||
// if (nav && nav.type === "reload") return;
|
||||
|
||||
// const rememberMe = JSON.parse(
|
||||
// localStorage.getItem("rememberMe") || "false"
|
||||
// );
|
||||
// if (!rememberMe) {
|
||||
// Cookies.remove("auth-token");
|
||||
// Cookies.remove("refresh-token");
|
||||
// sessionStorage.removeItem("auth-token");
|
||||
// setUser(null);
|
||||
// }
|
||||
// };
|
||||
|
||||
// window.addEventListener("beforeunload", handleTabClose);
|
||||
// return () => window.removeEventListener("beforeunload", handleTabClose);
|
||||
// }, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedPositionId) {
|
||||
Cookies.set("selected-position-id", selectedPositionId);
|
||||
}
|
||||
}, [selectedPositionId]);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{
|
||||
user,
|
||||
loading,
|
||||
setUser,
|
||||
selectedPositionId,
|
||||
setSelectedPositionId,
|
||||
showOtpModal,
|
||||
setShowOtpModal,
|
||||
rememberMePreference,
|
||||
setRememberMePreference,
|
||||
}}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// ----- HOOK -----
|
||||
export const useAuth = () => useContext(AuthContext);
|
||||
@@ -0,0 +1,91 @@
|
||||
import React, { createContext, useContext, useState, useCallback } from "react";
|
||||
|
||||
/**
|
||||
* Context for managing breadcrumb labels
|
||||
* Allows components to register human-readable labels for IDs
|
||||
*/
|
||||
|
||||
interface BreadcrumbLabel {
|
||||
id: string;
|
||||
label: string;
|
||||
type: "year" | "plan" | "position" | "employee" | "service" | "other";
|
||||
}
|
||||
|
||||
interface BreadcrumbContextType {
|
||||
labels: Map<string, BreadcrumbLabel>;
|
||||
registerLabel: (id: string, label: string, type: BreadcrumbLabel["type"]) => void;
|
||||
getLabel: (id: string) => string | null;
|
||||
clearLabels: () => void;
|
||||
}
|
||||
|
||||
const BreadcrumbContext = createContext<BreadcrumbContextType | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
export const BreadcrumbProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [labels, setLabels] = useState<Map<string, BreadcrumbLabel>>(
|
||||
new Map()
|
||||
);
|
||||
|
||||
const registerLabel = useCallback(
|
||||
(id: string, label: string, type: BreadcrumbLabel["type"]) => {
|
||||
setLabels((prev) => {
|
||||
const newMap = new Map(prev);
|
||||
newMap.set(id, { id, label, type });
|
||||
return newMap;
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const getLabel = useCallback(
|
||||
(id: string): string | null => {
|
||||
return labels.get(id)?.label || null;
|
||||
},
|
||||
[labels]
|
||||
);
|
||||
|
||||
const clearLabels = useCallback(() => {
|
||||
setLabels(new Map());
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<BreadcrumbContext.Provider
|
||||
value={{ labels, registerLabel, getLabel, clearLabels }}>
|
||||
{children}
|
||||
</BreadcrumbContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useBreadcrumbContext = () => {
|
||||
const context = useContext(BreadcrumbContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useBreadcrumbContext must be used within BreadcrumbProvider"
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to register a breadcrumb label when a component mounts
|
||||
* Usage in components:
|
||||
*
|
||||
* const { data: planData } = usePlan(planId);
|
||||
* useBreadcrumbLabel(planId, localizedName(planData?.name), "plan");
|
||||
*/
|
||||
export const useBreadcrumbLabel = (
|
||||
id: string | undefined,
|
||||
label: string | undefined,
|
||||
type: BreadcrumbLabel["type"]
|
||||
) => {
|
||||
const { registerLabel } = useBreadcrumbContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (id && label) {
|
||||
registerLabel(id, label, type);
|
||||
}
|
||||
}, [id, label, type, registerLabel]);
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Permission } from "@/shared/dto/user/meDto";
|
||||
import React, {
|
||||
createContext,
|
||||
FC,
|
||||
ReactNode,
|
||||
useContext,
|
||||
useMemo,
|
||||
} from "react";
|
||||
|
||||
type PermContext = { permissions: string[]; permissionObjects?: Permission[] };
|
||||
const PermissionContext = createContext<PermContext>({ permissions: [] });
|
||||
|
||||
interface PermissionProviderProps {
|
||||
permissions?: Permission[];
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const PermissionProvider: FC<PermissionProviderProps> = ({
|
||||
permissions,
|
||||
children,
|
||||
}) => {
|
||||
const permissionKeys = useMemo(
|
||||
() => permissions?.map((p) => p.key),
|
||||
[permissions]
|
||||
);
|
||||
|
||||
return (
|
||||
<PermissionContext.Provider value={{ permissions: permissionKeys || [],permissionObjects:permissions }}>
|
||||
{children}
|
||||
</PermissionContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const usePermissions = () => useContext(PermissionContext);
|
||||
@@ -0,0 +1,28 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
import { useUnit } from '@/user-management/hooks/useUnit';
|
||||
|
||||
// Define the context type to match the return type of useUnit hook
|
||||
type UnitContextType = ReturnType<typeof useUnit> | undefined;
|
||||
|
||||
// Create context with undefined as default
|
||||
const UnitContext = createContext<UnitContextType>(undefined);
|
||||
|
||||
// Provider component
|
||||
export const UnitProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
const unitQuery = useUnit(); // or whatever hook/query you're using to get units
|
||||
|
||||
return (
|
||||
<UnitContext.Provider value={unitQuery}>
|
||||
{children}
|
||||
</UnitContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// Custom hook to use the context
|
||||
export const useUnitContext = () => {
|
||||
const context = useContext(UnitContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useUnitContext must be used within a UnitProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
// src/context/UserContext.tsx
|
||||
import { createContext, useContext } from "react";
|
||||
import { useAuthUser } from "../hooks/useAuthUser";
|
||||
|
||||
const UserContext = createContext<any>(null);
|
||||
|
||||
export const UserProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const { userDetails, isLoading } = useAuthUser();
|
||||
// if (isLoading) return <div>Loading...</div>;
|
||||
return (
|
||||
<UserContext.Provider value={userDetails}>{children}</UserContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useUser = () => useContext(UserContext);
|
||||
Reference in New Issue
Block a user