From cc5edf2ff6e83a081f87f564914c2a3a6b541d85 Mon Sep 17 00:00:00 2001 From: athivaratz Date: Tue, 14 Jul 2026 00:30:01 +0700 Subject: [PATCH 1/4] Refactor layout and enhance responsiveness across components - Updated `globals.css` to adjust padding for landscape orientation on larger screens. - Simplified the layout structure in `layout.tsx` by removing unnecessary div wrappers. - Improved the home page layout with responsive classes for better handling of different screen sizes. - Enhanced the `AgentChatShell` and `AssistantAppShell` components to ensure proper flex behavior and overflow management. - Streamlined the `setup-aware-providers` to eliminate redundant height settings while maintaining background consistency. --- app/(app)/home/page.tsx | 17 ++++++++++++++--- app/(app)/layout.tsx | 4 +--- app/globals.css | 6 ++++++ components/agent/agent-chat-shell.tsx | 4 +++- components/layout/assistant-app-shell.tsx | 11 ++++++++--- components/providers/setup-aware-providers.tsx | 2 +- 6 files changed, 33 insertions(+), 11 deletions(-) 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/globals.css b/app/globals.css index d552373..1449c2c 100644 --- a/app/globals.css +++ b/app/globals.css @@ -469,6 +469,12 @@ body { padding-bottom: calc(var(--bottom-nav-height) + env(safe-area-inset-bottom, 0px)); } +@media (min-width: 768px) and (orientation: landscape) and (min-height: 600px) { + .main-with-bottom-nav { + padding-bottom: 0; + } +} + /* Extra scroll room when a sticky form footer sits above bottom nav (mobile) */ .form-sticky-footer-padding { padding-bottom: calc(var(--bottom-nav-height) + 4.5rem + env(safe-area-inset-bottom, 0px)); diff --git a/components/agent/agent-chat-shell.tsx b/components/agent/agent-chat-shell.tsx index 4dfe49b..a0f0e6e 100644 --- a/components/agent/agent-chat-shell.tsx +++ b/components/agent/agent-chat-shell.tsx @@ -172,7 +172,9 @@ function AgentChatInner() { export function AgentChatShell() { return ( - +
+ +
); } 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}
-
{children}
+
{children}
); } From a6041a32ab905ad24169f8b1c9be50cfd340e0bb Mon Sep 17 00:00:00 2001 From: athivaratz Date: Tue, 14 Jul 2026 00:36:05 +0700 Subject: [PATCH 2/4] Refactor layout components for improved responsiveness and structure - Introduced `shellMobileOnly` utility for better mobile layout handling in `ListPage`, `TrackingPage`, and other components. - Updated main container classes to enhance flex behavior and overflow management across various pages. - Adjusted loading states in NFC-related pages to ensure consistent height and alignment. - Enhanced `AppShell` and `StudentAppShell` components for better responsiveness and layout consistency on different screen sizes. --- app/(app)/list/page.tsx | 5 ++-- app/(app)/tracking/page.tsx | 21 ++++++++------- app/nfc/found/page.tsx | 4 +-- app/nfc/my-tags/page.tsx | 2 +- app/nfc/page.tsx | 2 +- app/nfc/register/page.tsx | 2 +- components/layout/app-shell.tsx | 24 ++++++++++++++--- components/layout/student-app-shell.tsx | 36 +++++++++++++++++++++---- 8 files changed, 72 insertions(+), 24 deletions(-) diff --git a/app/(app)/list/page.tsx b/app/(app)/list/page.tsx index feb1277..403bba4 100644 --- a/app/(app)/list/page.tsx +++ b/app/(app)/list/page.tsx @@ -16,6 +16,7 @@ import { import Header from "@/components/layout/header"; import BottomNav from "@/components/layout/bottom-nav"; import AppShell from "@/components/layout/app-shell"; +import { shellMobileOnly } from "@/components/layout/shell-layout"; import { StatusAlert } from "@/components/ui/status-alert"; import { useAuth } from "@/contexts/auth-context"; import { @@ -169,7 +170,7 @@ export default function ListPage() { return ( -
+
@@ -454,7 +455,7 @@ export default function ListPage() { )}
-
+
diff --git a/app/(app)/tracking/page.tsx b/app/(app)/tracking/page.tsx index 225e9de..ae2ef1d 100644 --- a/app/(app)/tracking/page.tsx +++ b/app/(app)/tracking/page.tsx @@ -15,6 +15,7 @@ import { import Header from "@/components/layout/header"; import BottomNav from "@/components/layout/bottom-nav"; import AppShell from "@/components/layout/app-shell"; +import { shellMobileOnly } from "@/components/layout/shell-layout"; import { StatusAlert } from "@/components/ui/status-alert"; import { CATEGORIES, @@ -138,7 +139,7 @@ export default function TrackingPage() { if (authLoading && !user) { return ( -
+
); @@ -146,13 +147,15 @@ export default function TrackingPage() { if (!user) { return ( -
+
- +
+ +
); @@ -168,7 +171,7 @@ export default function TrackingPage() { return ( -
+
@@ -475,7 +478,7 @@ export default function TrackingPage() {
-
+
diff --git a/app/nfc/found/page.tsx b/app/nfc/found/page.tsx index b3073fa..e7cc2a7 100644 --- a/app/nfc/found/page.tsx +++ b/app/nfc/found/page.tsx @@ -108,7 +108,7 @@ function NfcFoundContent() { if (authLoading && !user) { return ( -
+
); @@ -279,7 +279,7 @@ export default function NfcFoundPage() { return ( +
} diff --git a/app/nfc/my-tags/page.tsx b/app/nfc/my-tags/page.tsx index 4605151..3b7c347 100644 --- a/app/nfc/my-tags/page.tsx +++ b/app/nfc/my-tags/page.tsx @@ -178,7 +178,7 @@ export default function NfcMyTagsPage() { if ((authLoading && !user) || loading) { return ( -
+
); diff --git a/app/nfc/page.tsx b/app/nfc/page.tsx index d2d83b7..dabe48e 100644 --- a/app/nfc/page.tsx +++ b/app/nfc/page.tsx @@ -42,7 +42,7 @@ export default function NfcHubPage() { if (authLoading && !user) { return ( -
+
); diff --git a/app/nfc/register/page.tsx b/app/nfc/register/page.tsx index 926e8b5..1654810 100644 --- a/app/nfc/register/page.tsx +++ b/app/nfc/register/page.tsx @@ -171,7 +171,7 @@ export default function NfcRegisterPage() { if ((authLoading && !user) || !nfcChecked) { return ( -
+
); diff --git a/components/layout/app-shell.tsx b/components/layout/app-shell.tsx index d37fd30..1a88285 100644 --- a/components/layout/app-shell.tsx +++ b/components/layout/app-shell.tsx @@ -12,11 +12,29 @@ interface AppShellProps { /** Manual shell with sidebar — pages own horizontal padding inside children. */ export default function AppShell({ children }: AppShellProps) { return ( -
+
-
+
-
{children}
+
+ {children} +
); diff --git a/components/layout/student-app-shell.tsx b/components/layout/student-app-shell.tsx index 166e610..66ca6d8 100644 --- a/components/layout/student-app-shell.tsx +++ b/components/layout/student-app-shell.tsx @@ -46,23 +46,49 @@ export function StudentAppShell({ const contentClass = cn("mx-auto w-full", maxWidthClasses[maxWidth]); return ( -
+
{/* Mobile */} -
+
{headerTitle ? (
) : null} -
+
{children}
{showBottomNav ? : null}
{/* Desktop */} -
+
-
+
{children}
From 82ff9e076185c9c836673aecc7357a0c0bc15311 Mon Sep 17 00:00:00 2001 From: athivaratz Date: Tue, 14 Jul 2026 00:51:59 +0700 Subject: [PATCH 3/4] Revert "Refactor layout components for improved responsiveness and structure" This reverts commit a6041a32ab905ad24169f8b1c9be50cfd340e0bb. --- app/(app)/list/page.tsx | 5 ++-- app/(app)/tracking/page.tsx | 21 +++++++-------- app/nfc/found/page.tsx | 4 +-- app/nfc/my-tags/page.tsx | 2 +- app/nfc/page.tsx | 2 +- app/nfc/register/page.tsx | 2 +- components/layout/app-shell.tsx | 24 +++-------------- components/layout/student-app-shell.tsx | 36 ++++--------------------- 8 files changed, 24 insertions(+), 72 deletions(-) diff --git a/app/(app)/list/page.tsx b/app/(app)/list/page.tsx index 403bba4..feb1277 100644 --- a/app/(app)/list/page.tsx +++ b/app/(app)/list/page.tsx @@ -16,7 +16,6 @@ import { import Header from "@/components/layout/header"; import BottomNav from "@/components/layout/bottom-nav"; import AppShell from "@/components/layout/app-shell"; -import { shellMobileOnly } from "@/components/layout/shell-layout"; import { StatusAlert } from "@/components/ui/status-alert"; import { useAuth } from "@/contexts/auth-context"; import { @@ -170,7 +169,7 @@ export default function ListPage() { return ( -
+
@@ -455,7 +454,7 @@ export default function ListPage() { )}
-
+
diff --git a/app/(app)/tracking/page.tsx b/app/(app)/tracking/page.tsx index ae2ef1d..225e9de 100644 --- a/app/(app)/tracking/page.tsx +++ b/app/(app)/tracking/page.tsx @@ -15,7 +15,6 @@ import { import Header from "@/components/layout/header"; import BottomNav from "@/components/layout/bottom-nav"; import AppShell from "@/components/layout/app-shell"; -import { shellMobileOnly } from "@/components/layout/shell-layout"; import { StatusAlert } from "@/components/ui/status-alert"; import { CATEGORIES, @@ -139,7 +138,7 @@ export default function TrackingPage() { if (authLoading && !user) { return ( -
+
); @@ -147,15 +146,13 @@ export default function TrackingPage() { if (!user) { return ( -
+
-
- -
+
); @@ -171,7 +168,7 @@ export default function TrackingPage() { return ( -
+
@@ -478,7 +475,7 @@ export default function TrackingPage() {
-
+
diff --git a/app/nfc/found/page.tsx b/app/nfc/found/page.tsx index e7cc2a7..b3073fa 100644 --- a/app/nfc/found/page.tsx +++ b/app/nfc/found/page.tsx @@ -108,7 +108,7 @@ function NfcFoundContent() { if (authLoading && !user) { return ( -
+
); @@ -279,7 +279,7 @@ export default function NfcFoundPage() { return ( +
} diff --git a/app/nfc/my-tags/page.tsx b/app/nfc/my-tags/page.tsx index 3b7c347..4605151 100644 --- a/app/nfc/my-tags/page.tsx +++ b/app/nfc/my-tags/page.tsx @@ -178,7 +178,7 @@ export default function NfcMyTagsPage() { if ((authLoading && !user) || loading) { return ( -
+
); diff --git a/app/nfc/page.tsx b/app/nfc/page.tsx index dabe48e..d2d83b7 100644 --- a/app/nfc/page.tsx +++ b/app/nfc/page.tsx @@ -42,7 +42,7 @@ export default function NfcHubPage() { if (authLoading && !user) { return ( -
+
); diff --git a/app/nfc/register/page.tsx b/app/nfc/register/page.tsx index 1654810..926e8b5 100644 --- a/app/nfc/register/page.tsx +++ b/app/nfc/register/page.tsx @@ -171,7 +171,7 @@ export default function NfcRegisterPage() { if ((authLoading && !user) || !nfcChecked) { return ( -
+
); diff --git a/components/layout/app-shell.tsx b/components/layout/app-shell.tsx index 1a88285..d37fd30 100644 --- a/components/layout/app-shell.tsx +++ b/components/layout/app-shell.tsx @@ -12,29 +12,11 @@ interface AppShellProps { /** Manual shell with sidebar — pages own horizontal padding inside children. */ export default function AppShell({ children }: AppShellProps) { return ( -
+
-
+
-
- {children} -
+
{children}
); diff --git a/components/layout/student-app-shell.tsx b/components/layout/student-app-shell.tsx index 66ca6d8..166e610 100644 --- a/components/layout/student-app-shell.tsx +++ b/components/layout/student-app-shell.tsx @@ -46,49 +46,23 @@ export function StudentAppShell({ const contentClass = cn("mx-auto w-full", maxWidthClasses[maxWidth]); return ( -
+
{/* Mobile */} -
+
{headerTitle ? (
) : null} -
+
{children}
{showBottomNav ? : null}
{/* Desktop */} -
+
-
+
{children}
From 314317e0ddb221303e7741e15176c06a649f5b05 Mon Sep 17 00:00:00 2001 From: athivaratz Date: Thu, 16 Jul 2026 15:26:03 +0700 Subject: [PATCH 4/4] Update placeholder text and improve authentication hints - Changed placeholder text in login and registration forms to provide localized examples. - Enhanced hints in the authentication copy for clarity and user guidance, including more detailed password rules and student ID instructions. - Refactored `SetupAwareProviders` to utilize a new `FullAppProviders` component for better structure and maintainability. --- app/auth/login/page.tsx | 2 +- app/auth/register/page.tsx | 2 +- .../not-found/not-found-home-button.tsx | 8 +---- components/providers/full-app-providers.tsx | 30 +++++++++++++++++++ .../providers/setup-aware-providers.tsx | 23 +++----------- lib/auth-copy.ts | 10 +++---- lib/auth-routes.ts | 16 ++++++++++ 7 files changed, 58 insertions(+), 33 deletions(-) create mode 100644 components/providers/full-app-providers.tsx 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/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 d589080..e9ac401 100644 --- a/components/providers/setup-aware-providers.tsx +++ b/components/providers/setup-aware-providers.tsx @@ -1,12 +1,8 @@ "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 ( @@ -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;