From 754e494e7f2c3782878ec4e6504aa250b227edb5 Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 5 Oct 2025 11:05:03 +0700 Subject: [PATCH] =?UTF-8?q?fronted=20=E0=B9=81=E0=B8=81=E0=B9=89=20layout?= =?UTF-8?q?=20build=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/SideNavigation.jsx | 84 +++++++++++++++++++ frontend/app/(protected)/layout.jsx | 42 ++++------ 2 files changed, 98 insertions(+), 28 deletions(-) create mode 100644 frontend/app/(protected)/_components/SideNavigation.jsx diff --git a/frontend/app/(protected)/_components/SideNavigation.jsx b/frontend/app/(protected)/_components/SideNavigation.jsx new file mode 100644 index 00000000..583f3985 --- /dev/null +++ b/frontend/app/(protected)/_components/SideNavigation.jsx @@ -0,0 +1,84 @@ +// File: frontend/app/(protected)/_components/SideNavigation.jsx +'use client'; // <-- 1. กำหนดให้ไฟล์นี้เป็น Client Component + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import { Home, FileText, Settings, Package2 } from 'lucide-react'; +import { can } from "@/lib/rbac"; +import { cn } from "@/lib/utils"; +import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; + +export function SideNavigation({ user }) { // 2. รับข้อมูล user มาจาก props + const pathname = usePathname(); // 3. ใช้งาน usePathname ได้แล้ว + + const navLinks = [ + { href: '/dashboard', label: 'Dashboard', icon: Home }, + { href: '/correspondences', label: 'Correspondences', icon: FileText }, + { href: '/drawings', label: 'Drawings', icon: FileText }, + // ... เพิ่มเมนูอื่นๆ ตามต้องการ + ]; + + const adminLink = { + href: '/admin/users', + label: 'Admin', + icon: Settings, + requiredPermission: 'manage_users' + }; + + return ( +
+
+ + + LCB P3 DMS + +
+
+ +
+
+ + + Need Help? + Contact support for any issues. + + + + + +
+
+ ); +} \ No newline at end of file diff --git a/frontend/app/(protected)/layout.jsx b/frontend/app/(protected)/layout.jsx index f70acf32..d697b552 100644 --- a/frontend/app/(protected)/layout.jsx +++ b/frontend/app/(protected)/layout.jsx @@ -1,39 +1,26 @@ -// frontend/app/(protected)/layout.jsx -// frontend/app/(protected)/layout.jsx +// File: frontend/app/(protected)/layout.jsx -import { cookies, headers } from "next/headers"; // 1. ยังคงใช้ฟังก์ชันฝั่ง Server +import { cookies } from "next/headers"; // 1. ยังคงใช้ฟังก์ชันฝั่ง Server import { redirect } from "next/navigation"; -import { Bell, Users } from 'lucide-react'; - +import { Users } from 'lucide-react'; import { Button } from '@/components/ui/button'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu'; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; -// 2. Import Navigation Component ที่เราสร้างขึ้นมาใหม่ -import { Navigation } from "./_components/navigation"; - -export const metadata = { title: "DMS | Protected" }; +// 2. Import SideNavigation Component ที่เราสร้างขึ้นมาใหม่ +import { SideNavigation } from "./_components/SideNavigation"; +// (ฟังก์ชัน fetchSession และตัวแปรอื่นๆ เหมือนเดิม) const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001"; async function fetchSession() { const cookieStore = cookies(); const token = cookieStore.get("access_token")?.value; - if (!token) return null; - try { const res = await fetch(`${API_BASE}/api/auth/me`, { headers: { Authorization: `Bearer ${token}` }, cache: "no-store", }); - if (!res.ok) return null; return await res.json(); } catch (error) { @@ -42,12 +29,10 @@ async function fetchSession() { } } - export default async function ProtectedLayout({ children }) { // 3. ดึงข้อมูล Session บน Server const session = await fetchSession(); - // ถ้าไม่มี session หรือ user ให้ redirect ไปหน้า login if (!session?.user) { redirect("/login"); } @@ -55,13 +40,12 @@ export default async function ProtectedLayout({ children }) { return (
- {/* Mobile navigation can be here */}
{/* Optional: Add a search bar */}
@@ -77,12 +61,14 @@ export default async function ProtectedLayout({ children }) { Settings - {/* Logout button in client-side auth context handles the action */} - Logout + + {/* ปุ่ม Logout จริงๆ ควรอยู่ใน Client Component ที่เรียกใช้ useAuth() hook */} + Logout +
-
+
{children}