diff --git a/src/app/admin/dashboard/page.tsx b/src/app/admin/dashboard/page.tsx
index 0d92218..c7aecb2 100644
--- a/src/app/admin/dashboard/page.tsx
+++ b/src/app/admin/dashboard/page.tsx
@@ -3,14 +3,17 @@
import Background from '@/components/staff/qr/background';
import Top from './_components/top';
import Detail from './_components/detail';
+import Protect from '@/components/protect';
export default function Page() {
return (
-
+
+
+
);
}
diff --git a/src/app/staff/qr/page.tsx b/src/app/staff/qr/page.tsx
index 5e7b4b6..dba0abd 100644
--- a/src/app/staff/qr/page.tsx
+++ b/src/app/staff/qr/page.tsx
@@ -2,15 +2,18 @@ import Background from '@/components/staff/qr/background';
import TopPart from '@/components/staff/qr/toppart';
import Edit from '@/components/staff/qr/editbutton';
import QrButton from '@/components/staff/qr/qrbutton';
+import Protect from '@/components/protect';
export default function Home() {
return (
-
-
-
-
-
-
+
+
+
+
+
+
+
+
);
}
diff --git a/src/components/protect.tsx b/src/components/protect.tsx
new file mode 100644
index 0000000..892889c
--- /dev/null
+++ b/src/components/protect.tsx
@@ -0,0 +1,43 @@
+'use client';
+
+import { Role } from '@/const/role';
+import { useAuth } from '@/contexts/auth';
+import { useRouter } from 'next/navigation';
+import React from 'react';
+import Load from './loading/loading';
+import toast from 'react-hot-toast';
+
+interface ProtectProps {
+ roles: Role[];
+ children: React.ReactNode;
+ callBack?: string;
+}
+
+export default function Protect({
+ roles,
+ children,
+ callBack = '/',
+}: ProtectProps) {
+ const { user, isLoggingIn, isInitialized } = useAuth();
+ const router = useRouter();
+
+ if (isLoggingIn || !isInitialized) {
+ return ;
+ }
+
+ if (!user || !roles.includes(user.role)) {
+ toast.error('You cannot access this page');
+ router.push(callBack);
+ return ;
+ }
+
+ return children;
+}
+
+function Loading() {
+ return (
+
+
+
+ );
+}
diff --git a/src/components/staff/qr/editbutton.tsx b/src/components/staff/qr/editbutton.tsx
index ecc7291..6d2d91e 100644
--- a/src/components/staff/qr/editbutton.tsx
+++ b/src/components/staff/qr/editbutton.tsx
@@ -5,7 +5,7 @@ import Link from 'next/link';
export default function Edit() {
return (
diff --git a/src/contexts/auth.tsx b/src/contexts/auth.tsx
index 62759b5..cb04290 100644
--- a/src/contexts/auth.tsx
+++ b/src/contexts/auth.tsx
@@ -34,6 +34,7 @@ interface AuthState {
isLoggingIn: boolean;
isRegistering: boolean;
isEditing: boolean;
+ isInitialized: boolean;
login(): Promise>;
edit(req: EditReq): Promise>;
register(req: RegisterReq): Promise>;
@@ -54,6 +55,7 @@ export default function AuthProvider({ children }: { children: ReactNode }) {
isLoggingIn: false,
isRegistering: false,
isEditing: false,
+ isInitialized: false,
});
const { client } = useLiff();
@@ -71,15 +73,16 @@ export default function AuthProvider({ children }: { children: ReactNode }) {
return { success: false, error: error };
}
+ console.log('start login');
set('isLoggingIn', true);
const loginResp = await sendLogin(userId);
if (loginResp.success) {
set('token', loginResp.result);
- set('isLoggedIn', true);
} else {
console.error('login failed:', loginResp.error);
set('loginError', loginResp.error);
+ set('isLoggingIn', false);
return loginResp;
}
@@ -89,10 +92,11 @@ export default function AuthProvider({ children }: { children: ReactNode }) {
} else {
console.error('get user failed:', UserResp.error);
set('loginError', UserResp.error);
+ set('isLoggingIn', false);
return UserResp;
}
- set('isLoggedIn', false);
+ set('isLoggingIn', false);
return {
success: true,
@@ -136,6 +140,7 @@ export default function AuthProvider({ children }: { children: ReactNode }) {
useEffect(() => {
login();
+ set('isInitialized', true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);