Add useSubscribeGuard hook to manage subscription access and loading state

This commit is contained in:
seaznCode 2026-05-05 22:10:15 +02:00
parent 6441a39e71
commit ba13f378d7

View 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',
};
}