diff --git a/apps/web-client/src/app/(auth)/forgot-password/page.tsx b/apps/web-client/src/app/(auth)/forgot-password/page.tsx
index c5c8c7bb..08113a63 100644
--- a/apps/web-client/src/app/(auth)/forgot-password/page.tsx
+++ b/apps/web-client/src/app/(auth)/forgot-password/page.tsx
@@ -10,6 +10,7 @@ import { Button } from '@/features/shared/components/ui/button';
import { Input } from '@/features/shared/components/ui/input';
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/features/shared/components/ui/card';
import { useTranslations } from 'next-intl';
+import { AuthControls } from '@/features/shared/components/layout/auth-controls';
/**
* EN: Create forgot password schema with translated messages
@@ -108,159 +109,162 @@ export default function ForgotPasswordPage() {
return (
// EN: Centered forgot password form layout with dark mode background
// VI: Layout form quên mật khẩu được căn giữa với nền dark mode
-
-
-
-
- {t('auth.forgotPassword.title')}
-
-
- {isSuccess
- ? t('auth.forgotPassword.checkEmail')
- : t('auth.forgotPassword.description')}
-
-
+ <>
+
+
+
+
+
+ {t('auth.forgotPassword.title')}
+
+
+ {isSuccess
+ ? t('auth.forgotPassword.checkEmail')
+ : t('auth.forgotPassword.description')}
+
+
- {isSuccess ? (
- // EN: Success state - show confirmation message
- // VI: Trạng thái thành công - hiển thị thông báo xác nhận
-
- {/* EN: Success icon and message / VI: Icon và thông báo thành công */}
-
-
-
-
-
- {t('auth.forgotPassword.resetLinkSent')}
-
-
-
- {/* EN: Detailed success message / VI: Thông báo thành công chi tiết */}
-
-
- {t('auth.forgotPassword.resetLinkSentDetail', { email: submittedEmail })}
-
-
-
- {t('auth.forgotPassword.checkInbox')}
-
-
-
-
- {/* EN: Additional action buttons / VI: Các nút hành động bổ sung */}
-
- {
- setIsSuccess(false);
- setSubmittedEmail('');
- }}
- >
- {t('auth.forgotPassword.sendToAnotherEmail')}
-
-
-
- ) : (
- // EN: Form state - email input and submit
- // VI: Trạng thái form - input email và submit
-
- )}
+
+
+
+
+ {t('auth.forgotPassword.resetLinkSent')}
+
+
-
- {/* EN: Back to login link / VI: Link quay lại đăng nhập */}
-
- ← {t('auth.forgotPassword.backToLogin')}
-
+ {/* EN: Detailed success message / VI: Thông báo thành công chi tiết */}
+
+
+ {t('auth.forgotPassword.resetLinkSentDetail', { email: submittedEmail })}
+
+
+
+ {t('auth.forgotPassword.checkInbox')}
+
+
+
- {/* EN: Sign up link / VI: Link đăng ký */}
-
- {t('auth.forgotPassword.noAccount')}{' '}
+ {/* EN: Additional action buttons / VI: Các nút hành động bổ sung */}
+
+ {
+ setIsSuccess(false);
+ setSubmittedEmail('');
+ }}
+ >
+ {t('auth.forgotPassword.sendToAnotherEmail')}
+
+
+
+ ) : (
+ // EN: Form state - email input and submit
+ // VI: Trạng thái form - input email và submit
+
+ )}
+
+
+ {/* EN: Back to login link / VI: Link quay lại đăng nhập */}
- {t('auth.forgotPassword.signUp')}
+ ← {t('auth.forgotPassword.backToLogin')}
-
-
-
-
+
+ {/* EN: Sign up link / VI: Link đăng ký */}
+
+ {t('auth.forgotPassword.noAccount')}{' '}
+
+ {t('auth.forgotPassword.signUp')}
+
+
+
+
+
+ >
);
}
diff --git a/apps/web-client/src/app/(auth)/login/page.tsx b/apps/web-client/src/app/(auth)/login/page.tsx
index f8e66dc3..10137828 100644
--- a/apps/web-client/src/app/(auth)/login/page.tsx
+++ b/apps/web-client/src/app/(auth)/login/page.tsx
@@ -11,6 +11,7 @@ import { Button } from '@/features/shared/components/ui/button';
import { Input } from '@/features/shared/components/ui/input';
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/features/shared/components/ui/card';
import { useTranslations } from 'next-intl';
+import { AuthControls } from '@/features/shared/components/layout/auth-controls';
/**
* EN: Create login schema with translated messages
@@ -110,124 +111,125 @@ export default function LoginPage() {
// EN: Centered login form layout with dark mode background
// VI: Layout form đăng nhập được căn giữa với nền dark mode
-
-
-
-
- {t('auth.login.title')}
-
-
- {t('auth.login.description')}
-
-
+
+
+
+
+
+ {t('auth.login.title')}
+
+
+ {t('auth.login.description')}
+
+
-
+
+
);
}
diff --git a/apps/web-client/src/app/(auth)/register/page.tsx b/apps/web-client/src/app/(auth)/register/page.tsx
index b713564c..bcd8819f 100644
--- a/apps/web-client/src/app/(auth)/register/page.tsx
+++ b/apps/web-client/src/app/(auth)/register/page.tsx
@@ -11,6 +11,7 @@ import { Button } from '@/features/shared/components/ui/button';
import { Input } from '@/features/shared/components/ui/input';
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/features/shared/components/ui/card';
import { useTranslations } from 'next-intl';
+import { AuthControls } from '@/features/shared/components/layout/auth-controls';
/**
* EN: Create register schema with translated messages
@@ -223,166 +224,29 @@ export default function RegisterPage() {
return (
// EN: Centered register form layout with dark mode background
// VI: Layout form đăng ký được căn giữa với nền dark mode
-
-
-
-
- {t('auth.register.createAccount')}
-
-
- {t('auth.register.signUpToStart')}
-
-
+ <>
+
+
+
+
+
+ {t('auth.register.createAccount')}
+
+
+ {t('auth.register.signUpToStart')}
+
+
-
-
-
+ {isLoading || isSubmitting
+ ? t('auth.register.creatingAccount')
+ : t('auth.register.createAccount')}
+
+
+ {/* EN: Sign in link / VI: Link đăng nhập */}
+
+ {t('auth.register.alreadyHaveAccount')}{' '}
+
+ {t('auth.register.signIn')}
+
+
+
+
+
+
+ >
);
}
diff --git a/apps/web-client/src/features/shared/components/layout/auth-controls.tsx b/apps/web-client/src/features/shared/components/layout/auth-controls.tsx
new file mode 100644
index 00000000..8bc85e55
--- /dev/null
+++ b/apps/web-client/src/features/shared/components/layout/auth-controls.tsx
@@ -0,0 +1,28 @@
+'use client';
+
+import React from 'react';
+import { ThemeToggle } from '@/features/theme/components/theme-toggle-enhanced';
+import { LanguageSwitcher } from '@/features/theme/components/language-switcher';
+
+/**
+ * EN: Auth Controls - Theme and Language switchers for auth pages
+ * VI: Auth Controls - Bộ chuyển theme và ngôn ngữ cho trang auth
+ *
+ * Features:
+ * - Fixed position in top-right corner
+ * - Styled to match "Try Grok" button
+ * - Works on all auth pages (login, register, forgot-password)
+ *
+ * @example
+ * ```tsx
+ *
+ * ```
+ */
+export function AuthControls() {
+ return (
+
+
+
+
+ );
+}
diff --git a/apps/web-client/src/features/theme/components/language-switcher.tsx b/apps/web-client/src/features/theme/components/language-switcher.tsx
index fb2a8067..6c552017 100644
--- a/apps/web-client/src/features/theme/components/language-switcher.tsx
+++ b/apps/web-client/src/features/theme/components/language-switcher.tsx
@@ -53,9 +53,9 @@ export function LanguageSwitcher() {
{currentLanguage.code.toUpperCase()}
diff --git a/apps/web-client/src/features/theme/components/theme-toggle-enhanced.tsx b/apps/web-client/src/features/theme/components/theme-toggle-enhanced.tsx
index c054ac2e..618f0bae 100644
--- a/apps/web-client/src/features/theme/components/theme-toggle-enhanced.tsx
+++ b/apps/web-client/src/features/theme/components/theme-toggle-enhanced.tsx
@@ -44,9 +44,9 @@ export function ThemeToggle() {