JSFiddle - React, Tailwind, and code Playground

by oktaviardi pratama

HTML

<div class="max-w-6xl mx-auto grid grid-cols-1 lg:grid-cols-2 gap-6">
    <!-- Form -->
    <div class="bg-white p-6 rounded-lg shadow">
      <h2 class="text-xl font-bold mb-4">Form Slip Gaji (Editable)</h2>

      <label class="block text-sm font-medium">Nama Perusahaan</label>
      <input id="company" value="PT. Zombie Capitalism" class="w-full border p-2 rounded mb-2" />

      <label class="block text-sm font-medium">Alamat Perusahaan</label>
      <textarea id="address" class="w-full border p-2 rounded mb-2" rows="3">Jl. Kebraon no.27 karangpilang
Surabaya
Jawa Timur</textarea>

      <div class="grid grid-cols-2 gap-2">
        <div>
          <label class="block text-sm font-medium">Periode</label>
          <input id="period" value="September 2025" class="w-full border p-2 rounded mb-2" />
        </div>
        <div>
          <label class="block text-sm font-medium">Karyawan</label>
          <input id="employee" value="Indra L Brugman" class="w-full border p-2 rounded mb-2" />
        </div>
      </div>

      <div class="grid grid-cols-2 gap-2">
        <div>
          <label class="block text-sm font-medium">Jabatan</label>
          <input id="position" value="Operasional" class="w-full border p-2 rounded mb-2" />
        </div>
        <div>
          <label class="block text-sm font-medium">Status</label>
          <input id="status" value="Karyawan Kontrak" class="w-full border p-2 rounded mb-2" />
        </div>
      </div>

      <div class="mt-4">
        <h3 class="font-semibold">Penerimaan (Earnings)</h3>
        <div id="earnings"></div>
        <button onclick="addEarning()" class="mt-2 text-sm text-blue-600">+ Tambah Penerimaan</button>
      </div>

      <div class="mt-4">
        <h3 class="font-semibold">Pengurangan (Deductions)</h3>
        <div id="deductions"></div>
        <button onclick="addDeduction()" class="mt-2 text-sm text-blue-600">+ Tambah Pengurangan</button>
     ...

CSS

body{padding:20px;font-family:Inter, system-ui, Arial;}

JavaScript

let earnings = [
  { label: "Gaji Pokok", value: 2300000 },
  { label: "Tunjangan Jabatan", value: 625000 },
  { label: "Tunjangan Makan", value: 500000 },
];
let deductions = [
  { label: "Iuran BPJS Kesehatan", value: 23000 },
  { label: "Iuran BPJS Ketenagakerjaan", value: 46000 },
  { label: "Iuran BPJS Pensiun", value: 23000 },
];
let signaturePad;
let signatureData = "";

function init() {
  renderLists();
  updatePreview();
  const canvas = document.getElementById("signature-pad");
  signaturePad = new SignaturePad(canvas);
  canvas.width = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;
  signaturePad.onEnd = () => {
    signatureData = signaturePad.toDataURL();
    updatePreview();
  };
}

function fmt(n) {
  return Number(n||0).toLocaleString("id-ID");
}

function renderLists() {
  const earnDiv = document.getElementById("earnings");
  earnDiv.innerHTML = "";
  earnings.forEach((e,i) => {
    earnDiv.innerHTML += `<div class='flex gap-2 items-center mt-2'>
      <input value="${e.label}" onchange="updateEarning(${i}, 'label', this.value)" class='flex-1 border p-1 rounded'/>
      <input value="${e.value}" onchange="updateEarning(${i}, 'value', this.value)" class='w-32 border p-1 rounded text-right'/>
      <button onclick="removeEarning(${i})" class='text-red-600'>Hapus</button>
    </div>`;
  });

  const dedDiv = document.getElementById("deductions");
  dedDiv.innerHTML = "";
  deductions.forEach((d,i) => {
    dedDiv.innerHTML += `<div class='flex gap-2 items-center mt-2'>
      <input value="${d.label}" onchange="updateDeduction(${i}, 'label', this.value)" class='flex-1 border p-1 rounded'/>
      <input value="${d.value}" onchange="updateDeduction(${i}, 'value', this.value)" class='w-32 border p-1 rounded text-right'/>
      <button onclick="removeDeduction(${i})" class='text-red-600'>Hapus</button>
    </div>`;
  });

  updatePreview();
}

function updateEarning(i,field,val){
 ...