layout errer

This commit is contained in:
2025-10-01 17:15:51 +07:00
parent a1e9600ad5
commit d3339d75bf
43 changed files with 20 additions and 28 deletions

View File

@@ -9,9 +9,10 @@ export const metadata = { title: "DMS | Protected" };
const API_BASE = (process.env.NEXT_PUBLIC_API_BASE || "").replace(/\/$/, ""); const API_BASE = (process.env.NEXT_PUBLIC_API_BASE || "").replace(/\/$/, "");
async function fetchSessionFromAPI() { async function fetchSessionFromAPI() {
const cookieStore = await cookies(); // ✅ ต้อง await const cookieStore = await cookies(); // ✅ ต้อง await
const cookieHeader = cookieStore.toString(); const cookieHeader = cookieStore.toString();
const hdrs = await headers(); // ✅ ต้อง await
const hdrs = await headers(); // ✅ ต้อง await
const hostHdr = hdrs.get("host"); const hostHdr = hdrs.get("host");
const protoHdr = hdrs.get("x-forwarded-proto") || "https"; const protoHdr = hdrs.get("x-forwarded-proto") || "https";
@@ -46,10 +47,7 @@ export default async function ProtectedLayout({ children }) {
<section className="grid grid-cols-12 gap-6 p-4 mx-auto max-w-7xl"> <section className="grid grid-cols-12 gap-6 p-4 mx-auto max-w-7xl">
<aside className="col-span-12 lg:col-span-3 xl:col-span-3"> <aside className="col-span-12 lg:col-span-3 xl:col-span-3">
<div className="p-4 border rounded-3xl bg-white/70"> <div className="p-4 border rounded-3xl bg-white/70">
<div className="mb-3 text-sm"> <div className="mb-3 text-sm">RBAC: <b>{user.role}</b></div>
RBAC: <b>{user.role}</b>
</div>
<nav className="space-y-2"> <nav className="space-y-2">
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/dashboard">แดชบอร</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/dashboard">แดชบอร</Link>
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/drawings">Drawings</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/drawings">Drawings</Link>
@@ -58,7 +56,6 @@ export default async function ProtectedLayout({ children }) {
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/correspondences">Correspondences</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/correspondences">Correspondences</Link>
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/contracts-volumes">Contracts & Volumes</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/contracts-volumes">Contracts & Volumes</Link>
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/reports">Reports</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/reports">Reports</Link>
{can(user, "workflow:view") && <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/workflow">Workflow (n8n)</Link>} {can(user, "workflow:view") && <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/workflow">Workflow (n8n)</Link>}
{can(user, "health:view") && <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/health">Health</Link>} {can(user, "health:view") && <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/health">Health</Link>}
{can(user, "users:manage") && <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/users">ใช/บทบาท</Link>} {can(user, "users:manage") && <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/users">ใช/บทบาท</Link>}
@@ -67,12 +64,8 @@ export default async function ProtectedLayout({ children }) {
</aside> </aside>
<main className="col-span-12 space-y-6 lg:col-span-9 xl:col-span-9"> <main className="col-span-12 space-y-6 lg:col-span-9 xl:col-span-9">
{/* System / Quick Actions */}
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="flex-1 text-lg font-semibold"> <div className="flex-1 text-lg font-semibold">Document Management System LCBP3 Phase 3</div>
Document Management System LCBP3 Phase 3
</div>
{can(user, "admin:view") && <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/admin">Admin</a>} {can(user, "admin:view") && <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/admin">Admin</a>}
{can(user, "users:manage") && <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/users">ใช/บทบาท</a>} {can(user, "users:manage") && <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/users">ใช/บทบาท</a>}
{can(user, "health:view") && <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/health">Health</a>} {can(user, "health:view") && <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/health">Health</a>}

View File

@@ -1,18 +1,18 @@
// File: frontend/app/(protected)/layout.jsx // File: frontend/app/layout.jsx
import Link from "next/link"; import Link from "next/link";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { cookies, headers } from "next/headers"; import { cookies, headers } from "next/headers";
// ถ้ามี lib rbac เดิมอยู่ให้ใช้ต่อได้ // ถ้ามี lib rbac เดิมอยู่ให้ใช้ต่อได้
import { can } from "@/lib/rbac"; import { can } from "@/lib/rbac";
// แก้ title ให้ถูกสะกด // แก้ title ให้ถูกสะกด
export const metadata = { title: "DMS | Protected" }; export const metadata = { title: "DMS | Protected" };
const API_BASE = (process.env.NEXT_PUBLIC_API_BASE || "").replace(/\/$/, ""); const API_BASE = (process.env.NEXT_PUBLIC_API_BASE || "").replace(/\/$/, "");
async function fetchSessionFromAPI() { async function fetchSessionFromAPI() {
// ดึงคุกกี้จริงจากฝั่งเซิร์ฟเวอร์ แล้วส่งต่อให้ backend // ดึงคุกกี้จริงจากฝั่งเซิร์ฟเวอร์ แล้วส่งต่อให้ backend
const cookieHeader = cookies().toString(); // serialize ทั้งชุด const cookieHeader = cookies().toString(); // serialize ทั้งชุด
const hostHdr = headers().get("host"); const hostHdr = headers().get("host");
const protoHdr = headers().get("x-forwarded-proto") || "https"; const protoHdr = headers().get("x-forwarded-proto") || "https";
@@ -20,12 +20,12 @@ async function fetchSessionFromAPI() {
method: "GET", method: "GET",
headers: { headers: {
Cookie: cookieHeader, Cookie: cookieHeader,
// เผื่อ backend ตรวจ origin/proto/host // เผื่อ backend ตรวจ origin/proto/host
"X-Forwarded-Host": hostHdr || "", "X-Forwarded-Host": hostHdr || "",
"X-Forwarded-Proto": protoHdr, "X-Forwarded-Proto": protoHdr,
Accept: "application/json", Accept: "application/json",
}, },
// server component ไม่ต้องใช้ credentials // server component ไม่ต้องใช้ credentials
cache: "no-store", cache: "no-store",
}); });
@@ -41,7 +41,7 @@ async function fetchSessionFromAPI() {
export default async function ProtectedLayout({ children }) { export default async function ProtectedLayout({ children }) {
const session = await fetchSessionFromAPI(); const session = await fetchSessionFromAPI();
if (!session) { if (!session) {
// พยายามส่ง next path กลับไปที่ /login // พยายามส่ง next path กลับไปที่ /login
redirect("/login?next=/dashboard"); redirect("/login?next=/dashboard");
} }
const { user } = session; const { user } = session;
@@ -53,7 +53,7 @@ export default async function ProtectedLayout({ children }) {
<div className="mb-3 text-sm">RBAC: <b>{user.role}</b></div> <div className="mb-3 text-sm">RBAC: <b>{user.role}</b></div>
<nav className="space-y-2"> <nav className="space-y-2">
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/dashboard">แดชบอร</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/dashboard">แà¸à¸Šà¸šà¸­à¸£à¹Œà¸</Link>
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/drawings">Drawings</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/drawings">Drawings</Link>
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/rfas">RFAs</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/rfas">RFAs</Link>
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/transmittals">Transmittals</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/transmittals">Transmittals</Link>
@@ -68,7 +68,7 @@ export default async function ProtectedLayout({ children }) {
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/health">Health</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/health">Health</Link>
)} )}
{can(user, "users:manage") && ( {can(user, "users:manage") && (
<Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/users">ใช/บทบาท</Link> <Link className="block px-4 py-2 rounded-xl bg-white/60 hover:bg-white" href="/users">ผูà¹à¹ƒà¸Šà¹/บà¸à¸šà¸²à¸</Link>
)} )}
</nav> </nav>
</div> </div>
@@ -77,13 +77,13 @@ export default async function ProtectedLayout({ children }) {
<main className="col-span-12 space-y-6 lg:col-span-9 xl:col-span-9"> <main className="col-span-12 space-y-6 lg:col-span-9 xl:col-span-9">
{/* System / Quick Actions */} {/* System / Quick Actions */}
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="flex-1 text-lg font-semibold">Document Management System LCBP3 Phase 3</div> <div className="flex-1 text-lg font-semibold">Document Management System â LCBP3 Phase 3</div>
{can(user, "admin:view") && ( {can(user, "admin:view") && (
<a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/admin">Admin</a> <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/admin">Admin</a>
)} )}
{can(user, "users:manage") && ( {can(user, "users:manage") && (
<a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/users">ใช/บทบาท</a> <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/users">ผูà¹à¹ƒà¸Šà¹/บà¸à¸šà¸²à¸</a>
)} )}
{can(user, "health:view") && ( {can(user, "health:view") && (
<a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/health">Health</a> <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/health">Health</a>
@@ -101,7 +101,7 @@ export default async function ProtectedLayout({ children }) {
<a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/transmittals/new">+ Transmittal</a> <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/transmittals/new">+ Transmittal</a>
)} )}
{can(user, "correspondence:create") && ( {can(user, "correspondence:create") && (
<a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/correspondences/new">+ หนงสอสอสาร</a> <a className="px-3 py-2 text-white rounded-xl" style={{ background: "#0D5C75" }} href="/correspondences/new">+ หà¸à¸±à¸à¸ªà¸·à¸­à¸ªà¸·à¹ˆà¸­à¸ªà¸²à¸£</a>
)} )}
</div> </div>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,6 @@
1 1
/var/lib/postgresql/data /var/lib/postgresql/data
1759295885 1759310848
5432 5432
/var/run/postgresql /var/run/postgresql
* *

Binary file not shown.

View File

@@ -272,4 +272,3 @@ if ($request_method = OPTIONS) {
# Custom # Custom
include /data/nginx/custom/server_proxy[.]conf; include /data/nginx/custom/server_proxy[.]conf;
} }