New Changes with Table Component
This commit is contained in:
@@ -0,0 +1,399 @@
|
||||
---
|
||||
import ComponentLayout from "../layouts/ComponentLayout.astro";
|
||||
import Table from "../components/Table.astro";
|
||||
|
||||
export const columns = [
|
||||
{ key: "id", label: "ID", sortable: true, searchable: true },
|
||||
{ key: "name", label: "Name", searchable: true, sortable: true },
|
||||
{ key: "email", label: "Email", searchable: true, sortable: true },
|
||||
{ key: "role", label: "Role", sortable: true },
|
||||
{ key: "status", label: "Status", sortable: true },
|
||||
{ key: "created_at", label: "Created At", sortable: true },
|
||||
{ key: "actions", label: "Actions" },
|
||||
];
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Ajay Ghanwat",
|
||||
email: "ajay.gh@example.com",
|
||||
role: "Admin",
|
||||
status: "Active",
|
||||
created_at: "2025-10-10 09:32",
|
||||
avatar: "https://i.pravatar.cc/40?img=1",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Rahul Sharma",
|
||||
email: "rahul.sharma@example.com",
|
||||
role: "Member",
|
||||
status: "Pending",
|
||||
created_at: "2025-10-15 11:42",
|
||||
avatar: "https://i.pravatar.cc/40?img=2",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Sophia Patel",
|
||||
email: "sophia.patel@example.com",
|
||||
role: "Manager",
|
||||
status: "Active",
|
||||
created_at: "2025-10-11 15:20",
|
||||
avatar: "https://i.pravatar.cc/40?img=3",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Liam Brown",
|
||||
email: "liam.brown@example.com",
|
||||
role: "Member",
|
||||
status: "Suspended",
|
||||
created_at: "2025-10-12 08:45",
|
||||
avatar: "https://i.pravatar.cc/40?img=4",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Olivia Smith",
|
||||
email: "olivia.smith@example.com",
|
||||
role: "Admin",
|
||||
status: "Active",
|
||||
created_at: "2025-10-09 18:12",
|
||||
avatar: "https://i.pravatar.cc/40?img=5",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Noah Wilson",
|
||||
email: "noah.wilson@example.com",
|
||||
role: "Member",
|
||||
status: "Pending",
|
||||
created_at: "2025-10-13 10:18",
|
||||
avatar: "https://i.pravatar.cc/40?img=6",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "Emma Johnson",
|
||||
email: "emma.johnson@example.com",
|
||||
role: "Member",
|
||||
status: "Active",
|
||||
created_at: "2025-10-14 13:55",
|
||||
avatar: "https://i.pravatar.cc/40?img=7",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "William Lee",
|
||||
email: "william.lee@example.com",
|
||||
role: "Manager",
|
||||
status: "Inactive",
|
||||
created_at: "2025-10-12 17:44",
|
||||
avatar: "https://i.pravatar.cc/40?img=8",
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: "Isabella Taylor",
|
||||
email: "isabella.taylor@example.com",
|
||||
role: "Member",
|
||||
status: "Active",
|
||||
created_at: "2025-10-10 07:31",
|
||||
avatar: "https://i.pravatar.cc/40?img=9",
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: "Ethan Martinez",
|
||||
email: "ethan.martinez@example.com",
|
||||
role: "Admin",
|
||||
status: "Suspended",
|
||||
created_at: "2025-10-08 19:22",
|
||||
avatar: "https://i.pravatar.cc/40?img=10",
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
name: "Mia Thompson",
|
||||
email: "mia.thompson@example.com",
|
||||
role: "Member",
|
||||
status: "Active",
|
||||
created_at: "2025-10-09 09:45",
|
||||
avatar: "https://i.pravatar.cc/40?img=11",
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
name: "Alexander Davis",
|
||||
email: "alex.davis@example.com",
|
||||
role: "Manager",
|
||||
status: "Pending",
|
||||
created_at: "2025-10-15 14:10",
|
||||
avatar: "https://i.pravatar.cc/40?img=12",
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
name: "Charlotte Moore",
|
||||
email: "charlotte.moore@example.com",
|
||||
role: "Member",
|
||||
status: "Active",
|
||||
created_at: "2025-10-14 10:01",
|
||||
avatar: "https://i.pravatar.cc/40?img=13",
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
name: "Benjamin Anderson",
|
||||
email: "benjamin.anderson@example.com",
|
||||
role: "Member",
|
||||
status: "Suspended",
|
||||
created_at: "2025-10-08 11:32",
|
||||
avatar: "https://i.pravatar.cc/40?img=14",
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
name: "Amelia Harris",
|
||||
email: "amelia.harris@example.com",
|
||||
role: "Manager",
|
||||
status: "Active",
|
||||
created_at: "2025-10-13 08:50",
|
||||
avatar: "https://i.pravatar.cc/40?img=15",
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
name: "Lucas White",
|
||||
email: "lucas.white@example.com",
|
||||
role: "Member",
|
||||
status: "Active",
|
||||
created_at: "2025-10-10 17:10",
|
||||
avatar: "https://i.pravatar.cc/40?img=16",
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
name: "Harper Lewis",
|
||||
email: "harper.lewis@example.com",
|
||||
role: "Member",
|
||||
status: "Pending",
|
||||
created_at: "2025-10-14 09:00",
|
||||
avatar: "https://i.pravatar.cc/40?img=17",
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
name: "Evelyn Hall",
|
||||
email: "evelyn.hall@example.com",
|
||||
role: "Manager",
|
||||
status: "Active",
|
||||
created_at: "2025-10-11 16:42",
|
||||
avatar: "https://i.pravatar.cc/40?img=18",
|
||||
},
|
||||
{
|
||||
id: 19,
|
||||
name: "Henry Allen",
|
||||
email: "henry.allen@example.com",
|
||||
role: "Member",
|
||||
status: "Inactive",
|
||||
created_at: "2025-10-09 13:25",
|
||||
avatar: "https://i.pravatar.cc/40?img=19",
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
name: "Ava Scott",
|
||||
email: "ava.scott@example.com",
|
||||
role: "Admin",
|
||||
status: "Active",
|
||||
created_at: "2025-10-15 15:33",
|
||||
avatar: "https://i.pravatar.cc/40?img=20",
|
||||
},
|
||||
{
|
||||
id: 21,
|
||||
name: "Michael Young",
|
||||
email: "michael.young@example.com",
|
||||
role: "Member",
|
||||
status: "Pending",
|
||||
created_at: "2025-10-13 10:20",
|
||||
avatar: "https://i.pravatar.cc/40?img=21",
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
name: "Ella King",
|
||||
email: "ella.king@example.com",
|
||||
role: "Manager",
|
||||
status: "Active",
|
||||
created_at: "2025-10-14 08:45",
|
||||
avatar: "https://i.pravatar.cc/40?img=22",
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
name: "Daniel Clark",
|
||||
email: "daniel.clark@example.com",
|
||||
role: "Member",
|
||||
status: "Active",
|
||||
created_at: "2025-10-12 12:05",
|
||||
avatar: "https://i.pravatar.cc/40?img=23",
|
||||
},
|
||||
{
|
||||
id: 24,
|
||||
name: "Luna Wright",
|
||||
email: "luna.wright@example.com",
|
||||
role: "Member",
|
||||
status: "Pending",
|
||||
created_at: "2025-10-15 11:18",
|
||||
avatar: "https://i.pravatar.cc/40?img=24",
|
||||
},
|
||||
{
|
||||
id: 25,
|
||||
name: "Jack Turner",
|
||||
email: "jack.turner@example.com",
|
||||
role: "Admin",
|
||||
status: "Active",
|
||||
created_at: "2025-10-13 09:50",
|
||||
avatar: "https://i.pravatar.cc/40?img=25",
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
<ComponentLayout>
|
||||
<div class="wr:p-4">
|
||||
<Table
|
||||
columns={columns}
|
||||
data={data}
|
||||
columnsRendererKey="columnsRenderer"
|
||||
/>
|
||||
|
||||
<br />
|
||||
|
||||
<Table
|
||||
columns={columns}
|
||||
fetchData="fetchData"
|
||||
columnsRendererKey="columnsRenderer"
|
||||
/>
|
||||
</div>
|
||||
</ComponentLayout>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const buttons = document.querySelectorAll(
|
||||
"button[id^='view-'], button[id^='edit-'], button[id^='delete-']",
|
||||
);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
const id = button.getAttribute("data-id");
|
||||
|
||||
if (button.id.startsWith("view-")) {
|
||||
button.addEventListener("click", () => {
|
||||
console.log(`👁️ View user ${id}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (button.id.startsWith("edit-")) {
|
||||
button.addEventListener("click", () => {
|
||||
console.log(`✏️ Edit user ${id}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (button.id.startsWith("delete-")) {
|
||||
button.addEventListener("click", () => {
|
||||
if (
|
||||
confirm(`Are you sure you want to delete user ${id}?`)
|
||||
) {
|
||||
console.log(`🗑️ Deleted user ${id}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.columnsRenderer = {
|
||||
name: (v: any, row: any) => `
|
||||
<div class="wr:flex wr:items-center wr:gap-2">
|
||||
<img src="${row.avatar}" alt="${v}" class="wr:w-8 wr:h-8 wr:rounded-full" />
|
||||
<span class="wr:font-medium">${v}</span>
|
||||
</div>
|
||||
`,
|
||||
|
||||
role: (v: string) => `
|
||||
<span class="wr:rounded-full wr:px-2 wr:py-1 wr:text-xs ${
|
||||
v === "Admin"
|
||||
? "wr:bg-indigo-100 wr:text-indigo-700"
|
||||
: v === "Owner"
|
||||
? "wr:bg-yellow-100 wr:text-yellow-700"
|
||||
: "wr:bg-gray-100 wr:text-gray-600"
|
||||
}">${v}</span>
|
||||
`,
|
||||
|
||||
status: (v: string) => `
|
||||
<span class="wr:flex wr:items-center wr:gap-1 wr:font-medium">
|
||||
<span class="wr:w-2 wr:h-2 wr:rounded-full ${
|
||||
v === "Active"
|
||||
? "wr:bg-green-500"
|
||||
: v === "Inactive"
|
||||
? "wr:bg-red-500"
|
||||
: "wr:bg-yellow-500"
|
||||
}"></span>
|
||||
${v}
|
||||
</span>
|
||||
`,
|
||||
|
||||
actions: (v: any, row: any) => `
|
||||
<div class="wr:flex wr:gap-2 wr:justify-end">
|
||||
<button id="view-${row.id}" data-id="${row.id}" class="wr:px-2 wr:py-1 wr:bg-blue-500 wr:text-white wr:rounded wr:hover:bg-blue-600">View</button>
|
||||
<button id="edit-${row.id}" data-id="${row.id}" class="wr:px-2 wr:py-1 wr:bg-amber-500 wr:text-white wr:rounded wr:hover:bg-amber-600">Edit</button>
|
||||
<button id="delete-${row.id}" data-id="${row.id}" class="wr:px-2 wr:py-1 wr:bg-red-500 wr:text-white wr:rounded wr:hover:bg-red-600">Delete</button>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
||||
window.fetchData = ({
|
||||
page,
|
||||
pageSize,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
search,
|
||||
}: {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
sortKey?: string | null;
|
||||
sortOrder?: "asc" | "desc";
|
||||
search?: string;
|
||||
}) => {
|
||||
// 🧪 Generate 100 fake users
|
||||
const demoData = Array.from({ length: 100 }).map((_, i) => ({
|
||||
id: i + 1,
|
||||
name: `User ${i + 1}`,
|
||||
avatar: `https://i.pravatar.cc/40?img=${i + 1}`,
|
||||
email: `user${i + 1}@example.com`,
|
||||
role: ["Admin", "Manager", "Member"][i % 3],
|
||||
status: ["Active", "Pending", "Suspended"][i % 3],
|
||||
created_at: new Date(
|
||||
2025,
|
||||
0,
|
||||
1 + (i % 28),
|
||||
12,
|
||||
i % 60,
|
||||
).toLocaleString(),
|
||||
}));
|
||||
|
||||
// 🔍 Searching
|
||||
let filtered = demoData;
|
||||
if (search && search.trim() !== "") {
|
||||
const lower = search.toLowerCase();
|
||||
filtered = demoData.filter((row) =>
|
||||
Object.values(row).some((val) =>
|
||||
String(val).toLowerCase().includes(lower),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 🧭 Sorting
|
||||
if (sortKey) {
|
||||
filtered.sort((a, b) => {
|
||||
const aVal = String(a[sortKey as keyof typeof a]);
|
||||
const bVal = String(b[sortKey as keyof typeof b]);
|
||||
if (aVal < bVal) return sortOrder === "asc" ? -1 : 1;
|
||||
if (aVal > bVal) return sortOrder === "asc" ? 1 : -1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
// 📄 Pagination
|
||||
const total = filtered.length;
|
||||
const start = (page - 1) * pageSize;
|
||||
const end = start + pageSize;
|
||||
const pageData = filtered.slice(start, end);
|
||||
|
||||
// ✅ Return object data, not HTML
|
||||
return {
|
||||
data: pageData,
|
||||
total,
|
||||
};
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user