// ListPemasangan.tsx  
import React, { useEffect, useState } from "react";  
 import { axiosInstance } from "../lib/axiosInstance";  
import { Pemasangan } from "../interfaces/Interfaces";
import ListPemasanganTable from "../components/ListpemasanganTable";
 
const ListPemasangan: React.FC = () => {  
  const [pemasangans, setPemasangans] = useState<Pemasangan[]>([]);  
  const [loading, setLoading] = useState<boolean>(true);  
  const [error, _setError] = useState<string | null>(null);  

  useEffect(() => {  
    const fetchPemasangans = async () => {  
      try {  
        const response = await axiosInstance.get("/api/status-pemasangan");  
        console.log(response.data);    
        if (response.data && response.data.data) {  
          setPemasangans(response.data.data.map((item: any) => ({  
            id_pemasangan: item.id_pemasangan,  
            no_tugas: item.no_tugas,  
            serial_number: item.inventory_edc.serial_number,  
            tid: item.inventory_edc.tid, 
            wilayah: item.wilayah,  
            vendor: item.vendor,  
            merchant: item.merchant,  
            staging: item.staging,  
            statusKepemilikan: item.inventory_edc.status_owner,  
            tanggal_dipasang: item.tanggal_dipasang,  
          })));  
        } else {  
          throw new Error("Data tidak ditemukan dalam respons API");  
        }  
      } catch (err) {  
        console.error("Error fetching data:", err); 
      } finally {  
        setLoading(false);  
      }  
    };
    fetchPemasangans();  
  }, []);  

  const handleEdit = (pemasangan: Pemasangan) => {  
    // Implement edit functionality  
    console.log("Edit pemasangan:", pemasangan);  
  };  

  if (loading) return <div>Loading...</div>;  
  if (error) return <div>Error: {error}</div>;  

  return (  
    <div className="min-h-screen bg-gray-100">  
      <div className="p-4 sm:p-6 lg:p-8">  
        <div className="container mx-auto">  
          <div className="flex flex-col sm:flex-row justify-between items-center mb-6">  
            <h1 className="text-2xl sm:text-3xl font-bold text-gray-900">  
              List Pemasangan  
            </h1>  
          </div>  
          <ListPemasanganTable  
            filteredPemasangans={pemasangans}  
            visibleColumns={[  
              "no_tugas",  
              "serial_number",  
              "tid",  
              "wilayah",  
              "vendor",  
              "merchant",  
              "statusKepemilikan",  
              "tanggal_dipasang",  
              "staging",  
              "actions",  
            ]}  
            onEdit={handleEdit}   
          />  
        </div>  
      </div>  
    </div>  
  );  
};  

export default ListPemasangan;


===

import React, { useState } from 'react';  
import { PencilIcon } from 'lucide-react';  
import { Pemasangan } from '../interfaces/Interfaces';  

interface ListPemasanganTableProps {  
  filteredPemasangans?: Pemasangan[];  
  visibleColumns?: string[];  
  onEdit: (pemasangan: Pemasangan) => void;  
  rowsPerPage?: number;  
}  

const ListPemasanganTable: React.FC<ListPemasanganTableProps> = ({  
  filteredPemasangans = [],  
  visibleColumns = [],  
  onEdit,  
  rowsPerPage = 10,  
}) => {  
  const [currentPage, setCurrentPage] = useState(1);  

  const totalPages = Math.ceil(filteredPemasangans.length / rowsPerPage);  
  const startIndex = (currentPage - 1) * rowsPerPage;  
  const endIndex = startIndex + rowsPerPage;  
  const currentPemasangans = filteredPemasangans.slice(startIndex, endIndex);  

  const handlePageChange = (page: number) => {  
    setCurrentPage(page);  
  };  

  return (  
    <div className="bg-white rounded-lg shadow-md p-6 sm:p-8 lg:p-10">  
      <div className="overflow-x-auto ">  
        <table className="w-full divide-y divide-gray-200 ">  
          <thead className="  text-black sticky top-0 z-10">  
            <tr>  
              {visibleColumns.includes('no_tugas') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-white bg-[#006677] sticky left-0 z-20">  
                  Nomor Tugas  
                </th>  
              )}  
              {visibleColumns.includes('serial_number') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  Serial Number  
                </th>  
              )}  
              {visibleColumns.includes('tid') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  TID  
                </th>  
              )}  
              {visibleColumns.includes('wilayah') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  Wilayah  
                </th>  
              )}  
              {visibleColumns.includes('vendor') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  Vendor  
                </th>  
              )}  
              {visibleColumns.includes('merchant') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  Merchant  
                </th>  
              )}  
              {visibleColumns.includes('statusKepemilikan') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  Status Kepemilikan  
                </th>  
              )}  
              {visibleColumns.includes('staging') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  Staging  
                </th>  
              )}  
              {visibleColumns.includes('actions') && (  
                <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">  
                  Actions  
                </th>  
              )}  
            </tr>  
          </thead>  
          <tbody className="bg-white divide-y divide-gray-200">  
            {currentPemasangans.map(pemasangan => (  
              <tr key={pemasangan.id_pemasangan}>  
                {visibleColumns.includes('no_tugas') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r  bg-gray-100 sticky left-0 z-20">  
                    {pemasangan.no_tugas}  
                  </td>  
                )}  
                {visibleColumns.includes('serial_number') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r">  
                    {pemasangan.serial_number}  
                  </td>  
                )}  
                {visibleColumns.includes('tid') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r">  
                    {pemasangan.tid}  
                  </td>  
                )}  
                {visibleColumns.includes('wilayah') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r">  
                    {pemasangan.wilayah.name}  
                  </td>  
                )}  
                {visibleColumns.includes('vendor') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r">  
                    {pemasangan.vendor.name}  
                  </td>  
                )}  
                {visibleColumns.includes('merchant') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r">  
                    {pemasangan.merchant.merchantname}  
                  </td>  
                )}  
                {visibleColumns.includes('statusKepemilikan') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r">  
                    {pemasangan.statusKepemilikan}  
                  </td>  
                )}  
                {visibleColumns.includes('staging') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r">  
                    <span  
                      className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${  
                        pemasangan.staging.name === 'Solved'  
                          ? 'bg-green-100 text-green-800'  
                          : pemasangan.staging.name === 'Open'  
                          ? 'bg-blue-100 text-blue-800'  
                          : 'bg-gray-100 text-gray-800'  
                      }`}  
                    >  
                      {pemasangan.staging.name}  
                    </span>  
                  </td>  
                )}  
                {visibleColumns.includes('actions') && (  
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-center text-gray-900">  
                    <div className="flex justify-center">  
                      <button  
                        onClick={() => onEdit(pemasangan)}  
                        className="text-blue-500 hover:text-blue-700"  
                      >  
                        <PencilIcon className="w-5 h-5" />  
                      </button>  
                     
                    </div>  
                  </td>  
                )}  
              </tr>  
            ))}  
          </tbody>  
        </table>  
      </div>  
      <div className="flex justify-end mt-4 sm:mt-6 lg:mt-8">  
        <div className="flex items-center space-x-2 sm:space-x-4">  
          <span className="text-gray-500 hidden sm:block">Rows per page:</span>  
          <select  
            className="px-2 py-1 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"  
            value={rowsPerPage}  
            onChange={_e => handlePageChange(1)}  
          >  
            <option>10</option>  
            <option>20</option>  
            <option>50</option>  
          </select>  
          <div className="flex items-center space-x-2 sm:space-x-4">  
            <button  
              className={`px-2 py-1 rounded-md bg-gray-200 hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent ${  
                currentPage === 1 ? 'opacity-50 cursor-not-allowed' : ''  
              }`}  
              onClick={() => handlePageChange(currentPage - 1)}  
              disabled={currentPage === 1}  
            >  
              Prev  
            </button>  
            <span className="text-gray-500">  
              {startIndex + 1}-{endIndex} of {filteredPemasangans.length}  
            </span>  
            <button  
              className={`px-2 py-1 rounded-md bg-gray-200 hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent ${  
                currentPage === totalPages ? 'opacity-50 cursor-not-allowed' : ''  
              }`}  
              onClick={() => handlePageChange(currentPage + 1)}  
              disabled={currentPage === totalPages}  
            >  
              Next  
            </button>  
          </div>  
        </div>  
      </div>  
    </div>  
  );  
};  

export default ListPemasanganTable;

===

Buatkan untuk ListPenarikan