EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
page.tsx
Go to the documentation of this file.
1'use client';
2
3import { useEffect, useState, Suspense } from 'react';
4import { useRouter, useSearchParams } from 'next/navigation';
5import Link from 'next/link';
6import { useStore } from '@/contexts/StoreContext';
7
8function UnauthorizedPageContent() {
9 const router = useRouter();
10 const searchParams = useSearchParams();
11 const { session, logout } = useStore();
12 const [reason, setReason] = useState('');
13 const [attemptedRoute, setAttemptedRoute] = useState('');
14
15 useEffect(() => {
16 const reasonParam = searchParams.get('reason');
17 const routeParam = searchParams.get('route');
18
19 if (reasonParam) {
20 setReason(reasonParam);
21 }
22 if (routeParam) {
23 setAttemptedRoute(routeParam);
24 }
25 }, [searchParams]);
26
27 const getMessage = () => {
28 switch (reason) {
29 case 'store-required':
30 return {
31 title: 'Store Login Required',
32 description: 'This page requires you to be logged into a retail store location.',
33 explanation: 'POS functions (Sales, Returns) are only available when logged into a specific store like Cowra, Griffith, or Murwillumbah.',
34 action: 'Please logout and login to a retail store to access this feature.'
35 };
36 case 'management-required':
37 return {
38 title: 'Management Portal Required',
39 description: 'This page is only available in the management portal.',
40 explanation: 'Reports and system settings are only accessible when logged into the IIG Management Portal.',
41 action: 'Please logout and login to the management portal to access this feature.'
42 };
43 default:
44 return {
45 title: 'Access Denied',
46 description: 'You do not have permission to access this page.',
47 explanation: 'Your current role and login location do not grant access to this resource.',
48 action: 'Please contact your system administrator if you believe this is an error.'
49 };
50 }
51 };
52
53 const message = getMessage();
54
55 return (
56 <div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-red-50 to-orange-100 dark:from-gray-900 dark:to-gray-800 p-4">
57 <div className="max-w-2xl w-full space-y-6 p-8 bg-white dark:bg-gray-800 rounded-xl shadow-2xl">
58 {/* Icon */}
59 <div className="flex justify-center">
60 <div className="w-20 h-20 bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center">
61 <svg className="w-10 h-10 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
62 <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
63 </svg>
64 </div>
65 </div>
66
67 {/* Title */}
68 <div className="text-center">
69 <h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-2">
70 {message.title}
71 </h1>
72 <p className="text-lg text-gray-600 dark:text-gray-400">
73 {message.description}
74 </p>
75 </div>
76
77 {/* Details */}
78 <div className="bg-gray-50 dark:bg-gray-700/50 rounded-lg p-6 space-y-4">
79 {/* Current Context */}
80 {session && (
81 <div className="space-y-2">
82 <h3 className="text-sm font-semibold text-gray-900 dark:text-white">Your Current Session:</h3>
83 <div className="space-y-1 text-sm text-gray-600 dark:text-gray-300">
84 <div className="flex items-center gap-2">
85 <span className="font-medium">User:</span>
86 <span>{session.user.name}</span>
87 <span className="px-2 py-0.5 bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 text-xs rounded capitalize">
88 {session.user.role}
89 </span>
90 </div>
91 {session.store && (
92 <>
93 <div className="flex items-center gap-2">
94 <span className="font-medium">Store:</span>
95 <span>{session.store.name}</span>
96 </div>
97 <div className="flex items-center gap-2">
98 <span className="font-medium">Type:</span>
99 {session.store.type === 'management' ? (
100 <span className="px-2 py-0.5 bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 text-xs rounded">
101 Management Portal
102 </span>
103 ) : (
104 <span className="px-2 py-0.5 bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300 text-xs rounded">
105 Retail Store
106 </span>
107 )}
108 </div>
109 </>
110 )}
111 </div>
112 </div>
113 )}
114
115 {attemptedRoute && (
116 <div className="space-y-2 pt-2 border-t border-gray-200 dark:border-gray-600">
117 <h3 className="text-sm font-semibold text-gray-900 dark:text-white">Attempted Route:</h3>
118 <div className="text-sm font-mono bg-white dark:bg-gray-800 px-3 py-2 rounded border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-300">
119 {attemptedRoute}
120 </div>
121 </div>
122 )}
123
124 {/* Explanation */}
125 <div className="space-y-2 pt-2 border-t border-gray-200 dark:border-gray-600">
126 <h3 className="text-sm font-semibold text-gray-900 dark:text-white">Why am I seeing this?</h3>
127 <p className="text-sm text-gray-600 dark:text-gray-400">
128 {message.explanation}
129 </p>
130 </div>
131
132 {/* Action */}
133 <div className="space-y-2 pt-2 border-t border-gray-200 dark:border-gray-600">
134 <h3 className="text-sm font-semibold text-gray-900 dark:text-white">What should I do?</h3>
135 <p className="text-sm text-gray-600 dark:text-gray-400">
136 {message.action}
137 </p>
138 </div>
139 </div>
140
141 {/* Actions */}
142 <div className="flex flex-col sm:flex-row gap-3">
143 <Link
144 href="/pages/home"
145 className="flex-1 px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 font-semibold text-center transition"
146 >
147 Go to Home
148 </Link>
149 <button
150 onClick={() => router.back()}
151 className="flex-1 px-6 py-3 bg-gray-300 text-gray-700 rounded-lg hover:bg-gray-400 font-semibold transition"
152 >
153 Go Back
154 </button>
155 <button
156 onClick={logout}
157 className="flex-1 px-6 py-3 bg-red-100 text-red-700 rounded-lg hover:bg-red-200 font-semibold transition"
158 >
159 Logout
160 </button>
161 </div>
162
163 {/* Help */}
164 <div className="text-center text-sm text-gray-500 dark:text-gray-400">
165 <p>Need help? Contact your system administrator</p>
166 </div>
167 </div>
168 </div>
169 );
170}
171
172export default function UnauthorizedPage() {
173 return (
174 <Suspense fallback={<div className="flex items-center justify-center min-h-screen">Loading...</div>}>
175 <UnauthorizedPageContent />
176 </Suspense>
177 );
178}