diff --git a/app/(app)/home/page.tsx b/app/(app)/home/page.tsx index 2b02079..bd49873 100644 --- a/app/(app)/home/page.tsx +++ b/app/(app)/home/page.tsx @@ -134,10 +134,21 @@ export default function Home() { }; return ( -
+
-
+
{/* Mobile header — switcher inside the green band */}
@@ -291,7 +302,7 @@ export default function Home() {
-
+
-
{children}
- + {children} ); } diff --git a/app/auth/login/page.tsx b/app/auth/login/page.tsx index ec48a9a..4102fd7 100644 --- a/app/auth/login/page.tsx +++ b/app/auth/login/page.tsx @@ -372,7 +372,7 @@ function LoginPageContent() { value={studentId} onChange={(e) => setStudentId(e.target.value.replace(/\D/g, "").slice(0, 5))} className={authInputClassName("studentId")} - placeholder="12345" + placeholder="เช่น 12345" autoComplete="username" required /> diff --git a/app/auth/register/page.tsx b/app/auth/register/page.tsx index e1aadf6..9a146a7 100644 --- a/app/auth/register/page.tsx +++ b/app/auth/register/page.tsx @@ -191,7 +191,7 @@ export default function RegisterPage() { aria-invalid={errors.studentId ? true : undefined} aria-describedby={errors.studentId ? fieldErrorId("studentId") : undefined} className={authInputClassName("studentId", errors.studentId)} - placeholder="12345" + placeholder="เช่น 12345" autoFocus /> - +
+ +
); } diff --git a/components/layout/assistant-app-shell.tsx b/components/layout/assistant-app-shell.tsx index de0b0b4..6a89d22 100644 --- a/components/layout/assistant-app-shell.tsx +++ b/components/layout/assistant-app-shell.tsx @@ -20,14 +20,19 @@ export function AssistantAppShell({ mainClassName, }: AssistantAppShellProps) { return ( -
-
+
+
{children}
diff --git a/components/providers/full-app-providers.tsx b/components/providers/full-app-providers.tsx new file mode 100644 index 0000000..b6fb3e1 --- /dev/null +++ b/components/providers/full-app-providers.tsx @@ -0,0 +1,30 @@ +"use client"; + +import { AuthProvider } from "@/contexts/auth-context"; +import { AppModeProvider } from "@/contexts/app-mode-context"; +import { DataProvider } from "@/contexts/DataContext"; +import AuthGuard from "@/components/auth/auth-guard"; +import { BfcacheRestoreHandler } from "@/components/bfcache-restore-handler"; + +function AppShell({ children }: { children: React.ReactNode }) { + return ( +
+
{children}
+
+ ); +} + +export function FullAppProviders({ children }: { children: React.ReactNode }) { + return ( + + + + + + {children} + + + + + ); +} diff --git a/components/providers/setup-aware-providers.tsx b/components/providers/setup-aware-providers.tsx index f1d3e69..e9ac401 100644 --- a/components/providers/setup-aware-providers.tsx +++ b/components/providers/setup-aware-providers.tsx @@ -1,17 +1,13 @@ "use client"; import { usePathname } from "next/navigation"; -import { AuthProvider } from "@/contexts/auth-context"; -import { AppModeProvider } from "@/contexts/app-mode-context"; -import { DataProvider } from "@/contexts/DataContext"; -import AuthGuard from "@/components/auth/auth-guard"; -import { BfcacheRestoreHandler } from "@/components/bfcache-restore-handler"; -import { isSetupPublicPath } from "@/lib/auth-routes"; +import { isLightweightShellPath } from "@/lib/auth-routes"; +import { FullAppProviders } from "@/components/providers/full-app-providers"; function AppShell({ children }: { children: React.ReactNode }) { return (
-
{children}
+
{children}
); } @@ -19,20 +15,9 @@ function AppShell({ children }: { children: React.ReactNode }) { export function SetupAwareProviders({ children }: { children: React.ReactNode }) { const pathname = usePathname() ?? ""; - if (isSetupPublicPath(pathname)) { + if (isLightweightShellPath(pathname)) { return {children}; } - return ( - - - - - - {children} - - - - - ); + return {children}; } diff --git a/lib/auth-copy.ts b/lib/auth-copy.ts index 724cd81..953beb3 100644 --- a/lib/auth-copy.ts +++ b/lib/auth-copy.ts @@ -16,13 +16,13 @@ export const AUTH_COPY = { schoolPasswordField: "รหัสผ่านจากโรงเรียน", /** Hints */ - passwordRules: "อย่างน้อย 8 ตัว มีทั้งตัวอักษรและตัวเลข", - pinQuickUnlock: "ใช้แทนรหัสผ่านเมื่อเปิดแอปบนเครื่องนี้", + passwordRules: "อย่างน้อย 8 ตัวอักษร โดยต้องมีทั้งตัวอักษร (A-Z/a-z) และตัวเลข (0-9)", + pinQuickUnlock: "ใช้เพื่อเข้าสู่ระบบอย่างรวดเร็ว หากเคยล็อกอินด้วยรหัสผ่านแล้ว", registerStudentIdHint: - "กรอกเลขที่โรงเรียนแจ้ง ระบบจะแสดงชื่อและห้องให้ตรวจสอบก่อนดำเนินการต่อ", + "กรอกเลขประจำตัวนักเรียนของคุณ", schoolPasswordHint: "รหัสชั่วคราวที่โรงเรียนแจก — สำหรับบัญชีที่ยังไม่เคยตั้งรหัสผ่านเอง", - profileMismatchHint: "ข้อมูลไม่ตรง? ลอง \"แก้ไขเลขประจำตัว\" ด้านล่าง หรือติดต่อผู้ดูแลระบบ", + profileMismatchHint: "ข้อมูลไม่ตรง? ลองกด \"แก้ไขเลขประจำตัว\" ด้านล่าง หรือติดต่อผู้ดูแลระบบ", /** Primary actions */ signIn: "เข้าสู่ระบบ", @@ -92,7 +92,7 @@ export const AUTH_COPY = { /** Register flow */ registerTitle: "เริ่มใช้งาน", registerSubtitle: "สมัครสมาชิก", - registerDescription: "สมัครสมาชิกเพื่อใช้งานระบบของโรงเรียน", + registerDescription: "สมัครสมาชิกเพื่อเริ่มต้น", registerStepStudentId: "เลขประจำตัว", registerStepConfirm: "ยืนยันตัวตน", registerStepPassword: "รหัสผ่าน", diff --git a/lib/auth-routes.ts b/lib/auth-routes.ts index fa27bd5..4171bdf 100644 --- a/lib/auth-routes.ts +++ b/lib/auth-routes.ts @@ -39,6 +39,22 @@ export function isAuthPublicPath(pathname: string): boolean { ); } +/** Routes that skip AuthProvider / DataProvider / AuthGuard (no useAuth on page) */ +export const LIGHTWEIGHT_SHELL_EXACT_PATHS = [ + "/", + AUTH_ROUTES.hub, + AUTH_ROUTES.register, + AUTH_ROUTES.forgotPin, + AUTH_ROUTES.resetPassword, +] as const; + +export function isLightweightShellPath(pathname: string): boolean { + return ( + isSetupPublicPath(pathname) || + (LIGHTWEIGHT_SHELL_EXACT_PATHS as readonly string[]).includes(pathname) + ); +} + export function resolvePostLoginPath(payload: { mustChangePassword?: boolean; mustSetupPin?: boolean;