import React, { useState, useEffect } from 'react'; import { Search, Plus, DollarSign, Users, Wifi, Calculator, Trash2, Edit3, X } from 'lucide-react';
const KenangaWiFiSystem = () => { const [customers, setCustomers] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [newCustomer, setNewCustomer] = useState({ name: '', package: '', payment: '' }); const [expenses, setExpenses] = useState({ electricity: '', maintenance: '', billing: '', bandwidth: '' }); const [activeTab, setActiveTab] = useState('customers'); const [editingCustomer, setEditingCustomer] = useState(null); const [editForm, setEditForm] = useState({ name: '', package: '', payment: '' });
// Menghitung total pendapatan dari customer yang sudah lunas const totalRevenue = customers .filter(customer => customer.isPaid) .reduce((sum, customer) => sum + customer.payment, 0);
// Menghitung total pengeluaran const totalExpenses = Object.values(expenses) .reduce((sum, expense) => sum + (parseFloat(expense) || 0), 0);
// Pendapatan bersih const netRevenue = totalRevenue - totalExpenses;
// Bagi hasil (dibagi 4) const profitShare = netRevenue / 4;
// Filter customer berdasarkan pencarian const filteredCustomers = customers.filter(customer => customer.name.toLowerCase().includes(searchTerm.toLowerCase()) );
// Menambah customer baru const addCustomer = () => { if (newCustomer.name && newCustomer.package && newCustomer.payment) { const customer = { id: Date.now(), name: newCustomer.name, package: newCustomer.package, payment: parseFloat(newCustomer.payment), isPaid: false, addedDate: new Date().toLocaleDateString('id-ID') }; setCustomers([...customers, customer]); setNewCustomer({ name: '', package: '', payment: '' }); } };
// Toggle status pembayaran const togglePaymentStatus = (id) => { setCustomers(customers.map(customer => customer.id === id ? { ...customer, isPaid: !customer.isPaid } : customer )); };
// Hapus customer
const deleteCustomer = (id, customerName) => {
if (window.confirm(Apakah Anda yakin ingin menghapus customer "${customerName}"?\n\nData yang akan dihapus tidak dapat dikembalikan.
)) {
setCustomers(customers.filter(customer => customer.id !== id));
alert(Customer "${customerName}" berhasil dihapus dari sistem.
);
}
};
// Edit customer const startEditCustomer = (customer) => { setEditingCustomer(customer); setEditForm({ name: customer.name, package: customer.package, payment: customer.payment.toString() }); };
const saveEditCustomer = () => {
if (editForm.name && editForm.package && editForm.payment) {
setCustomers(customers.map(customer =>
customer.id === editingCustomer.id
? {
...customer,
name: editForm.name,
package: editForm.package,
payment: parseFloat(editForm.payment)
}
: customer
));
setEditingCustomer(null);
setEditForm({ name: '', package: '', payment: '' });
alert(Data customer "${editForm.name}" berhasil diperbarui.
);
}
};
const cancelEdit = () => { setEditingCustomer(null); setEditForm({ name: '', package: '', payment: '' }); };
// Format currency Indonesia const formatCurrency = (amount) => { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0 }).format(amount); };
const TabButton = ({ id, label, icon: Icon, isActive, onClick }) => (
<button
onClick={() => onClick(id)}
className={flex items-center space-x-2 px-6 py-3 rounded-lg font-medium transition-all duration-200 ${ isActive ? 'bg-green-500 text-white shadow-lg transform scale-105' : 'bg-white text-gray-600 hover:bg-green-50 hover:text-green-600 border border-gray-200' }
}
>
{label}
);
return (
{/* Navigation Tabs */}
<div className="flex flex-wrap justify-center gap-4 mb-8">
<TabButton
id="customers"
label="Manajemen Customer"
icon={Users}
isActive={activeTab === 'customers'}
onClick={setActiveTab}
/>
<TabButton
id="payments"
label="Status Pembayaran"
icon={DollarSign}
isActive={activeTab === 'payments'}
onClick={setActiveTab}
/>
<TabButton
id="expenses"
label="Pengeluaran"
icon={Calculator}
isActive={activeTab === 'expenses'}
onClick={setActiveTab}
/>
</div>
{/* Dashboard Cards */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<div className="bg-white/90 backdrop-blur-sm rounded-xl p-6 shadow-lg border border-white/20">
<h3 className="text-gray-600 text-sm font-medium">Total Customer</h3>
<p className="text-3xl font-bold text-gray-800">{customers.length}</p>
</div>
<div className="bg-white/90 backdrop-blur-sm rounded-xl p-6 shadow-lg border border-white/20">
<h3 className="text-gray-600 text-sm font-medium">Pendapatan</h3>
<p className="text-2xl font-bold text-green-600">{formatCurrency(totalRevenue)}</p>
</div>
<div className="bg-white/90 backdrop-blur-sm rounded-xl p-6 shadow-lg border border-white/20">
<h3 className="text-gray-600 text-sm font-medium">Pengeluaran</h3>
<p className="text-2xl font-bold text-red-600">{formatCurrency(totalExpenses)}</p>
</div>
<div className="bg-white/90 backdrop-blur-sm rounded-xl p-6 shadow-lg border border-white/20">
<h3 className="text-gray-600 text-sm font-medium">Bagi Hasil (1/4)</h3>
<p className="text-2xl font-bold text-blue-600">{formatCurrency(profitShare)}</p>
</div>
</div>
{/* Content Area */}
<div className="bg-white/95 backdrop-blur-sm rounded-2xl shadow-2xl p-8 border border-white/20">
{activeTab === 'customers' && (
<div>
<h2 className="text-2xl font-bold text-gray-800 mb-6 flex items-center">
<Users className="mr-3 text-green-600" />
Manajemen Customer
</h2>
{/* Form Tambah Customer */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8 p-6 bg-green-50 rounded-xl border border-green-200">
<input
type="text"
placeholder="Nama Customer"
value={newCustomer.name}
onChange={(e) => setNewCustomer({...newCustomer, name: e.target.value})}
className="px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
<input
type="text"
placeholder="Paket WiFi"
value={newCustomer.package}
onChange={(e) => setNewCustomer({...newCustomer, package: e.target.value})}
className="px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
<input
type="number"
placeholder="Biaya (Rp)"
value={newCustomer.payment}
onChange={(e) => setNewCustomer({...newCustomer, payment: e.target.value})}
className="px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
<button
onClick={addCustomer}
className="bg-green-600 text-white px-6 py-3 rounded-lg hover:bg-green-700 transition-colors flex items-center justify-center font-medium"
>
<Plus size={20} className="mr-2" />
Tambah
</button>
</div>
{/* Tabel Customer */}
<div className="overflow-x-auto">
<table className="w-full border-collapse">
<thead>
<tr className="bg-gray-100">
<th className="border border-gray-300 px-4 py-3 text-left font-semibold">No</th>
<th className="border border-gray-300 px-4 py-3 text-left font-semibold">Nama</th>
<th className="border border-gray-300 px-4 py-3 text-left font-semibold">Paket</th>
<th className="border border-gray-300 px-4 py-3 text-left font-semibold">Biaya</th>
<th className="border border-gray-300 px-4 py-3 text-left font-semibold">Tanggal</th>
<th className="border border-gray-300 px-4 py-3 text-left font-semibold">Status</th>
<th className="border border-gray-300 px-4 py-3 text-center font-semibold">Aksi</th>
</tr>
</thead>
<tbody>
{customers.map((customer, index) => (
<tr key={customer.id} className="hover:bg-gray-50">
<td className="border border-gray-300 px-4 py-3">{index + 1}</td>
<td className="border border-gray-300 px-4 py-3 font-medium">{customer.name}</td>
<td className="border border-gray-300 px-4 py-3">{customer.package}</td>
<td className="border border-gray-300 px-4 py-3">{formatCurrency(customer.payment)}</td>
<td className="border border-gray-300 px-4 py-3">{customer.addedDate}</td>
<td className="border border-gray-300 px-4 py-3">
<span className={`px-3 py-1 rounded-full text-sm font-medium ${
customer.isPaid
? 'bg-green-100 text-green-800'
: 'bg-red-100 text-red-800'
}`}>
{customer.isPaid ? 'Lunas' : 'Belum Lunas'}
</span>
</td>
<td className="border border-gray-300 px-4 py-3 text-center">
<div className="flex items-center justify-center space-x-2">
<button
onClick={() => startEditCustomer(customer)}
className="bg-blue-500 text-white px-3 py-2 rounded-lg hover:bg-blue-600 transition-all duration-200 flex items-center justify-center shadow-md hover:shadow-lg transform hover:scale-105 active:scale-95"
title={`Edit Customer: ${customer.name}`}
>
<Edit3 size={16} className="mr-1" />
<span className="text-sm font-medium">Edit</span>
</button>
<button
onClick={() => deleteCustomer(customer.id, customer.name)}
className="bg-red-500 text-white px-3 py-2 rounded-lg hover:bg-red-600 transition-all duration-200 flex items-center justify-center shadow-md hover:shadow-lg transform hover:scale-105 active:scale-95"
title={`Hapus Customer: ${customer.name}`}
>
<Trash2 size={16} className="mr-1" />
<span className="text-sm font-medium">Hapus</span>
</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
{customers.length === 0 && (
<div className="text-center py-8 text-gray-500">
Belum ada customer yang terdaftar
</div>
)}
</div>
</div>
)}
{/* Modal Edit Customer */}
{editingCustomer && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-2xl p-8 w-full max-w-md mx-4 shadow-2xl">
<div className="flex items-center justify-between mb-6">
<h3 className="text-2xl font-bold text-gray-800 flex items-center">
<Edit3 className="mr-3 text-blue-600" />
Edit Customer
</h3>
<button
onClick={cancelEdit}
className="text-gray-400 hover:text-gray-600 transition-colors"
>
<X size={24} />
</button>
</div>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Nama Customer</label>
<input
type="text"
value={editForm.name}
onChange={(e) => setEditForm({...editForm, name: e.target.value})}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Masukkan nama customer"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Paket WiFi</label>
<input
type="text"
value={editForm.package}
onChange={(e) => setEditForm({...editForm, package: e.target.value})}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Contoh: Paket 10Mbps"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Biaya Pembayaran</label>
<input
type="number"
value={editForm.payment}
onChange={(e) => setEditForm({...editForm, payment: e.target.value})}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Masukkan biaya dalam Rupiah"
/>
</div>
</div>
<div className="flex space-x-4 mt-8">
<button
onClick={saveEditCustomer}
className="flex-1 bg-blue-600 text-white py-3 px-6 rounded-lg hover:bg-blue-700 transition-colors font-medium flex items-center justify-center"
>
<Edit3 size={18} className="mr-2" />
Simpan Perubahan
</button>
<button
onClick={cancelEdit}
className="flex-1 bg-gray-500 text-white py-3 px-6 rounded-lg hover:bg-gray-600 transition-colors font-medium"
>
Batal
</button>
</div>
</div>
</div>
)}
{activeTab === 'payments' && (
<div>
<h2 className="text-2xl font-bold text-gray-800 mb-6 flex items-center">
<DollarSign className="mr-3 text-green-600" />
Status Pembayaran
</h2>
{/* Search Bar */}
<div className="relative mb-6">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
<input
type="text"
placeholder="Cari nama customer..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
</div>
{/* Status Pembayaran */}
<div className="space-y-4">
{filteredCustomers.map((customer) => (
<div key={customer.id} className="flex items-center justify-between p-4 border border-gray-200 rounded-lg hover:shadow-md transition-shadow">
<div className="flex-1">
<h3 className="font-semibold text-gray-800">{customer.name}</h3>
<p className="text-gray-600">{customer.package} - {formatCurrency(customer.payment)}</p>
</div>
<button
onClick={() => togglePaymentStatus(customer.id)}
className={`px-6 py-2 rounded-full font-medium transition-colors ${
customer.isPaid
? 'bg-green-500 text-white hover:bg-green-600'
: 'bg-red-500 text-white hover:bg-red-600'
}`}
>
{customer.isPaid ? 'Lunas' : 'Belum Lunas'}
</button>
</div>
))}
{filteredCustomers.length === 0 && (
<div className="text-center py-8 text-gray-500">
{searchTerm ? 'Customer tidak ditemukan' : 'Belum ada customer'}
</div>
)}
</div>
</div>
)}
{activeTab === 'expenses' && (
<div>
<h2 className="text-2xl font-bold text-gray-800 mb-6 flex items-center">
<Calculator className="mr-3 text-green-600" />
Pengeluaran Operasional & Bagi Hasil
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Form Pengeluaran */}
<div className="space-y-6">
<h3 className="text-xl font-semibold text-gray-700 mb-4">Input Pengeluaran</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Biaya Listrik</label>
<input
type="number"
placeholder="0"
value={expenses.electricity}
onChange={(e) => setExpenses({...expenses, electricity: e.target.value})}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Maintenance</label>
<input
type="number"
placeholder="0"
value={expenses.maintenance}
onChange={(e) => setExpenses({...expenses, maintenance: e.target.value})}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Billing</label>
<input
type="number"
placeholder="0"
value={expenses.billing}
onChange={(e) => setExpenses({...expenses, billing: e.target.value})}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Bandwidth</label>
<input
type="number"
placeholder="0"
value={expenses.bandwidth}
onChange={(e) => setExpenses({...expenses, bandwidth: e.target.value})}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent"
/>
</div>
</div>
</div>
{/* Summary & Bagi Hasil */}
<div className="space-y-6">
<h3 className="text-xl font-semibold text-gray-700 mb-4">Ringkasan Keuangan</h3>
<div className="space-y-4">
<div className="bg-green-50 p-4 rounded-lg border border-green-200">
<div className="flex justify-between items-center">
<span className="text-green-700 font-medium">Total Pendapatan</span>
<span className="text-green-800 font-bold text-lg">{formatCurrency(totalRevenue)}</span>
</div>
</div>
<div className="bg-red-50 p-4 rounded-lg border border-red-200">
<div className="flex justify-between items-center">
<span className="text-red-700 font-medium">Total Pengeluaran</span>
<span className="text-red-800 font-bold text-lg">{formatCurrency(totalExpenses)}</span>
</div>
</div>
<div className="bg-blue-50 p-4 rounded-lg border border-blue-200">
<div className="flex justify-between items-center">
<span className="text-blue-700 font-medium">Pendapatan Bersih</span>
<span className="text-blue-800 font-bold text-lg">{formatCurrency(netRevenue)}</span>
</div>
</div>
<div className="bg-purple-50 p-6 rounded-lg border-2 border-purple-300">
<h4 className="text-purple-700 font-semibold mb-3">Bagi Hasil (Dibagi 4)</h4>
<div className="text-center">
<span className="text-purple-800 font-bold text-2xl">{formatCurrency(profitShare)}</span>
<p className="text-purple-600 text-sm mt-1">per bagian</p>
</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
</div>
</div>
); };
export default KenangaWiFiSystem;