diff --git a/src/app/(protected)/orders/page.tsx b/src/app/(protected)/orders/page.tsx index 641a666..f11d991 100644 --- a/src/app/(protected)/orders/page.tsx +++ b/src/app/(protected)/orders/page.tsx @@ -245,7 +245,7 @@ const MOCK_ORDERS: Order[] = [ dimensionsCmW: 12, dimensionsCmH: 8, fulfillStatus: "unfulfilled", - shipBy: "2025-10-09T18:00+07:00", + shipBy: "2025-10-09T18:00:00+07:00", carrier: "Flash", serviceLevel: "COD-Standard", trackingNo: null, @@ -409,9 +409,7 @@ function downloadCsv(filename: string, rows: Order[], cols: Column[]) { const csv = headers.join(",") + "\n" + - rows - .map((r) => keys.map((k) => escapeCsv(getProp(r, k))).join(",")) - .join("\n"); + rows.map((r) => keys.map((k) => escapeCsv(getProp(r, k))).join(",")).join("\n"); const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); @@ -619,281 +617,294 @@ export default function OrdersPage() { }, [visibleCols]); return ( -
- {/* Header */} -
-
-

ออเดอร์

-

- มุมมองเต็ม • แสดง {visibleCols.length} ฟิลด์ • ทั้งหมด {rows.length} ออเดอร์ -

-
-
- - - -
-
+ <> + {/* ทำให้กว้างหน้า "นิ่งเท่ากัน" เสมอ โดยจองที่สกรอลล์บาร์ */} + - {/* Filters — ใช้ p-5 ให้เท่ากันทุกการ์ด */} -
-
-
- setQ(e.target.value)} - className="w-full rounded-xl border border-neutral-200/70 bg-white/70 px-3 py-2 text-sm shadow-sm outline-none placeholder:text-neutral-400 focus:border-neutral-300" - /> + {/* ผูกหน้าเข้ากับกรอบคงที่ */} +
+ {/* Header */} +
+
+

ออเดอร์

+

+ มุมมองเต็ม • แสดง {visibleCols.length} ฟิลด์ • ทั้งหมด {rows.length} ออเดอร์ +

-
- -
-
- -
-
- + ส่งออก CSV (เฉพาะคอลัมน์ที่แสดง) + +
-
- {/* Table — ดึงสกรอลบาร์ออกนอก padding ด้วย -mx-5 แล้วชดเชย px-5 */} -
-
-
- - - - {topHeaderSegments.map((seg, idx) => ( - - ))} - - - {visibleCols.map((c) => ( - - ))} - - - - - {rows.map((o) => ( - - {visibleCols.map((c) => { - const raw = getProp(o, c.key); - const content: ReactNode = c.format ? c.format(raw, o) : defaultCell(raw); - const align = c.align === "right" ? "text-right" : ""; - return ( - - ); - })} - - ))} - -
- {seg.groupTH} -
- {c.labelTH} -
- {c.key === "orderNo" ? ( - - {content} - - ) : c.key === "tags" && Array.isArray(o.tags) ? ( -
- {o.tags!.length ? ( - o.tags!.map((t) => ( - - {t} - - )) - ) : ( - - - )} -
- ) : ( - content - )} -
-
-
-
- - {openCustomize && ( -
setOpenCustomize(false)} - > -
e.stopPropagation()} - > -
-

ปรับแต่งตาราง

- - - - เลือก {tempKeys.length} คอลัมน์ -
+ {/* Table — เก็บเนื้อหาทั้งหมดด้วยสกรอลล์แนวนอน และสกรอลล์บาร์ชิดขอบการ์ด */} +
+
+
+ + + + {topHeaderSegments.map((seg, idx) => ( + + ))} + + + {visibleCols.map((c) => ( + + ))} + + -
- {GROUPS.map((g) => ( -
-
- {g.titleTH} -
- - -
-
-
- {g.keys.map((k) => { - const col = ALL_COLS.find((c) => c.key === k)!; - const checked = tempKeys.includes(k); - return ( - - ); - })} -
-
+
+ {rows.map((o) => ( + + {visibleCols.map((c) => { + const raw = getProp(o, c.key); + const content: ReactNode = c.format ? c.format(raw, o) : defaultCell(raw); + const align = c.align === "right" ? "text-right" : ""; + return ( + + ); + })} + ))} - + +
+ {seg.groupTH} +
+ {c.labelTH} +
+ {c.key === "orderNo" ? ( + + {content} + + ) : c.key === "tags" && Array.isArray(o.tags) ? ( +
+ {o.tags!.length ? ( + o.tags!.map((t) => ( + + {t} + + )) + ) : ( + - + )} +
+ ) : ( + content + )} +
+
+
-
-
- เคล็ดลับ: ระบบจะจำคอลัมน์ที่คุณเลือกไว้ในเบราว์เซอร์นี้ -
-
+ {openCustomize && ( +
setOpenCustomize(false)} + > +
e.stopPropagation()} + > +
+

ปรับแต่งตาราง

-
+ +
+
+ + + + เลือก {tempKeys.length} คอลัมน์ +
+ +
+ {GROUPS.map((g) => ( +
+
+ {g.titleTH} +
+ + +
+
+
+ {g.keys.map((k) => { + const col = ALL_COLS.find((c) => c.key === k)!; + const checked = tempKeys.includes(k); + return ( + + ); + })} +
+
+ ))} +
+
+ +
+
+ เคล็ดลับ: ระบบจะจำคอลัมน์ที่คุณเลือกไว้ในเบราว์เซอร์นี้ +
+
+ + +
+
-
- )} -
+ )} +
+ ); } diff --git a/src/app/globals.css b/src/app/globals.css index a2dc41e..2db8de1 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,5 +1,11 @@ @import "tailwindcss"; +html { scrollbar-gutter: stable both-edges; } + +@supports not (scrollbar-gutter: stable both-edges) { + html { overflow-y: scroll; } +} + :root { --background: #ffffff; --foreground: #171717;