Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion view/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,25 @@ function DashboardPage() {
const availableWidgets = allWidgetLabels.filter((widget) => hiddenWidgets.includes(widget.id));

return (
<ResourceGuard resource="dashboard" action="read">
<ResourceGuard
resource="dashboard"
action="read"
loadingFallback={
// TODO: remove fallback post prod testing @zhravan
<PageLayout maxWidth="6xl" padding="md" spacing="lg">
<div className="space-y-4">
<Skeleton className="h-12 w-64" />
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Skeleton className="h-48 w-full rounded-xl md:col-span-2" />
<Skeleton className="h-64 w-full rounded-xl" />
<Skeleton className="h-64 w-full rounded-xl" />
<Skeleton className="h-64 w-full rounded-xl" />
<Skeleton className="h-64 w-full rounded-xl" />
</div>
</div>
</PageLayout>
}
>
<PageLayout maxWidth="6xl" padding="md" spacing="lg">
<DashboardHeader
hasCustomLayout={hasCustomLayout}
Expand Down
14 changes: 13 additions & 1 deletion view/app/register/hooks/use-register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import { useIsAdminRegisteredQuery } from '@/redux/services/users/authApi';
import { useAppDispatch } from '@/redux/hooks';
import { initializeAuth } from '@/redux/features/users/authSlice';

const registerSchema = (t: (key: translationKey, params?: Record<string, string>) => string) =>
z
Expand Down Expand Up @@ -36,6 +38,7 @@ type RegisterForm = z.infer<ReturnType<typeof registerSchema>>;
function useRegister() {
const { t } = useTranslation();
const router = useRouter();
const dispatch = useAppDispatch();
const [isLoading, setIsLoading] = useState(false);
const {
data: isAdminRegistered,
Expand Down Expand Up @@ -69,7 +72,16 @@ function useRegister() {
toast.error('Sign up is not allowed');
} else {
toast.success(t('auth.register.success'));
router.push('/auth');

try {
await (dispatch(initializeAuth() as any) as any).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove type casts and fix initializeAuth typing.

The double as any cast bypasses TypeScript's type safety and prevents catching type errors at compile time. initializeAuth() should return a properly typed async thunk.

Apply this diff to remove the casts:

-        await (dispatch(initializeAuth() as any) as any).unwrap();
+        await dispatch(initializeAuth()).unwrap();

If TypeScript errors occur after removing the casts, ensure initializeAuth is properly defined as an async thunk using createAsyncThunk from @reduxjs/toolkit.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await (dispatch(initializeAuth() as any) as any).unwrap();
await dispatch(initializeAuth()).unwrap();
🤖 Prompt for AI Agents
In view/app/register/hooks/use-register.ts around line 77, remove the double "as
any" casts on the dispatched initializeAuth call and make the types flow
correctly: change the call to await dispatch(initializeAuth()).unwrap() (no
casts) and then fix typing errors by ensuring initializeAuth is created with
createAsyncThunk from @reduxjs/toolkit and its payload/return types are
declared, and that your store's dispatch type (e.g., AppDispatch) is the
correctly-typed dispatch used in this hook so unwrap() and the await operate
with proper types.

} catch (authError) {
console.warn('Auth initialization after registration failed:', authError);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove console.warn from production code.

Console statements should be removed from production code, as noted in the developer checklist.

This will be addressed by the error handling fix in the previous comment, which replaces the console.warn with a toast notification and proper navigation.

🤖 Prompt for AI Agents
In view/app/register/hooks/use-register.ts around line 79, remove the
console.warn call and replace it with production-safe error handling: show the
user-facing toast notification (e.g., toast.error with a clear message), perform
the proper navigation flow as described in the previous comment, and, if
necessary, record the error via the app's logger (not console) for diagnostics;
ensure no console.* calls remain.

}

await new Promise((resolve) => setTimeout(resolve, 200));

router.push('/dashboard');
Comment on lines +76 to +84
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix error handling to prevent permission errors on auth failure.

If initializeAuth() fails, the user is still redirected to /dashboard, which can cause the permission errors this PR aims to fix. The error is logged but not handled.

Apply this diff to properly handle auth initialization failure:

       toast.success(t('auth.register.success'));

       try {
-        await (dispatch(initializeAuth() as any) as any).unwrap();
+        await dispatch(initializeAuth()).unwrap();
+        await new Promise((resolve) => setTimeout(resolve, 200));
+        router.push('/dashboard');
       } catch (authError) {
-        console.warn('Auth initialization after registration failed:', authError);
+        toast.error('Failed to initialize authentication. Please try logging in.');
+        router.push('/auth');
+        return;
       }
-
-      await new Promise((resolve) => setTimeout(resolve, 200));
-
-      router.push('/dashboard');
     }

This ensures that only successful auth initialization leads to the dashboard, while failures redirect to the auth page.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
await (dispatch(initializeAuth() as any) as any).unwrap();
} catch (authError) {
console.warn('Auth initialization after registration failed:', authError);
}
await new Promise((resolve) => setTimeout(resolve, 200));
router.push('/dashboard');
try {
await dispatch(initializeAuth()).unwrap();
await new Promise((resolve) => setTimeout(resolve, 200));
router.push('/dashboard');
} catch (authError) {
toast.error('Failed to initialize authentication. Please try logging in.');
router.push('/auth');
return;
}
🤖 Prompt for AI Agents
In view/app/register/hooks/use-register.ts around lines 76 to 84, the code logs
but ignores initializeAuth() failures and unconditionally redirects to
'/dashboard'; change the flow so only a successful initializeAuth leads to the
dashboard: keep the await unwrap inside try, on success await the 200ms delay
and router.push('/dashboard'), and inside the catch stop further processing and
redirect to the auth page (e.g., router.push('/auth' or '/login')) so failed
auth initialization does not send users to the dashboard.

}
} catch (error) {
toast.error(t('auth.register.errors.registerFailed'));
Expand Down
Loading