fix(auth): sync navbar user after self admin edit
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
Keep the logged-in user context and cookie in sync when an admin updates their own profile so the navbar reflects name changes immediately. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,6 +25,7 @@ interface UserContextType {
|
|||||||
setAuthState: (data: ILoginResponse) => void;
|
setAuthState: (data: ILoginResponse) => void;
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
setUser: Dispatch<SetStateAction<IUser | null>>;
|
setUser: Dispatch<SetStateAction<IUser | null>>;
|
||||||
|
syncCurrentUser: (updates: Partial<IUser>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserContext = createContext<UserContextType | undefined>(undefined);
|
const UserContext = createContext<UserContextType | undefined>(undefined);
|
||||||
@@ -99,6 +100,16 @@ export const UserProvider: React.FC<UserProviderProps> = ({ children }) => {
|
|||||||
Cookies.set(COOKIE_KEYS.user, JSON.stringify(data.user));
|
Cookies.set(COOKIE_KEYS.user, JSON.stringify(data.user));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const syncCurrentUser = useCallback((updates: Partial<IUser>) => {
|
||||||
|
setUser((prev) => {
|
||||||
|
if (!prev) return prev;
|
||||||
|
|
||||||
|
const next = { ...prev, ...updates };
|
||||||
|
Cookies.set(COOKIE_KEYS.user, JSON.stringify(next));
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
user,
|
user,
|
||||||
@@ -108,8 +119,9 @@ export const UserProvider: React.FC<UserProviderProps> = ({ children }) => {
|
|||||||
setAuthState,
|
setAuthState,
|
||||||
logout,
|
logout,
|
||||||
setUser,
|
setUser,
|
||||||
|
syncCurrentUser,
|
||||||
}),
|
}),
|
||||||
[user, accessToken, isLoading, setAuthState, logout, setUser],
|
[user, accessToken, isLoading, setAuthState, logout, setUser, syncCurrentUser],
|
||||||
);
|
);
|
||||||
|
|
||||||
return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
|
return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { API_ENDPOINTS, userService } from "@/lib/api";
|
import { useUser } from "@/contexts";
|
||||||
|
import { API_ENDPOINTS, ICreateAdminCredentials, userService } from "@/lib/api";
|
||||||
import {
|
import {
|
||||||
useInfiniteQuery,
|
useInfiniteQuery,
|
||||||
useMutation,
|
useMutation,
|
||||||
@@ -9,6 +10,11 @@ import { useRouter } from "next/navigation";
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
|
const toCurrentUserUpdates = ({
|
||||||
|
password: _password,
|
||||||
|
...profile
|
||||||
|
}: ICreateAdminCredentials) => profile;
|
||||||
|
|
||||||
export const useDeleteAdmin = (onSuccessCallback: () => void) => {
|
export const useDeleteAdmin = (onSuccessCallback: () => void) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const mutationKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, "delete"], []);
|
const mutationKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, "delete"], []);
|
||||||
@@ -45,6 +51,7 @@ export const useCreateAdmin = () => {
|
|||||||
export const useUpdateAdmin = (id: string) => {
|
export const useUpdateAdmin = (id: string) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { user, syncCurrentUser } = useUser();
|
||||||
const mutationKey = useMemo(
|
const mutationKey = useMemo(
|
||||||
() => [API_ENDPOINTS.USER.ADMINS, "update", id],
|
() => [API_ENDPOINTS.USER.ADMINS, "update", id],
|
||||||
[id],
|
[id],
|
||||||
@@ -52,7 +59,11 @@ export const useUpdateAdmin = (id: string) => {
|
|||||||
return useMutation({
|
return useMutation({
|
||||||
mutationKey,
|
mutationKey,
|
||||||
mutationFn: userService.updateAdmin,
|
mutationFn: userService.updateAdmin,
|
||||||
onSuccess: (response) => {
|
onSuccess: (response, { id: adminId, credentials }) => {
|
||||||
|
if (user?.id === adminId) {
|
||||||
|
syncCurrentUser(toCurrentUserUpdates(credentials));
|
||||||
|
}
|
||||||
|
|
||||||
toast.success(response);
|
toast.success(response);
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: [API_ENDPOINTS.USER.ADMINS],
|
queryKey: [API_ENDPOINTS.USER.ADMINS],
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const useProfileQuery = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const useUpdateProfileQuery = () => {
|
export const useUpdateProfileQuery = () => {
|
||||||
const { setUser } = useUser();
|
const { syncCurrentUser } = useUser();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const mutationKey = useMemo(
|
const mutationKey = useMemo(
|
||||||
() => [API_ENDPOINTS.PROFILE.UPDATE, "UPDATE_USER_PROFILE"],
|
() => [API_ENDPOINTS.PROFILE.UPDATE, "UPDATE_USER_PROFILE"],
|
||||||
@@ -28,7 +28,7 @@ export const useUpdateProfileQuery = () => {
|
|||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: [API_ENDPOINTS.PROFILE.READ, "CURRENT_USER_PROFILE"],
|
queryKey: [API_ENDPOINTS.PROFILE.READ, "CURRENT_USER_PROFILE"],
|
||||||
});
|
});
|
||||||
setUser(response);
|
syncCurrentUser(response);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user