Table - React
Table
| Name | No. Telp | Status | actions |
|---|
Halaman 1 dari 1
<div class="flex flex-col h-full w-full gap-4">
<div>
<button
type="button"
class="ina-button ina-button--primary ina-button--md bg-blue-400"
id="table-add-btn"
>
<span class="ina-button__text">Tambah User +</span>
</button>
</div>
<div class="bg-white border-neutral-200 rounded-lg overflow-x-auto border pt-4">
<div class="flex flex-row gap-2 px-4 mb-4" id="table-search-controls">
<div class="ina-text-field">
<div class="ina-text-field__wrapper h-8">
<span class="ina-text-field__icon ina-text-field__icon--prefix">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path>
<path d="M21 21l-6 -6"></path>
</svg>
</span>
<input
type="text"
class="ina-text-field__input"
placeholder="Cari..."
id="table-search-input"
/>
</div>
</div>
<button
type="button"
class="ina-button ina-button--secondary ina-button--sm border-gray-300"
>
<span class="ina-button__text">Filter</span>
</button>
</div>
<table class="ina-table w-full text-sm">
<thead class="bg-guide-100">
<tr>
<th
class="text-left font-medium text-content-primary p-4 border-b border-neutral-200 cursor-pointer hover:bg-neutral-100"
>
Name
</th>
<th
class="text-left font-medium text-content-primary p-4 border-b border-neutral-200 cursor-pointer hover:bg-neutral-100"
>
Email
</th>
<th
class="text-left font-medium text-content-primary p-4 border-b border-neutral-200 cursor-pointer hover:bg-neutral-100"
>
No. Telp
</th>
<th
class="text-left font-medium text-content-primary p-4 border-b border-neutral-200 cursor-pointer hover:bg-neutral-100"
>
Status
</th>
<th
class="text-left font-medium text-content-primary p-4 border-b border-neutral-200 cursor-pointer hover:bg-neutral-100"
>
actions
</th>
</tr>
</thead>
<tbody id="table-body">
<!-- Populated via Javascript -->
</tbody>
</table>
<div
class="ina-pagination flex flex-row items-center justify-between p-4 border-t border-neutral-200"
>
<span class="text-xs text-content-secondary">Halaman 1 dari 1</span>
<div class="flex gap-2">
<button class="ina-button ina-button--tertiary ina-button--sm p-1" disabled
><svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
><path d="M11 7l-5 5l5 5"></path><path d="M17 7l-5 5l5 5"></path></svg
></button
>
<button class="ina-button ina-button--tertiary ina-button--sm p-1" disabled
><svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"><path d="M15 6l-6 6l6 6"></path></svg
></button
>
<div class="flex items-center gap-1 mx-2">
<button class="ina-button ina-button--primary ina-button--sm w-8 rounded-full"
>1</button
>
</div>
<button class="ina-button ina-button--tertiary ina-button--sm p-1" disabled
><svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"><path d="M9 6l6 6l-6 6"></path></svg
></button
>
<button class="ina-button ina-button--tertiary ina-button--sm p-1" disabled
><svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
><path d="M7 7l5 5l-5 5"></path><path d="M13 7l5 5l-5 5"></path></svg
></button
>
</div>
</div>
</div>
</div>
<script is:inline>
document.addEventListener('DOMContentLoaded', () => {
const data = [
{ id: 1, name: 'John Doe', email: 'john@example.com', telp: '081234567890', status: true },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', telp: '081298765432', status: false },
{ id: 3, name: 'Michael', email: null, telp: null, status: true },
];
const initialPageSize = 5;
const tableBody = document.getElementById('table-body');
const searchInput = document.getElementById('table-search-input');
const addBtn = document.getElementById('table-add-btn');
function renderTable(searchTerm = '') {
const searchLower = searchTerm.toLowerCase();
let filteredData = data.filter(
(item) =>
item.name.toLowerCase().includes(searchLower) ||
(item.email && item.email.toLowerCase().includes(searchLower)) ||
item.id.toString().includes(searchLower)
);
let rowsHtml = '';
filteredData.forEach((row) => {
let statusHtml = '-';
if (row.status === true) {
statusHtml = '<span class="text-green-500 font-medium">Aktif</span>';
} else if (row.status === false) {
statusHtml = '<span class="text-red-500 font-medium">Tidak Aktif</span>';
}
const editSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4"></path><path d="M13.5 6.5l4 4"></path></svg>`;
const trashSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg>`;
rowsHtml += `
<tr class="hover:bg-neutral-50 border-b border-neutral-200 cursor-pointer" data-id="${row.id}">
<td class="p-4">${row.name ?? '-'}</td>
<td class="p-4">${row.email ?? '-'}</td>
<td class="p-4">${row.telp ?? '-'}</td>
<td class="p-4">${statusHtml}</td>
<td class="p-4">
<div class="flex gap-2">
<button class="ina-button ina-button--tertiary ina-button--sm p-1 text-guide-500" onclick="console.log('Edit:', ${row.id})">${editSvg}</button>
<button class="ina-button ina-button--tertiary ina-button--sm p-1 text-red-500" onclick="console.log('Delete:', ${row.id})">${trashSvg}</button>
</div>
</td>
</tr>
`;
});
const emptyRowsCount = initialPageSize - filteredData.length;
for (let i = 0; i < emptyRowsCount; i++) {
rowsHtml += `
<tr class="border-b border-neutral-200">
<td class="p-4"> </td>
<td class="p-4"> </td>
<td class="p-4"> </td>
<td class="p-4"> </td>
<td class="p-4"> </td>
</tr>
`;
}
if (tableBody) {
tableBody.innerHTML = rowsHtml;
}
}
renderTable();
if (searchInput) {
searchInput.addEventListener('input', (e) => {
renderTable(e.target.value);
});
}
if (addBtn) {
addBtn.addEventListener('click', () => {
console.log('Added');
});
}
});
</script>