diff --git a/src/components/customs/custom-table.tsx b/src/components/customs/custom-table.tsx index 96ff1bc..4354a60 100644 --- a/src/components/customs/custom-table.tsx +++ b/src/components/customs/custom-table.tsx @@ -106,7 +106,7 @@ export default function Table({ ); }; - /* ================= ROWS ================= */ + /* ================= DESKTOP / TABLET ROWS ================= */ const renderRows = (rows: T[], path: number[] = []): React.ReactNode => rows.map((row, i) => { const currentPath = [...path, i]; @@ -141,6 +141,7 @@ export default function Table({ "px-4 py-3 text-sm font-medium whitespace-nowrap", col.fixedLeft && "sticky left-0 bg-white z-10", col.fixedRight && "sticky right-0 bg-white z-10", + col.className, )} >
({ ); }); - /* ================= UI ================= */ - return ( -
table>thead]:sticky [&>table>thead]:top-0", - activeHeader && "[&>table>thead]:bg-[#F4F7FA]", - )} - > - - - - {getChildren && {renderRows(sortedData)} +
} + /* ================= MOBILE CARDS (KHUÔN BẢNG GIỐNG ẢNH MẪU) ================= */ + const renderMobileCards = (rows: T[], path: number[] = []): React.ReactNode => + rows.map((row, i) => { + const currentPath = [...path, i]; + const keyPath = useIndexPathAsKey ? currentPath.join(".") : rowKey(row); + const children = getChildren?.(row); + const expanded = expandedRows.includes(keyPath); - {column.map((col, i) => { - const isActive = col.sortTable === sortConfig.key; - - return ( - { - thRefs.current[i] = el; - }} - onClick={() => col.sortTable && handleSort(col.sortTable)} - className={clsx( - "px-4 py-3 text-left text-[15px] font-semibold whitespace-nowrap", - col.sortTable && "cursor-pointer", - isActive && "text-blue-600", - col.fixedLeft && "sticky left-0 bg-white z-10", - col.fixedRight && "sticky right-0 bg-white z-10", + return ( + + {/* Khung Card cho mỗi bệnh nhân / dòng */} +
+ {column.map((col, idx) => ( +
+ {/* Tiêu đề bên trái (TÊN BỆNH NHÂN, MÃ PHIÊN KHÁM,...) */} +
+ {col.checkBox && ( + handleCheckedRow?.(e, row)} + checked={handleIsCheckedRow?.(row) ?? false} + /> )} + {col.title} +
+ + {/* Giá trị / Nút bấm bên phải */} +
+ {col.render(row, i, currentPath)} +
+
+ ))} + + {/* Xem thêm nếu có hàng con */} + {getChildren && !!children?.length && ( +
+ +
+ )} +
- {col.title} + {/* Render hàng con nếu có */} + {expanded && children && ( +
+ {renderMobileCards(children, currentPath)} +
+ )} +
+ ); + }); - {col.sortTable && - (isActive ? ( - sortConfig.direction === "asc" ? ( - - ) : sortConfig.direction === "desc" ? ( - + /* ================= UI MAIN ================= */ + return ( +
+ {/* 1. ĐIỆN THOẠI (< md) */} +
{renderMobileCards(sortedData)}
+ + {/* 2. TABLET & DESKTOP (>= md) */} +
table>thead]:sticky [&>table>thead]:top-0", + activeHeader && "[&>table>thead]:bg-[#F4F7FA]", + )} + > + + + + {getChildren && - ); - })} - - + ))} + + + ); + })} + + - {renderRows(sortedData)} -
} + + {column.map((col, i) => { + const isActive = col.sortTable === sortConfig.key; + + return ( + { + thRefs.current[i] = el; + }} + onClick={() => col.sortTable && handleSort(col.sortTable)} + className={clsx( + "px-4 py-3 text-left text-[15px] font-semibold whitespace-nowrap", + col.sortTable && "cursor-pointer", + isActive && "text-blue-600", + col.fixedLeft && "sticky left-0 bg-white z-10", + col.fixedRight && "sticky right-0 bg-white z-10", + col.className, + )} + > +
+ {col.checkBox && ( + + )} + + {col.title} + + {col.sortTable && + (isActive ? ( + sortConfig.direction === "asc" ? ( + + ) : sortConfig.direction === "desc" ? ( + + ) : ( + + ) ) : ( - ) - ) : ( - - ))} -
-
+
+
); } diff --git a/src/components/page/consultation/MainPageConsultation/MainPageConsultation.tsx b/src/components/page/consultation/MainPageConsultation/MainPageConsultation.tsx index 1cb150c..77715c1 100644 --- a/src/components/page/consultation/MainPageConsultation/MainPageConsultation.tsx +++ b/src/components/page/consultation/MainPageConsultation/MainPageConsultation.tsx @@ -601,13 +601,19 @@ const MainPageConsultation = () => { // ===== TAB TẤT CẢ ===== return ( -
+ /* + Chỉnh sửa tại đây: + - flex-col: xếp dọc trên màn mobile + - sm:flex-row: quay lại xếp ngang trên tablet / desktop (>= 640px) + - w-full sm:w-auto: mở rộng full chiều rộng ô khi ở màn mobile cho cân đối + */ +