Add useSubscribeGuard hook to manage subscription access and loading state
This commit is contained in:
parent
6441a39e71
commit
ba13f378d7
107
src/app/coffee-abonnements/hooks/useSubscribeGuard.ts
Normal file
107
src/app/coffee-abonnements/hooks/useSubscribeGuard.ts
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
import useAuthStore from '../../store/authStore';
|
||||||
|
|
||||||
|
type GuardState = 'checking' | 'allowed' | 'redirecting';
|
||||||
|
|
||||||
|
function hasPermission(permsSrc: any, permission: string) {
|
||||||
|
if (Array.isArray(permsSrc)) {
|
||||||
|
return (
|
||||||
|
permsSrc.includes?.(permission) ||
|
||||||
|
permsSrc.some?.((perm: any) => perm?.name === permission || perm?.key === permission)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permsSrc && typeof permsSrc === 'object') {
|
||||||
|
return !!permsSrc[permission];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSubscribeGuard() {
|
||||||
|
const router = useRouter();
|
||||||
|
const user = useAuthStore((state) => state.user);
|
||||||
|
const isAuthReady = useAuthStore((state) => state.isAuthReady);
|
||||||
|
const accessToken = useAuthStore((state) => state.accessToken);
|
||||||
|
const refreshAuthToken = useAuthStore((state) => state.refreshAuthToken);
|
||||||
|
const [guardState, setGuardState] = useState<GuardState>('checking');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
const run = async () => {
|
||||||
|
if (!isAuthReady) {
|
||||||
|
if (!cancelled) setGuardState('checking');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
if (!cancelled) setGuardState('redirecting');
|
||||||
|
router.replace('/login');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uid = (user as any)?.id ?? (user as any)?._id ?? (user as any)?.userId;
|
||||||
|
if (!uid) {
|
||||||
|
if (!cancelled) setGuardState('redirecting');
|
||||||
|
router.replace('/');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tokenToUse = accessToken;
|
||||||
|
try {
|
||||||
|
if (!tokenToUse && refreshAuthToken) {
|
||||||
|
const ok = await refreshAuthToken();
|
||||||
|
if (ok) tokenToUse = useAuthStore.getState().accessToken;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('useSubscribeGuard.refreshAuthToken', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const base = process.env.NEXT_PUBLIC_API_BASE_URL || '';
|
||||||
|
const url = `${base}/api/users/${uid}/permissions`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(url, {
|
||||||
|
method: 'GET',
|
||||||
|
cache: 'no-store',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...(tokenToUse ? { Authorization: `Bearer ${tokenToUse}` } : {}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = await res.json().catch(() => null);
|
||||||
|
const permsSrc = body?.data?.permissions ?? body?.permissions ?? body;
|
||||||
|
const allowed = hasPermission(permsSrc, 'can_subscribe');
|
||||||
|
|
||||||
|
if (!allowed) {
|
||||||
|
if (!cancelled) setGuardState('redirecting');
|
||||||
|
router.replace('/');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cancelled) setGuardState('allowed');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('useSubscribeGuard.permissions', error);
|
||||||
|
if (!cancelled) setGuardState('redirecting');
|
||||||
|
router.replace('/');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
run();
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, [isAuthReady, user, accessToken, refreshAuthToken, router]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isChecking: guardState === 'checking',
|
||||||
|
isAllowed: guardState === 'allowed',
|
||||||
|
isRedirecting: guardState === 'redirecting',
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user