Skip to content
View KenangaNet's full-sized avatar
  • Joined Sep 19, 2025

Block or report KenangaNet

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Please don't include any personal information such as legal names or email addresses. Maximum 250 characters, markdown supported. This note will be visible to only you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
KenangaNet/README.md

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 (

{/* Header */}

Kenanga.Net

Sistem Manajemen Pembayaran WiFi

    {/* 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;

Popular repositories Loading

  1. KenangaNet KenangaNet Public

    HTML