update: tutorial, datatables pengangkutan dan olah

main
marszayn 2025-08-27 23:48:00 +07:00
parent 6d0bf76cb4
commit cf5106ec70
20 changed files with 3621 additions and 263 deletions

View File

@ -33,6 +33,12 @@ public class WebsiteController : Controller
return View("~/Views/Website/Kontak/Index.cshtml");
}
[HttpGet("tutorial")]
public IActionResult Tutorial()
{
return View("~/Views/Website/Tutorial/Index.cshtml");
}
[HttpGet("usaha")]
public IActionResult Usaha()
{

View File

@ -27,79 +27,217 @@
</div>
</div>
<div class="max-w-6xl mx-auto ">
<div class="bg-white rounded-lg shadow-lg p-6 mb-8">
<div class="flex items-start space-x-4 mb-4">
<div class="bg-blue-100 rounded-full p-3">
<svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-6a2 2 0 012-2h6m2 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2z"></path>
</svg>
</div>
<div>
<h2 class="text-2xl font-semibold text-gray-800 mb-2">Pengangkutan Residu Sampah</h2>
<p class="text-gray-600 leading-relaxed mb-2">
Pelaksanaan pengangkutan residu sampah dari usaha dan/atau kegiatan serta kawasan telah diatur dalam <span class="font-semibold text-blue-600">Peraturan Daerah Nomor 3 Tahun 2020 Pasal 36 ayat (2)</span>:
</p>
<blockquote class="mt-2 p-4 bg-blue-50 border-l-4 border-blue-500 italic text-blue-800">
“Pengangkutan residu sampah kawasan dari TPS dan/atau TPS 3R kawasan sebagaimana dimaksud pada ayat (1), ke TPST menjadi kewajiban penanggung jawab dan/atau pengelola kawasan dan dapat dikerjasamakan dengan badan usaha di bidang kebersihan.”
</blockquote>
</div>
</div>
<div class="mt-6">
<h3 class="text-xl font-semibold text-gray-800 mb-2">Izin Usaha Pelayanan Angkutan</h3>
<p class="text-gray-600 mb-2">
Badan usaha yang melakukan pengangkutan sampah wajib memiliki izin usaha pelayanan angkutan di bidang kebersihan sesuai <span class="font-semibold text-blue-600">Peraturan Gubernur Nomor 47 Tahun 2017</span>. Pendaftaran dilakukan melalui <span class="font-semibold text-blue-600">UP PMPTSP Kota</span> dengan kelengkapan dokumen sesuai ketentuan.
</p>
<ul class="list-disc pl-5 text-gray-600 space-y-1 mb-4">
<li>Pengecekan kendaraan dilakukan bersama Tim Teknis Bersama (UP PMPTSP Kota & Dinas Lingkungan Hidup).</li>
<li>Izin diterbitkan jika persyaratan administrasi dan teknis kendaraan terpenuhi.</li>
</ul>
</div>
<div class="mt-6">
<h3 class="text-xl font-semibold text-gray-800 mb-2">Persyaratan Teknis Kendaraan</h3>
<div class="bg-gray-50 rounded-lg p-4 mb-4">
<ul class="list-decimal pl-5 text-gray-700 space-y-2">
<li>Berbadan usaha.</li>
<li>Jenis truk yang diizinkan: <span class="font-semibold">Arm Roll Truck (6-10 m<sup>3</sup>), Dump Truck (6-14 m<sup>3</sup>), Compactor (6-10 m<sup>3</sup>)</span>.</li>
<li>Truk wajib lulus uji KIR.</li>
<li>Bak truk tidak bocor, ada tanggul penahan air lindi, bahan tahan korosif.</li>
<li>Bak penampung air lindi dari plat besi/sejenisnya, model & dimensi sesuai kebutuhan, pipa/selang kuat & tahan bocor.</li>
<li>Umur truk maksimal 6 tahun saat pendaftaran:
<div class="overflow-x-auto mt-2">
<table class="min-w-full text-sm text-left border border-gray-200">
<thead>
<tr class="bg-blue-100">
<th class="px-2 py-1 border">Umur Kendaraan</th>
<th class="px-2 py-1 border">Masa Berlaku Izin</th>
</tr>
</thead>
<tbody>
<tr>
<td class="px-2 py-1 border">0 4 tahun</td>
<td class="px-2 py-1 border">Maks. 3 tahun</td>
</tr>
<tr>
<td class="px-2 py-1 border">5 tahun</td>
<td class="px-2 py-1 border">Maks. 2 tahun</td>
</tr>
<tr>
<td class="px-2 py-1 border">6 tahun</td>
<td class="px-2 py-1 border">Maks. 1 tahun</td>
</tr>
</tbody>
</table>
<div class="max-w-6xl mx-auto px-4">
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section1')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M9 1L5 3l4 2 4-2-4-2z"></path>
</svg>
</div>
</li>
<li>Domisili perusahaan di DKI Jakarta.</li>
<li>STNK truk sesuai domisili perusahaan atau wilayah hukum Polda Metro Jaya.</li>
<li>STNK atas nama pemohon atau lampirkan surat pernyataan penguasaan kendaraan & perjanjian kerja sama.</li>
<li>Atribut khusus berupa stiker identitas perusahaan & nomor pintu kendaraan (tidak boleh atribut Pemprov DKI/DLH).</li>
<li>Truk dilengkapi GPS & akses login untuk DLH DKI Jakarta.</li>
<li>Truk dilengkapi jaring, terpal, dan APD untuk supir & kru.</li>
<li>Perusahaan wajib menyediakan lahan parkir sesuai jumlah kendaraan, dibuktikan surat & foto lokasi.</li>
</ul>
<div>
<h2 class="text-xl font-bold text-gray-800 mb-1">Pengangkutan Residu Sampah</h2>
<p class="text-gray-600 text-sm">Pelaksanaan pengangkutan residu sampah sesuai regulasi DKI Jakarta</p>
</div>
</div>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
</div>
<div class="dropdown-content" id="section1">
<div>
<p class="text-gray-600 leading-relaxed mb-4">
Pelaksanaan pengangkutan residu sampah dari usaha dan/atau kegiatan serta kawasan telah diatur dalam <span class="font-semibold text-blue-600">Peraturan Daerah Nomor 3 Tahun 2020 Pasal 36 ayat (2)</span>:
</p>
<blockquote class="mt-4 p-4 bg-blue-50 border-l-4 border-blue-500 italic text-blue-800 rounded-r-lg">
"Pengangkutan residu sampah kawasan dari TPS dan/atau TPS 3R kawasan sebagaimana dimaksud pada ayat (1), ke TPST menjadi kewajiban penanggung jawab dan/atau pengelola kawasan dan dapat dikerjasamakan dengan badan usaha di bidang kebersihan."
</blockquote>
</div>
</div>
</div>
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section2')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div>
<h2 class="text-xl font-bold text-gray-800 mb-1">Izin Usaha Pelayanan Angkutan</h2>
<p class="text-gray-600 text-sm">Persyaratan izin usaha untuk pengangkutan sampah</p>
</div>
</div>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
</div>
</div>
<div class="dropdown-content" id="section2">
<div>
<p class="text-gray-600 mb-4">
Badan usaha yang melakukan pengangkutan sampah wajib memiliki izin usaha pelayanan angkutan di bidang kebersihan sesuai <span class="font-semibold text-blue-600">Peraturan Gubernur Nomor 47 Tahun 2017</span>. Pendaftaran dilakukan melalui <span class="font-semibold text-blue-600">UP PMPTSP Kota</span> dengan kelengkapan dokumen sesuai ketentuan.
</p>
<div class="bg-green-50 rounded-lg p-4 mb-4">
<ul class="list-disc pl-5 text-gray-600 space-y-2">
<li class="flex items-start">
<span class=" w-2 h-2 bg-green-500 rounded-full mt-2 mr-3 flex-shrink-0"></span>
Pengecekan kendaraan dilakukan bersama Tim Teknis Bersama (UP PMPTSP Kota & Dinas Lingkungan Hidup)
</li>
<li class="flex items-start">
<span class=" w-2 h-2 bg-green-500 rounded-full mt-2 mr-3 flex-shrink-0"></span>
Izin diterbitkan jika persyaratan administrasi dan teknis kendaraan terpenuhi
</li>
</ul>
</div>
</div>
</div>
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section3')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-purple-500 to-purple-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"></path>
</svg>
</div>
<div>
<h2 class="text-xl font-bold text-gray-800 mb-1">Persyaratan Teknis Kendaraan</h2>
<p class="text-gray-600 text-sm">Spesifikasi dan persyaratan kendaraan pengangkut sampah</p>
</div>
</div>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
</div>
<div class="dropdown-content" id="section3">
<div>
<div class="bg-gray-50 rounded-lg p-4 mb-6">
<ul class="pl-5 text-gray-700 space-y-3">
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">1</span>
Berbadan usaha
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">2</span>
Jenis truk yang diizinkan: <span class="font-semibold text-purple-600">Arm Roll Truck (6-10 m³), Dump Truck (6-14 m³), Compactor (6-10 m³)</span>
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">3</span>
Truk wajib lulus uji KIR
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">4</span>
Bak truk tidak bocor, ada tanggul penahan air lindi, bahan tahan korosif
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">5</span>
Bak penampung air lindi dari plat besi/sejenisnya, model & dimensi sesuai kebutuhan, pipa/selang kuat & tahan bocor
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">6</span>
<div>
Umur truk maksimal 6 tahun saat pendaftaran
<div class="overflow-x-auto mt-3 text-left">
<table class="min-w-full text-sm text-left border border-gray-200 rounded-lg overflow-hidden">
<thead>
<tr class="bg-purple-100">
<th class="px-3 py-2 border font-semibold text-purple-800 text-left">Umur Kendaraan</th>
<th class="px-3 py-2 border font-semibold text-purple-800 text-left">Masa Berlaku Izin</th>
</tr>
</thead>
<tbody>
<tr class="hover:bg-purple-50">
<td class="px-3 py-2 border">0 4 tahun</td>
<td class="px-3 py-2 border">Maks. 3 tahun</td>
</tr>
<tr class="hover:bg-purple-50">
<td class="px-3 py-2 border">5 tahun</td>
<td class="px-3 py-2 border">Maks. 2 tahun</td>
</tr>
<tr class="hover:bg-purple-50"></tr>
<td class="px-3 py-2 border">6 tahun</td>
<td class="px-3 py-2 border">Maks. 1 tahun</td>
</tr>
</tbody>
</table>
</div>
</div>
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">7</span>
Domisili perusahaan di DKI Jakarta
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">8</span>
STNK truk sesuai domisili perusahaan atau wilayah hukum Polda Metro Jaya
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">9</span>
STNK atas nama pemohon atau lampirkan surat pernyataan penguasaan kendaraan & perjanjian kerja sama
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">10</span>
Atribut khusus berupa stiker identitas perusahaan & nomor pintu kendaraan (tidak boleh atribut Pemprov DKI/DLH)
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">11</span>
Truk dilengkapi GPS & akses login untuk DLH DKI Jakarta
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">12</span>
Truk dilengkapi jaring, terpal, dan APD untuk supir & kru
</li>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">13</span>
Perusahaan wajib menyediakan lahan parkir sesuai jumlah kendaraan, dibuktikan surat & foto lokasi
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="my-12 max-w-6xl mx-auto px-4">
<div class="bg-white rounded-xl shadow-lg p-6 border border-gray-200">
<div class="mb-6">
<h2 class="text-2xl font-bold text-gray-800 mb-2">📋 Daftar Jasa Pengangkutan Sampah</h2>
<p class="text-gray-600">Data perusahaan yang memiliki izin pengangkutan sampah di DKI Jakarta</p>
</div>
<div class="overflow-x-auto">
<table id="pengangkutanTable" class="min-w-full bg-white">
<thead class="bg-cyan-400 text-white">
<tr>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">No</th>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">Perusahaan</th>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">Alamat</th>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">Berlaku Hingga</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
</tbody>
</table>
</div>
<div class="mt-4 text-sm text-gray-500 text-center" id="loadingIndicator">
<div class="inline-flex items-center">
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Memuat data...
</div>
</div>
</div>
</div>
</div>

View File

@ -27,228 +27,296 @@
</div>
</div>
<div class="max-w-6xl mx-auto px-4 lg:px-6 z-20">
<div class="bg-white rounded-2xl p-8 mb-7 border border-gray-200">
<div class="flex flex-col lg:flex-row items-start gap-6">
<div class="bg-gradient-to-br from-blue-500 to-cyan-600 rounded-xl p-4 flex-shrink-0">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div class="flex-1">
<h2 class="text-2xl font-bold text-gray-900 mb-4">Izin Usaha Pengolahan Sampah</h2>
<p class="text-gray-700 leading-relaxed mb-6">
Dalam melaksanakan kegiatan usaha pengolahan sampah, badan usaha yang melakukan usaha pengolahan sampah wajib memiliki izin usaha pengolahan sampah. Jenis izin yang diterbitkan sesuai dengan <span class="font-semibold text-blue-600">Peraturan Gubernur Nomor 47 Tahun 2017</span> tentang Petunjuk Pelaksanaan Pelayanan Terpadu Satu Pintu, adapun jenis izin pengangkutan sampah yaitu Izin Usaha Pengelolaan Sampah.
</p>
<p class="text-gray-700 leading-relaxed">
Mekanisme perolehan Izin Usaha didaftarkan melalui Unit Pengelola Penanaman Modal dan Pelayanan Terpadu Satu Pintu Kota (UP PMPTSP Kota). Adapun formulir dan kelengkapan dokumen sesuai dengan ketentuan yang diatur oleh UP PMPTSP Kota. Setelah berkas administrasi dinyatakan lengkap dan lolos verifikasi, maka dilanjutkan dengan pengecekan/survey terhadap lokasi dan teknologi pengolahan sampah yang diajukan dalam proses permohonan izin.
</p>
</div>
</div>
</div>
<div class="bg-white rounded-2xl p-8 mb-7 border border-gray-200">
<div class="text-center mb-8">
<h3 class="text-2xl font-bold text-gray-900 mb-3">Alur Permohonan Izin</h3>
<div class="w-24 h-1 bg-gradient-to-r from-blue-500 to-cyan-500 mx-auto rounded-full"></div>
</div>
<div class="flex justify-center mb-8">
<img src="@Url.Content("~/website/images/alur_jasa.webp")" class="rounded-2xl border border-gray-200 shadow-lg max-w-full h-auto" alt="Gambaran Alur">
</div>
<div class="bg-gradient-to-r from-blue-50 to-cyan-50 border-l-4 border-blue-500 p-6 rounded-r-xl">
<p class="text-gray-700 leading-relaxed">
Pelaksanaan survey dimaksud dilakukan bersama-sama oleh Tim Teknis Bersama yang terdiri dari unsur UP PMPTSP Kota dan Dinas Lingkungan Hidup. Izin akan diterbitkan apabila telah memenuhi persyaratan administrasi dan hasil survey telah disetujui atau dinyatakan sesuai persyaratan teknis oleh Tim Teknis Bersama.
</p>
</div>
</div>
<div class="bg-white rounded-2xl p-8 mb-7 border border-gray-200">
<div class="flex items-center gap-4 mb-6">
<div class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"></path>
</svg>
</div>
<div>
<h3 class="text-2xl font-bold text-gray-900">Teknologi Pengolahan</h3>
<p class="text-gray-600">Teknologi yang diizinkan untuk pengolahan sampah</p>
</div>
</div>
<p class="text-gray-700 leading-relaxed mb-6">
Dalam pelaksanaan survey/pengecekan lokasi dan teknologi pengolahan sampah, dilakukan pemeriksaan kesesuaian persyaratan teknis yang diatur dalam <span class="font-semibold text-blue-600">SK Kepala Dinas Lingkungan Hidup Nomor 374 Tahun 2017</span> tentang Persyaratan Teknis Izin Usaha Pengelolaan Sampah.
</p>
<div class="grid md:grid-cols-2 gap-6">
<div class="bg-gradient-to-br from-blue-50 to-indigo-50 p-6 rounded-xl border border-blue-200">
<h4 class="font-bold text-blue-900 mb-3">Teknologi Fisik</h4>
<p class="text-blue-800 text-sm">Pengurangan ukuran, pemadatan, pemisahan magnetis, masa-jenis, dan optik</p>
</div>
<div class="bg-gradient-to-br from-green-50 to-emerald-50 p-6 rounded-xl border border-green-200">
<h4 class="font-bold text-green-900 mb-3">Teknologi Biologi</h4>
<p class="text-green-800 text-sm">Pengolahan aerobik dan/atau anaerobik seperti pengomposan dan biogasifikasi</p>
</div>
<div class="bg-gradient-to-br from-orange-50 to-red-50 p-6 rounded-xl border border-orange-200">
<h4 class="font-bold text-orange-900 mb-3">Teknologi Termal</h4>
<p class="text-orange-800 text-sm">Gasifikasi, pirolisis, plasma dan insenerasi</p>
</div>
<div class="bg-gradient-to-br from-purple-50 to-pink-50 p-6 rounded-xl border border-purple-200">
<h4 class="font-bold text-purple-900 mb-3">Teknologi Lainnya</h4>
<p class="text-purple-800 text-sm">Teknologi lain atau gabungan dari beberapa macam teknologi</p>
</div>
</div>
</div>
<div class="grid lg:grid-cols-2 gap-8 mb-7">
<div class="bg-white rounded-2xl p-8 border border-gray-200">
<div class="flex items-center gap-4 mb-6">
<div class="bg-gradient-to-br from-blue-500 to-cyan-600 rounded-xl p-4">
<div class="max-w-6xl mx-auto px-4">
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section1')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div>
<h3 class="text-xl font-bold text-gray-900">Persyaratan Umum</h3>
<h2 class="text-xl font-bold text-gray-800 mb-1">Izin Usaha Pengolahan Sampah</h2>
<p class="text-gray-600 text-sm">Persyaratan dan mekanisme perolehan izin usaha pengolahan sampah</p>
</div>
</div>
<div class="space-y-4">
<div class="bg-gradient-to-r from-gray-50 to-slate-50 p-4 rounded-xl border border-gray-200">
<ul class="text-gray-700 space-y-2 text-sm">
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Pemohon wajib berbadan usaha</span>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
</div>
<div class="dropdown-content" id="section1">
<div>
<p class="text-gray-600 leading-relaxed mb-4">
Dalam melaksanakan kegiatan usaha pengolahan sampah, badan usaha yang melakukan usaha pengolahan sampah wajib memiliki izin usaha pengolahan sampah. Jenis izin yang diterbitkan sesuai dengan <span class="font-semibold text-blue-600">Peraturan Gubernur Nomor 47 Tahun 2017</span> tentang Petunjuk Pelaksanaan Pelayanan Terpadu Satu Pintu.
</p>
<p class="text-gray-600 leading-relaxed mb-4">
Mekanisme perolehan Izin Usaha didaftarkan melalui Unit Pengelola Penanaman Modal dan Pelayanan Terpadu Satu Pintu Kota (UP PMPTSP Kota). Adapun formulir dan kelengkapan dokumen sesuai dengan ketentuan yang diatur oleh UP PMPTSP Kota.
</p>
<div class="bg-blue-50 rounded-lg p-4 mb-4">
<p class="text-blue-800 text-sm">
<strong>Proses Survey:</strong> Setelah berkas administrasi dinyatakan lengkap dan lolos verifikasi, dilanjutkan dengan pengecekan/survey terhadap lokasi dan teknologi pengolahan sampah yang diajukan dalam proses permohonan izin.
</p>
</div>
</div>
</div>
</div>
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section2')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"></path>
</svg>
</div>
<div>
<h2 class="text-xl font-bold text-gray-800 mb-1">Teknologi Pengolahan</h2>
<p class="text-gray-600 text-sm">Jenis teknologi yang diizinkan untuk pengolahan sampah</p>
</div>
</div>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
</div>
<div class="dropdown-content" id="section2">
<div>
<p class="text-gray-600 mb-4">
Dalam pelaksanaan survey/pengecekan lokasi dan teknologi pengolahan sampah, dilakukan pemeriksaan kesesuaian persyaratan teknis yang diatur dalam <span class="font-semibold text-blue-600">SK Kepala Dinas Lingkungan Hidup Nomor 374 Tahun 2017</span> tentang Persyaratan Teknis Izin Usaha Pengelolaan Sampah.
</p>
<div class="grid md:grid-cols-2 gap-4 mb-4">
<div class="bg-blue-50 p-4 rounded-xl border border-blue-200">
<h4 class="font-bold text-blue-900 mb-2">Teknologi Fisik</h4>
<p class="text-blue-800 text-sm">Pengurangan ukuran, pemadatan, pemisahan magnetis, masa-jenis, dan optik</p>
</div>
<div class="bg-green-50 p-4 rounded-xl border border-green-200">
<h4 class="font-bold text-green-900 mb-2">Teknologi Biologi</h4>
<p class="text-green-800 text-sm">Pengolahan aerobik dan/atau anaerobik seperti pengomposan dan biogasifikasi</p>
</div>
<div class="bg-orange-50 p-4 rounded-xl border border-orange-200">
<h4 class="font-bold text-orange-900 mb-2">Teknologi Termal</h4>
<p class="text-orange-800 text-sm">Gasifikasi, pirolisis, plasma dan insenerasi</p>
</div>
<div class="bg-purple-50 p-4 rounded-xl border border-purple-200">
<h4 class="font-bold text-purple-900 mb-2">Teknologi Lainnya</h4>
<p class="text-purple-800 text-sm">Teknologi lain atau gabungan dari beberapa macam teknologi</p>
</div>
</div>
</div>
</div>
</div>
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section3')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-purple-500 to-purple-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div>
<h2 class="text-xl font-bold text-gray-800 mb-1">Persyaratan Umum</h2>
<p class="text-gray-600 text-sm">Persyaratan umum untuk izin usaha pengolahan sampah</p>
</div>
</div>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
</div>
<div class="dropdown-content" id="section3">
<div>
<div class="bg-gray-50 rounded-lg p-4 mb-6">
<ul class="pl-5 text-gray-700 space-y-3">
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">1</span>
Pemohon wajib berbadan usaha
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Melampirkan deskripsi dari lokasi kegiatan dengan tata letak (layout) di lokasi kegiatan dan terhadap bangunan sekelilingnya</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">2</span>
Melampirkan deskripsi dari lokasi kegiatan dengan tata letak (layout) di lokasi kegiatan
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Papan nama yang mudah terlihat dengan tulisan "Fasilitas Pengolahan Sampah Non B3" yang dipasang pada unit/bangunan pengolah sampah</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">3</span>
Papan nama yang mudah terlihat dengan tulisan "Fasilitas Pengolahan Sampah Non B3"
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Melampirkan dokumen rencana pengolahan sampah yang menjelaskan jenis, karakteristik, jumlah, komposisi dan asal/sumber sampah yang akan diolah</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">4</span>
Melampirkan dokumen rencana pengolahan sampah yang menjelaskan jenis, karakteristik, jumlah, komposisi dan asal/sumber sampah
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Melampirkan dokumen studi kelayakan</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">5</span>
Melampirkan dokumen studi kelayakan
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Melampirkan dokumen lingkungan (Amdal/UKL-UPL) dan izin lingkungan atau SPPL (Surat Pernyataan Pengelolaan Lingkungan)</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">6</span>
Melampirkan dokumen lingkungan (Amdal/UKL-UPL) dan izin lingkungan atau SPPL
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Umur truk sampah pada saat pendaftaran maksimal 6 tahun, dengan masa berlaku izin minimal 1 tahun dan maksimal 3 tahun</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">7</span>
Melampirkan DED/detailed engineering design fasilitas pengolahan sampah
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Melampirkan DED/detailed engineering design fasilitas pengolahan sampah</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">8</span>
Memiliki fasilitas pendukung berupa peralatan/instalasi pengendalian pencemaran lingkungan
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Memiliki fasilitas pendukung berupa peralatan/instalasi pengendalian pencemaran lingkungan (air dan/atau udara)</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">9</span>
Melampirkan Standar Operasional Prosedur (SOP)
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Melampirkan Standar Operasional Prosedur (SOP)</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">10</span>
Memiliki Alat Pelindung Diri (APD) untuk petugas
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Memiliki Alat Pelindung Diri (APD) untuk petugas</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">11</span>
Memiliki alat perlengkapan peralatan tanggap darurat
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Memiliki alat perlengkapan peralatan tanggap darurat</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">12</span>
Melampirkan Izin Gangguan Tempat Usaha Berdasarkan Undang-Undang Gangguan (UUG/HO)
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Melampirkan Izin Gangguan Tempat Usaha Berdasarkan Undang-Undang Gangguan (UUG/HO)</span>
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-1">✓</span>
<span>Memiliki fasilitas pendukung: ruang pemilahan dan bak penampung air lindi</span>
<li class="flex items-start">
<span class=" w-6 h-6 bg-purple-500 text-white text-sm rounded-full flex items-center justify-center mr-3 mt-0.5 flex-shrink-0">13</span>
Memiliki fasilitas pendukung: ruang pemilahan dan bak penampung air lindi
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-2xl p-8 border border-gray-200">
<div class="flex items-center gap-4 mb-6">
<div class="bg-gradient-to-br from-orange-500 to-red-600 rounded-xl p-4">
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section4')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-orange-500 to-red-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
</svg>
</div>
<div>
<h3 class="text-xl font-bold text-gray-900">Persyaratan Khusus</h3>
<h2 class="text-xl font-bold text-gray-800 mb-1">Persyaratan Khusus Teknologi</h2>
<p class="text-gray-600 text-sm">Persyaratan spesifik berdasarkan jenis teknologi yang digunakan</p>
</div>
</div>
<div class="space-y-4">
<div class="bg-gradient-to-r from-blue-50 to-cyan-50 p-4 rounded-xl border border-blue-200">
<h4 class="font-bold text-blue-900 mb-2">Teknologi Fisik</h4>
<p class="text-blue-800 text-sm">Kapasitas minimal 20 ton/hari atau luas lahan minimal 200 m²</p>
</div>
<div class="bg-gradient-to-r from-green-50 to-emerald-50 p-4 rounded-xl border border-green-200">
<h4 class="font-bold text-green-900 mb-2">Teknologi Biologi</h4>
<ul class="text-green-800 text-sm space-y-1">
<li>• Kapasitas minimal 10 ton/hari atau luas >200 m²</li>
<li>• Wajib memenuhi baku mutu kebauan</li>
<li>• Wajib memenuhi baku mutu air lindi</li>
</ul>
</div>
<div class="bg-gradient-to-r from-orange-50 to-red-50 p-4 rounded-xl border border-orange-200">
<h4 class="font-bold text-orange-900 mb-2">Teknologi Termal</h4>
<ul class="text-orange-800 text-sm space-y-1">
<li>• Insinerasi: minimal 8000°C</li>
<li>• Pirolisis: minimal 4000°C</li>
<li>• Gasifikasi: minimal 7000°C</li>
<li>• Plasma: minimal 5000°C</li>
<li>• Wajib memenuhi baku mutu emisi</li>
</ul>
</div>
<div class="bg-gradient-to-r from-purple-50 to-pink-50 p-4 rounded-xl border border-purple-200">
<h4 class="font-bold text-purple-900 mb-2">Teknologi Lainnya</h4>
<ul class="text-purple-800 text-sm space-y-1">
<li>• Kapasitas minimal 20 ton/hari atau luas lahan minimal 200 m2</li>
<li>• Wajib memenuhi persyaratan khusus pada semua jenis teknologi yang digunakan</li>
<li>• Memenuhi baku mutu lingkungan</li>
</ul>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
</div>
<div class="dropdown-content" id="section4">
<div>
<div class="space-y-4">
<div class="bg-blue-50 p-4 rounded-xl border border-blue-200">
<h4 class="font-bold text-blue-900 mb-2">Teknologi Fisik</h4>
<p class="text-blue-800 text-sm">Kapasitas minimal 20 ton/hari atau luas lahan minimal 200 m²</p>
</div>
<div class="bg-green-50 p-4 rounded-xl border border-green-200">
<h4 class="font-bold text-green-900 mb-2">Teknologi Biologi</h4>
<ul class="text-green-800 text-sm space-y-1">
<li>• Kapasitas minimal 10 ton/hari atau luas >200 m²</li>
<li>• Wajib memenuhi baku mutu kebauan</li>
<li>• Wajib memenuhi baku mutu air lindi</li>
</ul>
</div>
<div class="bg-orange-50 p-4 rounded-xl border border-orange-200">
<h4 class="font-bold text-orange-900 mb-2">Teknologi Termal</h4>
<ul class="text-orange-800 text-sm space-y-1">
<li>• Insinerasi: minimal 8000°C</li>
<li>• Pirolisis: minimal 4000°C</li>
<li>• Gasifikasi: minimal 7000°C</li>
<li>• Plasma: minimal 5000°C</li>
<li>• Wajib memenuhi baku mutu emisi</li>
</ul>
</div>
<div class="bg-purple-50 p-4 rounded-xl border border-purple-200">
<h4 class="font-bold text-purple-900 mb-2">Teknologi Lainnya</h4>
<ul class="text-purple-800 text-sm space-y-1">
<li>• Kapasitas minimal 20 ton/hari atau luas lahan minimal 200 m²</li>
<li>• Wajib memenuhi persyaratan khusus pada semua jenis teknologi yang digunakan</li>
<li>• Memenuhi baku mutu lingkungan</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="bg-gradient-to-r from-green-50 to-emerald-50 border border-green-200 rounded-2xl p-8 mb-7">
<div class="flex items-center gap-4 mb-6">
<div class="bg-green-500 rounded-full p-3">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<div class="mb-6">
<div class="dropdown-header" onclick="toggleDropdown('section5')">
<div class="flex items-center space-x-4">
<div class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-3 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div>
<h2 class="text-xl font-bold text-gray-800 mb-1">Kewajiban Setelah Memperoleh Izin</h2>
<p class="text-gray-600 text-sm">Kewajiban yang harus dipenuhi setelah mendapat izin usaha</p>
</div>
</div>
<div class="dropdown-icon flex items-center space-x-2">
<i class="w-4 h-4 text-gray-500 transition-colors duration-300" data-lucide="chevron-down"></i>
</div>
<h3 class="text-2xl font-bold text-green-800">Kewajiban Setelah Memperoleh Izin</h3>
</div>
<p class="text-green-700 mb-6 leading-relaxed">
Setelah memperoleh Izin Usaha Pengelolaan Sampah, penyedia jasa pengolahan sampah wajib melaporkan izinnya kepada Dinas Lingkungan Hidup Provinsi DKI Jakarta untuk melakukan pendaftaran/registrasi secara online melalui website ini.
</p>
<div class="bg-white p-6 rounded-xl border border-green-200 shadow-sm">
<h4 class="font-bold text-green-900 mb-4">Penyedia jasa pengolahan sampah wajib melakukan:</h4>
<div class="grid md:grid-cols-3 gap-4">
<div class="bg-green-100 p-4 rounded-lg text-center">
<div class="bg-green-500 text-white px-3 py-1 rounded-full text-sm font-bold mb-2 inline-block">1</div>
<p class="text-green-800 text-sm font-semibold">Pendaftaran sebagai penyedia jasa yang teregistrasi</p>
</div>
<div class="bg-green-100 p-4 rounded-lg text-center">
<div class="bg-green-500 text-white px-3 py-1 rounded-full text-sm font-bold mb-2 inline-block">2</div>
<p class="text-green-800 text-sm font-semibold">Melaporkan kontrak kerjasama pengolahan sampah</p>
</div>
<div class="bg-green-100 p-4 rounded-lg text-center">
<div class="bg-green-500 text-white px-3 py-1 rounded-full text-sm font-bold mb-2 inline-block">3</div>
<p class="text-green-800 text-sm font-semibold">Melaporkan hasil kegiatan pengolahan sampah</p>
<div class="dropdown-content" id="section5">
<div>
<p class="text-gray-600 mb-4 leading-relaxed">
Setelah memperoleh Izin Usaha Pengelolaan Sampah, penyedia jasa pengolahan sampah wajib melaporkan izinnya kepada Dinas Lingkungan Hidup Provinsi DKI Jakarta untuk melakukan pendaftaran/registrasi secara online melalui website ini.
</p>
<div class="bg-green-50 rounded-lg p-4 mb-4">
<h4 class="font-bold text-green-900 mb-3">Penyedia jasa pengolahan sampah wajib melakukan:</h4>
<div class="grid md:grid-cols-3 gap-4">
<div class="bg-white p-4 rounded-lg text-center border border-green-200">
<div class="bg-green-500 text-white px-3 py-1 rounded-full text-sm font-bold mb-2 inline-block">1</div>
<p class="text-green-800 text-sm font-semibold">Pendaftaran sebagai penyedia jasa yang teregistrasi</p>
</div>
<div class="bg-white p-4 rounded-lg text-center border border-green-200">
<div class="bg-green-500 text-white px-3 py-1 rounded-full text-sm font-bold mb-2 inline-block">2</div>
<p class="text-green-800 text-sm font-semibold">Melaporkan kontrak kerjasama pengolahan sampah</p>
</div>
<div class="bg-white p-4 rounded-lg text-center border border-green-200">
<div class="bg-green-500 text-white px-3 py-1 rounded-full text-sm font-bold mb-2 inline-block">3</div>
<p class="text-green-800 text-sm font-semibold">Melaporkan hasil kegiatan pengolahan sampah</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="my-12 max-w-6xl mx-auto px-4">
<div class="bg-white rounded-xl shadow-lg p-6 border border-gray-200">
<div class="mb-6">
<h2 class="text-2xl font-bold text-gray-800 mb-2">🏭 Daftar Jasa Pengolahan Sampah</h2>
<p class="text-gray-600">Data perusahaan yang memiliki izin pengolahan sampah di DKI Jakarta</p>
</div>
<div class="overflow-x-auto">
<table id="pengolahanTable" class="min-w-full bg-white">
<thead class="bg-cyan-400 text-white">
<tr>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">No</th>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">Perusahaan</th>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">Alamat</th>
<th class="px-6 py-4 text-left text-white text-sm font-semibold uppercase tracking-wider">Berlaku Hingga</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
</tbody>
</table>
</div>
<div class="mt-4 text-sm text-gray-500 text-center" id="loadingIndicator">
<div class="inline-flex items-center">
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Memuat data...
</div>
</div>
</div>
</div>
</div>

View File

@ -75,6 +75,33 @@
</p>
</div>
</div>
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<i class="w-5 h-5 text-cyan-500" data-lucide="phone"></i>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-1">Helpdesk Sistem Pesapakawan</h3>
<p class="text-gray-600">
<a href="https://wa.me/6285212436339?text=Halo%20Pesapakawan%2C%20saya%20ingin%20bertanya%20mengenai%20layanan%20pengelolaan%20sampah" class="hover:text-cyan-600 transition-colors">
0852-1243-6339
</a>
</p>
</div>
</div>
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<i class="w-5 h-5 text-cyan-500" data-lucide="phone"></i>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-1">Helpdesk BLUD UPST</h3>
<p class="text-gray-600">
<a href="https://wa.me/6282211001180?text=Halo%20Pesapakawan%2C%20saya%20ingin%20bertanya%20mengenai%20layanan%20pengelolaan%20sampah" class="hover:text-cyan-600 transition-colors">
0822-1100-1180
</a>
</p>
</div>
</div>
</div>
<div>

View File

@ -58,5 +58,80 @@
</p>
</div>
</div>
<div class="whatsapp-widget">
<div class="whatsapp-button" onclick="toggleWhatsAppWidget()">
<div class="whatsapp-icon">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893A11.821 11.821 0 0020.465 3.516"/>
</svg>
</div>
<div class="pulse-ring"></div>
<div class="pulse-ring-2"></div>
</div>
<div class="whatsapp-popup" id="whatsappPopup">
<div class="popup-header">
<div class="header-content">
<div class="avatar">
<i class="w-8 h-8 text-white" data-lucide="bot"></i>
<div class="online-indicator"></div>
</div>
<div class="header-text">
<h4>Pesapakawan Support</h4>
<p class="online-status">Online - Siap membantu Anda</p>
</div>
</div>
<button class="close-btn" onclick="toggleWhatsAppWidget()">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
</svg>
</button>
</div>
<div class="popup-body">
<div class="chat-message">
@* <div class="message-avatar">
<img src="@Url.Content("~/website/logo.svg")" alt="Support">
</div> *@
<div class="message-bubble">
<p>Halo! 👋</p>
<p>Selamat datang di Pesapakawan. Bagaimana kami bisa membantu Anda hari ini?</p>
<div class="message-time">
<span id="currentTime"></span>
</div>
</div>
</div>
@* <div class="quick-options">
<h5>Pilihan Bantuan Cepat:</h5>
<div class="options-list">
<button class="option-btn" onclick="showHelpdeskSelection('Informasi tentang layanan pengelolaan sampah')">
📋 Info Layanan
</button>
<button class="option-btn" onclick="showHelpdeskSelection('Cara mendaftar sebagai driver')">
🚛 Daftar Driver
</button>
<button class="option-btn" onclick="showHelpdeskSelection('Informasi penggunaan aplikasi')">
📱 Bantuan Aplikasi
</button>
<button class="option-btn" onclick="showHelpdeskSelection('Keluhan atau saran')">
💬 Keluhan & Saran
</button>
</div>
</div> *@
</div>
<div class="popup-footer">
<button class="whatsapp-chat-btn" onclick="showHelpdeskSelection('')">
<svg viewBox="0 0 24 24" fill="currentColor" class="chat-icon">
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893A11.821 11.821 0 0020.465 3.516"/>
</svg>
Pilih Helpdesk WhatsApp
</button>
</div>
</div>
</div>
</div>
</footer>

View File

@ -32,6 +32,10 @@
</div>
</div>
<a href="@Url.Action("Tutorial", "Website")" class="text-white hover:text-amber-300 font-medium transition-all duration-300 hover:scale-105 relative group">
TUTORIAL
<span class="absolute -bottom-1 left-0 w-0 h-0.5 bg-amber-300 transition-all duration-300 group-hover:w-full"></span>
</a>
<a href="@Url.Action("Kontak", "Website")" class="text-white hover:text-amber-300 font-medium transition-all duration-300 hover:scale-105 relative group">
KONTAK
@ -86,6 +90,9 @@
<a href="@Url.Action("Kontak", "Website")" class="block px-3 py-2 text-white hover:text-amber-300 hover:bg-white/10 rounded-lg font-medium transition-all duration-300">
KONTAK
</a>
<a href="@Url.Action("Tutorial", "Website")" class="block px-3 py-2 text-white hover:text-amber-300 hover:bg-white/10 rounded-lg font-medium transition-all duration-300">
TUTORIAL
</a>
<div class="flex flex-col space-y-2 pt-2 border-t border-white/20">
<a href="#" class="block px-3 py-2 text-white hover:text-amber-300 hover:bg-white/10 rounded-lg font-medium transition-all duration-300 text-center border border-white/20">
MASUK

View File

@ -1,8 +1,18 @@
<script src="https://api.mapbox.com/mapbox-gl-js/v3.13.0/mapbox-gl.js"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
lucide.createIcons();
});
</script>
<script src="https://unpkg.com/lucide@latest"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
lucide.createIcons();
});
</script>
<script src="@Url.Content("~/website/js/helpdesk.js")"></script>
<script src="~/website/js/dropdown.js"></script>
<script src="~/website/js/datatables_angkut.js"></script>
<script src="~/website/js/datatables_pengolahan.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/2.1.8/js/dataTables.min.js"></script>
<script src="https://cdn.datatables.net/2.1.8/js/dataTables.tailwindcss.min.js"></script>
<script src="https://cdn.datatables.net/responsive/3.0.3/js/dataTables.responsive.min.js"></script>

View File

@ -49,6 +49,10 @@
<link rel="stylesheet" href="~/website/css/watch.css" asp-append-version="true" />
<link rel="stylesheet" href="~/website/css/website.css" asp-append-version="true" />
<link rel="stylesheet" href="https://cdn.datatables.net/2.1.8/css/dataTables.tailwindcss.css">
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/3.0.3/css/responsive.dataTables.css">
<link rel="stylesheet" href="~/website/css/datatables-responsive.css" asp-append-version="true" />
<dynamic-section name="css" />
@await RenderSectionAsync("css", required: false)

View File

@ -0,0 +1,77 @@
@{
Layout = "~/Views/Website/Shared/_Layout.cshtml";
ViewData["Title"] = "Tutorial & Manual Book Sistem Informasi Pesapakawan";
}
<div class="mx-auto">
<div class="bg-cyan-700 pt-30 pb-10 mb-8 shadow-md rounded-br-4xl rounded-bl-4xl relative overflow-hidden">
<div class="absolute inset-0" style="background-image: radial-gradient(circle at 85% 1%, hsla(190, 0%, 93%, 0.05) 0%, hsla(190, 0%, 93%, 0.05) 96%, transparent 96%, transparent 100%), radial-gradient(circle at 14% 15%, hsla(190, 0%, 93%, 0.05) 0%, hsla(190, 0%, 93%, 0.05) 1%, transparent 1%, transparent 100%), radial-gradient(circle at 60% 90%, hsla(190, 0%, 93%, 0.05) 0%, hsla(190, 0%, 93%, 0.05) 20%, transparent 20%, transparent 100%), radial-gradient(circle at 79% 7%, hsla(190, 0%, 93%, 0.05) 0%, hsla(190, 0%, 93%, 0.05) 78%, transparent 78%, transparent 100%), radial-gradient(circle at 55% 65%, hsla(190, 0%, 93%, 0.05) 0%, hsla(190, 0%, 93%, 0.05) 52%, transparent 52%, transparent 100%), linear-gradient(135deg, rgb(0, 163, 227), rgb(6, 182, 212));"></div>
<div class="max-w-6xl mx-auto px-6 hidden md:block relative z-10">
<nav class="flex items-center text-white text-sm space-x-2" aria-label="Breadcrumb">
<a href="@Url.Action("Index", "Home")" class="hover:underline">Beranda</a>
<i class="w-4 h-4 text-white transition-colors duration-300" data-lucide="chevron-right"></i>
<span class="font-semibold">Tutorial & Manual Book Sistem Informasi Pesapakawan</span>
</nav>
</div>
<div class="max-w-6xl mx-auto justify-between flex flex-col md:flex-row items-center px-6 gap-8 relative z-10">
<div class="flex-1 text-center max-w-xl md:text-left">
<h1 class="text-3xl md:text-4xl font-medium text-white mb-3">Tutorial & Manual Book Sistem Informasi Pesapakawan</h1>
<p class="text-lg text-white mb-4">Panduan lengkap dan petunjuk teknis untuk membantu Anda menggunakan Sistem Informasi Pesapakawan dengan mudah dan efektif.</p>
<div class="w-20 h-1 bg-white mt-4 mx-auto md:mx-0 rounded-full"></div>
</div>
<div class="flex-shrink-0 hidden md:block">
<img src="@Url.Content("~/website/images/bg-header.webp")" alt="Usaha Pesapakawan" class="w-75 h-auto">
</div>
</div>
</div>
<div class="max-w-6xl mx-auto px-4">
<div class="bg-white rounded-xl border border-gray-200 p-8 mb-8 shadow-sm hover:shadow-md transition-shadow duration-300">
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div class="space-y-6">
<h2 class="text-2xl font-semibold text-gray-800 mb-6 border-b pb-2 border-cyan-100">Manual Book</h2>
<div class="flex items-start space-x-4 group">
<div class="flex-shrink-0 p-2 bg-cyan-50 rounded-lg group-hover:bg-cyan-100 transition-colors">
<i class="w-5 h-5 text-cyan-600" data-lucide="file-text"></i>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-1">Panduan Pengguna</h3>
<p class="text-gray-600 leading-relaxed">
Dokumen ini berisi petunjuk lengkap penggunaan sistem informasi Pesapakawan
untuk semua fitur dan modul.
</p>
<a href="~/website/documents/manual_book_pesapakawan.pdf" target="_blank" rel="noopener noreferrer" class="inline-flex items-center mt-2 px-4 py-2 bg-gradient-to-r from-cyan-500 to-cyan-600 text-white font-medium rounded-lg shadow-sm hover:from-cyan-600 hover:to-cyan-700 transition-all duration-300 transform hover:-translate-y-0.5">
Download PDF <i class="w-4 h-4 ml-2" data-lucide="download"></i>
</a>
</div>
</div>
</div>
<div>
<h2 class="text-2xl font-semibold text-gray-800 mb-6 border-b pb-2 border-cyan-100">Video Tutorial</h2>
<div class="w-full aspect-video rounded-lg overflow-hidden shadow-md hover:shadow-lg transition-shadow duration-300">
<iframe
width="100%"
height="100%"
src="https://www.youtube.com/embed/id_video_disini_ya"
title="Tutorial Sistem Informasi Pesapakawan"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
<div class="mt-4">
<p class="text-gray-600 mb-3">
Pelajari cara menggunakan sistem melalui video tutorial lengkap kami.
Video ini memberikan panduan langkah demi langkah untuk memahami dan memanfaatkan fitur-fitur utama Sistem Informasi Pesapakawan secara optimal.
</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,180 @@
/* #pengangkutanTable {
width: 100% !important;
table-layout: fixed;
}
#pengangkutanTable thead th,
#pengangkutanTable tbody td {
display: table-cell !important;
vertical-align: top;
word-wrap: break-word;
word-break: break-word;
white-space: normal;
overflow-wrap: break-word;
}
.dtr-details {
display: none !important;
}
.dtr-control {
display: none !important;
}
.child {
display: none !important;
}
#pengangkutanTable tbody tr:nth-child(even) {
background-color: #f9fafb;
}
#pengangkutanTable tbody tr:hover {
background-color: #e0f2fe !important;
transition: background-color 0.2s ease;
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.dt-paging .dt-paging-button {
display: inline-block !important;
margin: 0 2px;
}
@media (max-width: 768px) {
.dataTables_wrapper {
overflow-x: visible;
}
#pengangkutanTable th:nth-child(1),
#pengangkutanTable td:nth-child(1) {
width: 10%;
min-width: 40px;
}
#pengangkutanTable th:nth-child(2),
#pengangkutanTable td:nth-child(2) {
width: 35%;
min-width: 120px;
}
#pengangkutanTable th:nth-child(3),
#pengangkutanTable td:nth-child(3) {
width: 35%;
min-width: 120px;
}
#pengangkutanTable th:nth-child(4),
#pengangkutanTable td:nth-child(4) {
width: 20%;
min-width: 100px;
}
#pengangkutanTable {
font-size: 13px;
}
#pengangkutanTable th,
#pengangkutanTable td {
padding: 10px 6px;
line-height: 1.4;
}
.overflow-x-auto {
overflow-x: visible;
}
}
@media (max-width: 640px) {
#pengangkutanTable {
font-size: 12px;
}
#pengangkutanTable th,
#pengangkutanTable td {
padding: 8px 4px;
line-height: 1.3;
}
#pengangkutanTable th:nth-child(1),
#pengangkutanTable td:nth-child(1) {
width: 8%;
min-width: 35px;
}
#pengangkutanTable th:nth-child(2),
#pengangkutanTable td:nth-child(2) {
width: 42%;
}
#pengangkutanTable th:nth-child(3),
#pengangkutanTable td:nth-child(3) {
width: 30%;
}
#pengangkutanTable th:nth-child(4),
#pengangkutanTable td:nth-child(4) {
width: 20%;
}
.status-badge {
display: block;
margin-top: 4px;
font-size: 10px;
padding: 2px 6px;
}
}
.dt-paging {
text-align: center;
margin-top: 1rem;
}
.dt-paging .dt-paging-button {
padding: 6px 12px;
margin: 0 2px;
border: 1px solid #d1d5db;
border-radius: 6px;
background: white;
color: #374151;
text-decoration: none;
transition: all 0.2s ease;
}
.dt-paging .dt-paging-button:hover {
background: #e0f2fe;
border-color: #0ea5e9;
color: #0369a1;
}
.dt-paging .dt-paging-button.current {
background: #0ea5e9;
border-color: #0ea5e9;
color: white;
}
.dt-paging .dt-paging-button.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.dt-search input {
padding: 8px 12px;
border: 1px solid #d1d5db;
border-radius: 6px;
font-size: 14px;
transition: border-color 0.2s ease;
}
.dt-search input:focus {
outline: none;
border-color: #0ea5e9;
box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1);
}
.dt-length select {
padding: 6px 10px;
border: 1px solid #d1d5db;
border-radius: 6px;
font-size: 14px;
} */

View File

@ -85,12 +85,21 @@
--color-indigo-50: oklch(96.2% 0.018 272.314);
--color-indigo-100: oklch(93% 0.034 272.788);
--color-indigo-300: oklch(78.5% 0.115 274.713);
--color-indigo-700: oklch(45.7% 0.24 277.023);
--color-indigo-800: oklch(39.8% 0.195 277.366);
--color-purple-50: oklch(97.7% 0.014 308.299);
--color-purple-100: oklch(94.6% 0.033 307.174);
--color-purple-200: oklch(90.2% 0.063 306.703);
--color-purple-300: oklch(82.7% 0.119 306.383);
--color-purple-500: oklch(62.7% 0.265 303.9);
--color-purple-600: oklch(55.8% 0.288 302.321);
--color-purple-700: oklch(49.6% 0.265 301.924);
--color-purple-800: oklch(43.8% 0.218 303.724);
--color-purple-900: oklch(38.1% 0.176 304.987);
--color-pink-50: oklch(97.1% 0.014 343.198);
--color-pink-500: oklch(65.6% 0.241 354.308);
--color-pink-600: oklch(59.2% 0.249 0.584);
--color-pink-700: oklch(52.5% 0.223 3.958);
--color-rose-50: oklch(96.9% 0.015 12.422);
--color-rose-500: oklch(64.5% 0.246 16.439);
--color-rose-600: oklch(58.6% 0.253 17.585);
@ -118,6 +127,7 @@
--container-xs: 20rem;
--container-sm: 24rem;
--container-md: 28rem;
--container-lg: 32rem;
--container-xl: 36rem;
--container-2xl: 42rem;
--container-3xl: 48rem;
@ -140,6 +150,8 @@
--text-3xl--line-height: calc(2.25 / 1.875);
--text-4xl: 2.25rem;
--text-4xl--line-height: calc(2.5 / 2.25);
--text-5xl: 3rem;
--text-5xl--line-height: 1;
--text-6xl: 3.75rem;
--text-6xl--line-height: 1;
--font-weight-light: 300;
@ -169,6 +181,8 @@
--blur-sm: 8px;
--blur-md: 12px;
--blur-lg: 16px;
--blur-xl: 24px;
--aspect-video: 16 / 9;
--default-transition-duration: 150ms;
--default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
--default-font-family: var(--font-sans);
@ -399,6 +413,9 @@
.top-0 {
top: calc(var(--spacing) * 0);
}
.top-1 {
top: calc(var(--spacing) * 1);
}
.top-1\/2 {
top: calc(1/2 * 100%);
}
@ -453,6 +470,9 @@
.right-full {
right: 100%;
}
.-bottom-0 {
bottom: calc(var(--spacing) * -0);
}
.-bottom-0\.5 {
bottom: calc(var(--spacing) * -0.5);
}
@ -489,6 +509,9 @@
.left-0 {
left: calc(var(--spacing) * 0);
}
.left-1 {
left: calc(var(--spacing) * 1);
}
.left-1\/2 {
left: calc(1/2 * 100%);
}
@ -696,6 +719,9 @@
.my-6 {
margin-block: calc(var(--spacing) * 6);
}
.my-12 {
margin-block: calc(var(--spacing) * 12);
}
.my-auto {
margin-block: auto;
}
@ -783,6 +809,9 @@
.mt-8 {
margin-top: calc(var(--spacing) * 8);
}
.mt-12 {
margin-top: calc(var(--spacing) * 12);
}
.mt-25 {
margin-top: calc(var(--spacing) * 25);
}
@ -837,12 +866,21 @@
.mb-auto {
margin-bottom: auto;
}
.-ml-1 {
margin-left: calc(var(--spacing) * -1);
}
.ml-0 {
margin-left: calc(var(--spacing) * 0);
}
.ml-2 {
margin-left: calc(var(--spacing) * 2);
}
.ml-4 {
margin-left: calc(var(--spacing) * 4);
}
.ml-9 {
margin-left: calc(var(--spacing) * 9);
}
.ml-auto {
margin-left: auto;
}
@ -888,6 +926,12 @@
.table-row {
display: table-row;
}
.aspect-video {
aspect-ratio: var(--aspect-video);
}
.h-0 {
height: calc(var(--spacing) * 0);
}
.h-0\.5 {
height: calc(var(--spacing) * 0.5);
}
@ -1134,6 +1178,9 @@
.grow {
flex-grow: 1;
}
.table-fixed {
table-layout: fixed;
}
.caption-top {
caption-side: top;
}
@ -1143,6 +1190,10 @@
.origin-top {
transform-origin: top;
}
.-translate-x-1 {
--tw-translate-x: calc(var(--spacing) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-x-1\/2 {
--tw-translate-x: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
@ -1155,6 +1206,10 @@
--tw-translate-x: calc(var(--spacing) * 16);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-1 {
--tw-translate-y: calc(var(--spacing) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-1\/2 {
--tw-translate-y: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
@ -1179,6 +1234,12 @@
--tw-scale-z: 100%;
scale: var(--tw-scale-x) var(--tw-scale-y);
}
.scale-102 {
--tw-scale-x: 102%;
--tw-scale-y: 102%;
--tw-scale-z: 102%;
scale: var(--tw-scale-x) var(--tw-scale-y);
}
.scale-110 {
--tw-scale-x: 110%;
--tw-scale-y: 110%;
@ -1338,6 +1399,13 @@
margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)));
}
}
.space-x-1 {
:where(& > :not(:last-child)) {
--tw-space-x-reverse: 0;
margin-inline-start: calc(calc(var(--spacing) * 1) * var(--tw-space-x-reverse));
margin-inline-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-x-reverse)));
}
}
.space-x-2 {
:where(& > :not(:last-child)) {
--tw-space-x-reverse: 0;
@ -1380,6 +1448,16 @@
border-color: var(--color-amber-100);
}
}
.divide-gray-100 {
:where(& > :not(:last-child)) {
border-color: var(--color-gray-100);
}
}
.divide-gray-200 {
:where(& > :not(:last-child)) {
border-color: var(--color-gray-200);
}
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
@ -1551,12 +1629,24 @@
.border-black {
border-color: var(--color-black);
}
.border-blue-100 {
border-color: var(--color-blue-100);
}
.border-blue-200 {
border-color: var(--color-blue-200);
}
.border-blue-500 {
border-color: var(--color-blue-500);
}
.border-blue-600 {
border-color: var(--color-blue-600);
}
.border-blue-800 {
border-color: var(--color-blue-800);
}
.border-cyan-100 {
border-color: var(--color-cyan-100);
}
.border-cyan-200 {
border-color: var(--color-cyan-200);
}
@ -1572,12 +1662,18 @@
border-color: color-mix(in oklab, var(--color-cyan-400) 20%, transparent);
}
}
.border-cyan-600 {
border-color: var(--color-cyan-600);
}
.border-cyan-600\/50 {
border-color: color-mix(in srgb, oklch(60.9% 0.126 221.723) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
border-color: color-mix(in oklab, var(--color-cyan-600) 50%, transparent);
}
}
.border-cyan-700 {
border-color: var(--color-cyan-700);
}
.border-cyan-700\/50 {
border-color: color-mix(in srgb, oklch(52% 0.105 223.128) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
@ -1605,6 +1701,9 @@
.border-gray-300 {
border-color: var(--color-gray-300);
}
.border-gray-400 {
border-color: var(--color-gray-400);
}
.border-green-100 {
border-color: var(--color-green-100);
}
@ -1650,6 +1749,9 @@
border-color: color-mix(in oklab, var(--color-slate-200) 50%, transparent);
}
}
.border-transparent {
border-color: transparent;
}
.border-white {
border-color: var(--color-white);
}
@ -1725,6 +1827,9 @@
.bg-blue-500 {
background-color: var(--color-blue-500);
}
.bg-blue-600 {
background-color: var(--color-blue-600);
}
.bg-cyan-50 {
background-color: var(--color-cyan-50);
}
@ -1740,6 +1845,9 @@
.bg-cyan-500 {
background-color: var(--color-cyan-500);
}
.bg-cyan-600 {
background-color: var(--color-cyan-600);
}
.bg-cyan-700 {
background-color: var(--color-cyan-700);
}
@ -1800,6 +1908,9 @@
.bg-green-600 {
background-color: var(--color-green-600);
}
.bg-indigo-100 {
background-color: var(--color-indigo-100);
}
.bg-indigo-300 {
background-color: var(--color-indigo-300);
}
@ -1818,6 +1929,15 @@
.bg-orange-500 {
background-color: var(--color-orange-500);
}
.bg-pink-500 {
background-color: var(--color-pink-500);
}
.bg-purple-50 {
background-color: var(--color-purple-50);
}
.bg-purple-100 {
background-color: var(--color-purple-100);
}
.bg-purple-500 {
background-color: var(--color-purple-500);
}
@ -1920,6 +2040,10 @@
--tw-gradient-from: var(--color-blue-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-blue-400 {
--tw-gradient-from: var(--color-blue-400);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-blue-500 {
--tw-gradient-from: var(--color-blue-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -2000,6 +2124,10 @@
--tw-gradient-from: var(--color-purple-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-purple-500 {
--tw-gradient-from: var(--color-purple-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-red-50 {
--tw-gradient-from: var(--color-red-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -2024,6 +2152,10 @@
--tw-gradient-from: var(--color-slate-700);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-slate-800 {
--tw-gradient-from: var(--color-slate-800);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-teal-400 {
--tw-gradient-from: var(--color-teal-400);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -2058,6 +2190,11 @@
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-via-stops);
}
.via-blue-700 {
--tw-gradient-via: var(--color-blue-700);
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-via-stops);
}
.via-cyan-400 {
--tw-gradient-via: var(--color-cyan-400);
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
@ -2083,6 +2220,11 @@
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-via-stops);
}
.via-slate-700 {
--tw-gradient-via: var(--color-slate-700);
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-via-stops);
}
.via-white {
--tw-gradient-via: var(--color-white);
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
@ -2112,6 +2254,10 @@
--tw-gradient-to: var(--color-blue-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-blue-700 {
--tw-gradient-to: var(--color-blue-700);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-cyan-50 {
--tw-gradient-to: var(--color-cyan-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -2196,6 +2342,14 @@
--tw-gradient-to: var(--color-purple-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-purple-500 {
--tw-gradient-to: var(--color-purple-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-purple-600 {
--tw-gradient-to: var(--color-purple-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-red-50 {
--tw-gradient-to: var(--color-red-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -2228,6 +2382,10 @@
--tw-gradient-to: var(--color-slate-50);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-slate-800 {
--tw-gradient-to: var(--color-slate-800);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-slate-900 {
--tw-gradient-to: var(--color-slate-900);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@ -2322,6 +2480,9 @@
.py-0 {
padding-block: calc(var(--spacing) * 0);
}
.py-0\.5 {
padding-block: calc(var(--spacing) * 0.5);
}
.py-1 {
padding-block: calc(var(--spacing) * 1);
}
@ -2592,6 +2753,9 @@
.break-all {
word-break: break-all;
}
.whitespace-nowrap {
white-space: nowrap;
}
.text-amber-400 {
color: var(--color-amber-400);
}
@ -2673,6 +2837,9 @@
.text-gray-900 {
color: var(--color-gray-900);
}
.text-green-100 {
color: var(--color-green-100);
}
.text-green-400 {
color: var(--color-green-400);
}
@ -2691,6 +2858,9 @@
.text-green-900 {
color: var(--color-green-900);
}
.text-indigo-800 {
color: var(--color-indigo-800);
}
.text-orange-100 {
color: var(--color-orange-100);
}
@ -2709,6 +2879,12 @@
.text-orange-900 {
color: var(--color-orange-900);
}
.text-purple-100 {
color: var(--color-purple-100);
}
.text-purple-600 {
color: var(--color-purple-600);
}
.text-purple-800 {
color: var(--color-purple-800);
}
@ -2784,6 +2960,11 @@
.underline {
text-decoration-line: underline;
}
.placeholder-gray-400 {
&::placeholder {
color: var(--color-gray-400);
}
}
.opacity-0 {
opacity: 0%;
}
@ -3019,6 +3200,13 @@
}
}
}
.group-hover\:bg-cyan-100 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
background-color: var(--color-cyan-100);
}
}
}
.group-hover\:text-cyan-500 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@ -3127,6 +3315,13 @@
}
}
}
.hover\:border-transparent {
&:hover {
@media (hover: hover) {
border-color: transparent;
}
}
}
.hover\:bg-amber-50 {
&:hover {
@media (hover: hover) {
@ -3155,6 +3350,13 @@
}
}
}
.hover\:bg-blue-700 {
&:hover {
@media (hover: hover) {
background-color: var(--color-blue-700);
}
}
}
.hover\:bg-cyan-500 {
&:hover {
@media (hover: hover) {
@ -3218,6 +3420,13 @@
}
}
}
.hover\:bg-purple-50 {
&:hover {
@media (hover: hover) {
background-color: var(--color-purple-50);
}
}
}
.hover\:bg-red-50 {
&:hover {
@media (hover: hover) {
@ -3269,6 +3478,30 @@
}
}
}
.hover\:bg-gradient-to-r {
&:hover {
@media (hover: hover) {
--tw-gradient-position: to right in oklab;
background-image: linear-gradient(var(--tw-gradient-stops));
}
}
}
.hover\:from-blue-500 {
&:hover {
@media (hover: hover) {
--tw-gradient-from: var(--color-blue-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:from-blue-600 {
&:hover {
@media (hover: hover) {
--tw-gradient-from: var(--color-blue-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:from-cyan-600 {
&:hover {
@media (hover: hover) {
@ -3333,6 +3566,22 @@
}
}
}
.hover\:to-purple-600 {
&:hover {
@media (hover: hover) {
--tw-gradient-to: var(--color-purple-600);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:to-purple-700 {
&:hover {
@media (hover: hover) {
--tw-gradient-to: var(--color-purple-700);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
}
}
.hover\:text-amber-300 {
&:hover {
@media (hover: hover) {
@ -3347,6 +3596,13 @@
}
}
}
.hover\:text-blue-600 {
&:hover {
@media (hover: hover) {
color: var(--color-blue-600);
}
}
}
.hover\:text-cyan-200 {
&:hover {
@media (hover: hover) {
@ -3471,6 +3727,11 @@
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
}
.focus\:ring-blue-500 {
&:focus {
--tw-ring-color: var(--color-blue-500);
}
}
.focus\:ring-cyan-200 {
&:focus {
--tw-ring-color: var(--color-cyan-200);
@ -3517,11 +3778,21 @@
margin-top: calc(var(--spacing) * 8);
}
}
.sm\:mb-0 {
@media (width >= 40rem) {
margin-bottom: calc(var(--spacing) * 0);
}
}
.sm\:mb-8 {
@media (width >= 40rem) {
margin-bottom: calc(var(--spacing) * 8);
}
}
.sm\:block {
@media (width >= 40rem) {
display: block;
}
}
.sm\:h-5 {
@media (width >= 40rem) {
height: calc(var(--spacing) * 5);
@ -3552,6 +3823,11 @@
max-width: var(--container-md);
}
}
.sm\:flex-row {
@media (width >= 40rem) {
flex-direction: row;
}
}
.sm\:space-y-6 {
@media (width >= 40rem) {
:where(& > :not(:last-child)) {
@ -3596,6 +3872,11 @@
padding-left: calc(var(--spacing) * 10);
}
}
.sm\:text-right {
@media (width >= 40rem) {
text-align: right;
}
}
.sm\:text-3xl {
@media (width >= 40rem) {
font-size: var(--text-3xl);
@ -3684,6 +3965,21 @@
flex-direction: row;
}
}
.md\:items-center {
@media (width >= 48rem) {
align-items: center;
}
}
.md\:justify-between {
@media (width >= 48rem) {
justify-content: space-between;
}
}
.md\:gap-0 {
@media (width >= 48rem) {
gap: calc(var(--spacing) * 0);
}
}
.md\:space-x-4 {
@media (width >= 48rem) {
:where(& > :not(:last-child)) {
@ -3804,6 +4100,25 @@
flex-direction: row;
}
}
.lg\:items-center {
@media (width >= 64rem) {
align-items: center;
}
}
.lg\:justify-between {
@media (width >= 64rem) {
justify-content: space-between;
}
}
.lg\:space-y-0 {
@media (width >= 64rem) {
:where(& > :not(:last-child)) {
--tw-space-y-reverse: 0;
margin-block-start: calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));
margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)));
}
}
}
.lg\:p-8 {
@media (width >= 64rem) {
padding: calc(var(--spacing) * 8);

View File

@ -1,3 +1,729 @@
.font-sans {
font-family: "Figtree", sans-serif;
}
.dropdown-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease,
border-color 0.3s ease;
background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
border-top: 1px solid #e5e7eb;
border-radius: 0 0 12px 12px;
position: relative;
}
.dropdown-content.open {
border: 1px solid #e5e7eb;
border-top: none;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1),
0 10px 10px -5px rgba(0, 0, 0, 0.04), 0 0 0 1px rgba(59, 130, 246, 0.1);
}
.dropdown-content.opening {
border-color: #3b82f6;
box-shadow: 0 20px 40px -10px rgba(59, 130, 246, 0.25);
}
.dropdown-content.closing {
border-color: #e5e7eb;
}
.dropdown-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.25rem 1.5rem;
background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
border: 2px solid #e5e7eb;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
margin-bottom: 0.5rem;
font-weight: 600;
color: #374151;
position: relative;
overflow: hidden;
backdrop-filter: blur(10px);
transform: translateY(0);
}
.dropdown-header::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(59, 130, 246, 0.1),
transparent
);
transition: left 0.5s ease;
}
.dropdown-header:hover::before {
left: 100%;
}
.dropdown-header:hover {
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
border-color: #3b82f6;
box-shadow: 0 8px 25px -5px rgba(59, 130, 246, 0.2),
0 8px 10px -5px rgba(59, 130, 246, 0.1);
transform: translateY(-2px);
}
.dropdown-header.active {
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
border-color: #2563eb;
color: #1e40af;
box-shadow: 0 12px 30px -8px rgba(37, 99, 235, 0.3),
0 0 0 3px rgba(59, 130, 246, 0.1);
transform: translateY(-1px);
}
.dropdown-header:active {
transform: translateY(0);
transition: transform 0.1s ease;
}
.dropdown-icon {
width: 24px;
height: 24px;
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease,
filter 0.3s ease;
color: #6b7280;
flex-shrink: 0;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
}
.dropdown-header:hover .dropdown-icon {
color: #3b82f6;
filter: drop-shadow(0 4px 8px rgba(59, 130, 246, 0.3));
}
.dropdown-header.active .dropdown-icon {
color: #1e40af;
filter: drop-shadow(0 6px 12px rgba(30, 64, 175, 0.4));
}
.dropdown-content > div {
padding: 2rem;
color: #4b5563;
line-height: 1.7;
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.9) 0%,
rgba(248, 250, 252, 0.9) 100%
);
position: relative;
}
.dropdown-content > div::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, #3b82f6, #8b5cf6, #06b6d4);
opacity: 0;
transition: opacity 0.3s ease;
}
.dropdown-content.open > div::before {
opacity: 1;
}
.dropdown-content h3 {
margin: 0 0 1.5rem 0;
color: #111827;
font-size: 1.25rem;
font-weight: 700;
position: relative;
padding-left: 1rem;
}
.dropdown-content h3::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 1.5rem;
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
border-radius: 2px;
}
.dropdown-content p {
margin: 0 0 1.5rem 0;
transition: transform 0.3s ease;
}
.dropdown-content p:hover {
transform: translateX(5px);
}
.dropdown-content ul {
margin: 1.5rem 0;
padding-left: 2rem;
position: relative;
}
.dropdown-content li {
margin-bottom: 0.75rem;
color: #4b5563;
position: relative;
transition: all 0.3s ease;
padding-left: 0.5rem;
}
.dropdown-content li:hover::before {
transform: translateX(3px);
}
.dropdown-content li:hover {
color: #1f2937;
transform: translateX(5px);
}
.dropdown-content table {
width: 100%;
border-collapse: collapse;
margin: 1.5rem 0;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
background: white;
}
.dropdown-content th,
.dropdown-content td {
padding: 1rem 0.75rem;
text-align: left;
border-bottom: 1px solid #f1f5f9;
transition: background-color 0.3s ease;
}
.dropdown-content th {
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
font-weight: 700;
color: #374151;
position: relative;
}
.dropdown-content th::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
}
.dropdown-content tr:hover td {
background-color: #f0f9ff;
transform: scale(1.01);
}
.dropdown-content tbody tr {
transition: all 0.3s ease;
}
.content-item {
transition: opacity 0.3s ease, transform 0.3s ease;
}
.dropdown-content.opening .content-item {
opacity: 0;
transform: translateY(20px);
}
.dropdown-content.open .content-item {
opacity: 1;
transform: translateY(0);
}
.ripple-effect {
position: absolute;
border-radius: 50%;
background: radial-gradient(
circle,
rgba(59, 130, 246, 0.3) 0%,
transparent 70%
);
transform: scale(0);
animation: ripple-animation 0.6s ease-out;
pointer-events: none;
}
.dropdown-header::after {
content: "";
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 2px;
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
transform: translateX(-50%);
}
.dropdown-header.active::after {
width: 100%;
}
.dropdown-header.active h2 {
background: linear-gradient(135deg, #1e40af, #7c3aed);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
@keyframes pulse-glow {
0%,
100% {
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
}
50% {
box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
}
}
.dropdown-header:hover {
animation: pulse-glow 2s infinite;
}
.dropdown-content.opening {
animation: slide-in-content 0.5s ease-out;
}
@keyframes slide-in-content {
from {
opacity: 0;
transform: translateY(-20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.dropdown-header:hover .bg-gradient-to-br {
transform: scale(1.1) rotate(5deg);
transition: transform 0.3s ease;
}
.dropdown-header.active .bg-gradient-to-br {
transform: scale(1.1) rotate(-5deg);
animation: icon-bounce 0.6s ease;
}
@keyframes icon-bounce {
0%,
20%,
60%,
100% {
transform: scale(1.1) rotate(-5deg);
}
40% {
transform: scale(1.2) rotate(-10deg);
}
80% {
transform: scale(1.15) rotate(-2deg);
}
}
@media (max-width: 768px) {
.dropdown-header {
padding: 1rem;
font-size: 0.875rem;
border-radius: 10px;
}
.dropdown-content > div {
padding: 1.5rem 1rem;
}
.dropdown-content h3 {
font-size: 1.125rem;
margin-bottom: 1rem;
}
.dropdown-icon {
width: 20px;
height: 20px;
}
.dropdown-content > div {
padding: 1rem;
}
}
.whatsapp-widget {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif;
}
.whatsapp-button {
position: relative;
width: 60px;
height: 60px;
background: linear-gradient(135deg, #25d366 0%, #128c7e 100%);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 20px rgba(37, 211, 102, 0.4);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
animation: bounce 2s infinite;
}
.whatsapp-button:hover {
transform: scale(1.1);
box-shadow: 0 6px 25px rgba(37, 211, 102, 0.6);
}
.whatsapp-icon {
width: 32px;
height: 32px;
color: white;
z-index: 2;
}
.pulse-ring {
position: absolute;
width: 60px;
height: 60px;
border: 2px solid #25d366;
border-radius: 50%;
animation: pulse 2s infinite;
opacity: 0;
}
.pulse-ring-2 {
position: absolute;
width: 60px;
height: 60px;
border: 2px solid #25d366;
border-radius: 50%;
animation: pulse 2s infinite 1s;
opacity: 0;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.3);
opacity: 0.3;
}
100% {
transform: scale(1.6);
opacity: 0;
}
}
@keyframes bounce {
0%,
20%,
50%,
80%,
100% {
transform: translateY(0);
}
40% {
transform: translateY(-5px);
}
60% {
transform: translateY(-3px);
}
}
.whatsapp-popup {
position: absolute;
bottom: 80px;
right: 0;
width: 350px;
background: white;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
opacity: 0;
transform: translateY(20px) scale(0.9);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
pointer-events: none;
overflow: hidden;
}
.whatsapp-popup.show {
opacity: 1;
transform: translateY(0) scale(1);
pointer-events: all;
}
.popup-header {
background: linear-gradient(135deg, #25d366 0%, #128c7e 100%);
color: white;
padding: 15px;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-content {
display: flex;
align-items: center;
gap: 12px;
}
.avatar {
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 45px;
height: 45px;
border-radius: 50%;
overflow: hidden;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
background: white;
padding: 5px;
}
.online-indicator {
position: absolute;
bottom: 2px;
right: 2px;
width: 12px;
height: 12px;
background: #4caf50;
border-radius: 50%;
border: 2px solid white;
animation: blink 2s infinite;
}
@keyframes blink {
0%,
50% {
opacity: 1;
}
51%,
100% {
opacity: 0.3;
}
}
.header-text h4 {
margin: 0;
font-size: 16px;
font-weight: 600;
}
.online-status {
margin: 0;
font-size: 12px;
opacity: 0.9;
}
.close-btn {
background: none;
border: none;
color: white;
width: 24px;
height: 24px;
cursor: pointer;
border-radius: 50%;
transition: background 0.2s;
}
.close-btn:hover {
background: rgba(255, 255, 255, 0.2);
}
.popup-body {
padding: 20px;
max-height: 300px;
overflow-y: auto;
}
.chat-message {
display: flex;
gap: 10px;
margin-bottom: 20px;
animation: slideInUp 0.5s ease-out;
}
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.message-avatar {
width: 30px;
height: 30px;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
}
.message-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
background: #f0f0f0;
padding: 3px;
}
.message-bubble {
background: #f0f0f0;
border-radius: 15px 15px 15px 5px;
padding: 12px 15px;
flex: 1;
position: relative;
}
.message-bubble p {
margin: 0 0 5px 0;
font-size: 14px;
line-height: 1.4;
color: #333;
}
.message-bubble p:last-of-type {
margin-bottom: 0;
}
.message-time {
text-align: right;
margin-top: 8px;
}
.message-time span {
font-size: 11px;
color: #999;
}
.quick-options h5 {
margin: 0 0 15px 0;
font-size: 14px;
font-weight: 600;
color: #333;
}
.options-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.option-btn {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 12px 15px;
text-align: left;
cursor: pointer;
transition: all 0.2s;
font-size: 13px;
color: #495057;
}
.option-btn:hover {
background: #25d366;
color: white;
border-color: #25d366;
transform: translateX(5px);
}
.popup-footer {
padding: 15px;
border-top: 1px solid #f0f0f0;
}
.whatsapp-chat-btn {
width: 100%;
background: linear-gradient(135deg, #25d366 0%, #128c7e 100%);
color: white;
border: none;
border-radius: 25px;
padding: 12px 20px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
transition: all 0.3s;
}
.whatsapp-chat-btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(37, 211, 102, 0.3);
}
.chat-icon {
width: 18px;
height: 18px;
}
@media (max-width: 768px) {
.whatsapp-popup {
width: 300px;
right: -25px;
}
.whatsapp-widget {
bottom: 15px;
right: 15px;
}
}
@media (max-width: 480px) {
.whatsapp-popup {
width: 280px;
right: 5px;
}
}
.popup-body::-webkit-scrollbar {
width: 4px;
}
.popup-body::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 2px;
}
.popup-body::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 2px;
}
.popup-body::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}

View File

@ -0,0 +1,302 @@
[
{
"no": 1,
"nama": "PT. Bersih Sejahtera",
"alamat": "Jl. Sudirman No. 123, Jakarta Pusat",
"tglBerlakuIzin": "2025-12-31"
},
{
"no": 2,
"nama": "CV. Lingkungan Hijau",
"alamat": "Jl. Thamrin No. 45, Jakarta Selatan",
"tglBerlakuIzin": "2025-11-15"
},
{
"no": 3,
"nama": "PT. Waste Management Pro",
"alamat": "Jl. Gatot Subroto No. 78 Kelurahan Grogol Selatan, Kebauoran Lama, Jakarta Selatan",
"tglBerlakuIzin": "2026-01-20"
},
{
"no": 4,
"nama": "UD. Sampah Bersih",
"alamat": "Jl. Cikini No. 56, Jakarta Pusat",
"tglBerlakuIzin": "2025-10-30"
},
{
"no": 5,
"nama": "PT. Eco Transport",
"alamat": "Jl. Kuningan No. 89, Jakarta Selatan",
"tglBerlakuIzin": "2026-02-14"
},
{
"no": 6,
"nama": "CV. Green Waste Solution",
"alamat": "Jl. Matraman No. 34, Jakarta Timur",
"tglBerlakuIzin": "2025-09-25"
},
{
"no": 7,
"nama": "PT. Clean Environment",
"alamat": "Jl. Casablanca No. 67, Jakarta Selatan",
"tglBerlakuIzin": "2026-03-10"
},
{
"no": 8,
"nama": "UD. Waste Collector",
"alamat": "Jl. Kramat No. 12, Jakarta Pusat",
"tglBerlakuIzin": "2025-08-18"
},
{
"no": 9,
"nama": "PT. Urban Waste Management",
"alamat": "Jl. Sudirman No. 234, Jakarta Pusat",
"tglBerlakuIzin": "2026-04-05"
},
{
"no": 10,
"nama": "CV. Environmental Care",
"alamat": "Jl. Tebet No. 78, Jakarta Selatan",
"tglBerlakuIzin": "2025-07-22"
},
{
"no": 11,
"nama": "PT. Sumber Alam Bersih",
"alamat": "Jl. Merdeka No. 101, Jakarta Barat",
"tglBerlakuIzin": "2026-05-12"
},
{
"no": 12,
"nama": "CV. Hijau Lestari",
"alamat": "Jl. Mangga Dua No. 56, Jakarta Utara",
"tglBerlakuIzin": "2025-06-30"
},
{
"no": 13,
"nama": "PT. Lingkungan Asri",
"alamat": "Jl. Daan Mogot No. 88, Jakarta Barat",
"tglBerlakuIzin": "2026-07-19"
},
{
"no": 14,
"nama": "UD. Bersih Mandiri",
"alamat": "Jl. Salemba No. 23, Jakarta Pusat",
"tglBerlakuIzin": "2025-05-15"
},
{
"no": 15,
"nama": "PT. Eco Waste Nusantara",
"alamat": "Jl. Fatmawati No. 77, Jakarta Selatan",
"tglBerlakuIzin": "2026-08-25"
},
{
"no": 16,
"nama": "CV. Solusi Bersih",
"alamat": "Jl. Pramuka No. 45, Jakarta Timur",
"tglBerlakuIzin": "2025-04-10"
},
{
"no": 17,
"nama": "PT. Lestari Bersama",
"alamat": "Jl. Panjang No. 12, Jakarta Barat",
"tglBerlakuIzin": "2026-09-30"
},
{
"no": 18,
"nama": "UD. Hijau Bersih",
"alamat": "Jl. Kemang No. 34, Jakarta Selatan",
"tglBerlakuIzin": "2025-03-18"
},
{
"no": 19,
"nama": "PT. Mitra Lingkungan",
"alamat": "Jl. Pluit No. 56, Jakarta Utara",
"tglBerlakuIzin": "2026-10-11"
},
{
"no": 20,
"nama": "CV. Bersih Jaya",
"alamat": "Jl. Pasar Minggu No. 89, Jakarta Selatan",
"tglBerlakuIzin": "2025-02-05"
},
{
"no": 21,
"nama": "PT. Bersih Prima",
"alamat": "Jl. Sudirman No. 321, Jakarta Pusat",
"tglBerlakuIzin": "2026-11-01"
},
{
"no": 22,
"nama": "CV. Lingkungan Bersama",
"alamat": "Jl. Thamrin No. 99, Jakarta Selatan",
"tglBerlakuIzin": "2025-12-12"
},
{
"no": 23,
"nama": "PT. Waste Solution",
"alamat": "Jl. Gatot Subroto No. 88, Jakarta Selatan",
"tglBerlakuIzin": "2026-01-15"
},
{
"no": 24,
"nama": "UD. Sampah Mandiri",
"alamat": "Jl. Cikini No. 78, Jakarta Pusat",
"tglBerlakuIzin": "2025-10-10"
},
{
"no": 25,
"nama": "PT. Eco Transportasi",
"alamat": "Jl. Kuningan No. 100, Jakarta Selatan",
"tglBerlakuIzin": "2026-02-20"
},
{
"no": 26,
"nama": "CV. Green Solution",
"alamat": "Jl. Matraman No. 56, Jakarta Timur",
"tglBerlakuIzin": "2025-09-10"
},
{
"no": 27,
"nama": "PT. Clean Indo",
"alamat": "Jl. Casablanca No. 88, Jakarta Selatan",
"tglBerlakuIzin": "2026-03-15"
},
{
"no": 28,
"nama": "UD. Waste Pro",
"alamat": "Jl. Kramat No. 34, Jakarta Pusat",
"tglBerlakuIzin": "2025-08-10"
},
{
"no": 29,
"nama": "PT. Urban Waste Pro",
"alamat": "Jl. Sudirman No. 345, Jakarta Pusat",
"tglBerlakuIzin": "2026-04-10"
},
{
"no": 30,
"nama": "CV. Environmental Solution",
"alamat": "Jl. Tebet No. 99, Jakarta Selatan",
"tglBerlakuIzin": "2025-07-10"
},
{
"no": 31,
"nama": "PT. Sumber Alam Lestari",
"alamat": "Jl. Merdeka No. 200, Jakarta Barat",
"tglBerlakuIzin": "2026-05-20"
},
{
"no": 32,
"nama": "CV. Hijau Bersama",
"alamat": "Jl. Mangga Dua No. 78, Jakarta Utara",
"tglBerlakuIzin": "2025-06-10"
},
{
"no": 33,
"nama": "PT. Lingkungan Hijau",
"alamat": "Jl. Daan Mogot No. 99, Jakarta Barat",
"tglBerlakuIzin": "2026-07-10"
},
{
"no": 34,
"nama": "UD. Bersih Lestari",
"alamat": "Jl. Salemba No. 45, Jakarta Pusat",
"tglBerlakuIzin": "2025-05-10"
},
{
"no": 35,
"nama": "PT. Eco Nusantara",
"alamat": "Jl. Fatmawati No. 88, Jakarta Selatan",
"tglBerlakuIzin": "2026-08-10"
},
{
"no": 36,
"nama": "CV. Solusi Hijau",
"alamat": "Jl. Pramuka No. 67, Jakarta Timur",
"tglBerlakuIzin": "2025-04-20"
},
{
"no": 37,
"nama": "PT. Lestari Hijau",
"alamat": "Jl. Panjang No. 34, Jakarta Barat",
"tglBerlakuIzin": "2026-09-10"
},
{
"no": 38,
"nama": "UD. Hijau Mandiri",
"alamat": "Jl. Kemang No. 56, Jakarta Selatan",
"tglBerlakuIzin": "2025-03-10"
},
{
"no": 39,
"nama": "PT. Mitra Bersih",
"alamat": "Jl. Pluit No. 78, Jakarta Utara",
"tglBerlakuIzin": "2026-10-10"
},
{
"no": 40,
"nama": "CV. Bersih Mandiri",
"alamat": "Jl. Pasar Minggu No. 100, Jakarta Selatan",
"tglBerlakuIzin": "2025-02-10"
},
{
"no": 41,
"nama": "PT. Bersih Jaya",
"alamat": "Jl. Sudirman No. 400, Jakarta Pusat",
"tglBerlakuIzin": "2026-11-10"
},
{
"no": 42,
"nama": "CV. Lingkungan Lestari",
"alamat": "Jl. Thamrin No. 120, Jakarta Selatan",
"tglBerlakuIzin": "2025-12-20"
},
{
"no": 43,
"nama": "PT. Waste Bersih",
"alamat": "Jl. Gatot Subroto No. 120, Jakarta Selatan",
"tglBerlakuIzin": "2026-01-25"
},
{
"no": 44,
"nama": "UD. Sampah Lestari",
"alamat": "Jl. Cikini No. 100, Jakarta Pusat",
"tglBerlakuIzin": "2025-10-20"
},
{
"no": 45,
"nama": "PT. Eco Transport Mandiri",
"alamat": "Jl. Kuningan No. 120, Jakarta Selatan",
"tglBerlakuIzin": "2026-02-25"
},
{
"no": 46,
"nama": "CV. Green Mandiri",
"alamat": "Jl. Matraman No. 78, Jakarta Timur",
"tglBerlakuIzin": "2025-09-20"
},
{
"no": 47,
"nama": "PT. Clean Solution",
"alamat": "Jl. Casablanca No. 120, Jakarta Selatan",
"tglBerlakuIzin": "2026-03-25"
},
{
"no": 48,
"nama": "UD. Waste Lestari",
"alamat": "Jl. Kramat No. 56, Jakarta Pusat",
"tglBerlakuIzin": "2025-08-20"
},
{
"no": 49,
"nama": "PT. Urban Waste Lestari",
"alamat": "Jl. Sudirman No. 500, Jakarta Pusat",
"tglBerlakuIzin": "2026-04-20"
},
{
"no": 50,
"nama": "CV. Environmental Mandiri",
"alamat": "Jl. Tebet No. 120, Jakarta Selatan",
"tglBerlakuIzin": "2025-07-20"
}
]

View File

@ -0,0 +1,242 @@
[
{
"no": 1,
"nama": "PT. Waste Processing Jakarta",
"alamat": "Jl. Soekarno Hatta No. 123, Jakarta Timur",
"tglBerlakuIzin": "2025-12-31"
},
{
"no": 2,
"nama": "CV. Eco Recycle Indonesia",
"alamat": "Jl. Gatot Subroto No. 45, Jakarta Selatan",
"tglBerlakuIzin": "2025-11-15"
},
{
"no": 3,
"nama": "PT. Green Processing Solution",
"alamat": "Jl. Sudirman No. 78 Kelurahan Tanah Abang, Jakarta Pusat",
"tglBerlakuIzin": "2026-01-20"
},
{
"no": 4,
"nama": "UD. Daur Ulang Mandiri",
"alamat": "Jl. Thamrin No. 56, Jakarta Pusat",
"tglBerlakuIzin": "2025-10-30"
},
{
"no": 5,
"nama": "PT. Komposter Nusantara",
"alamat": "Jl. Kuningan No. 89, Jakarta Selatan",
"tglBerlakuIzin": "2026-02-14"
},
{
"no": 6,
"nama": "CV. Recycle Pro Indonesia",
"alamat": "Jl. Matraman No. 34, Jakarta Timur",
"tglBerlakuIzin": "2025-09-25"
},
{
"no": 7,
"nama": "PT. Waste Treatment Center",
"alamat": "Jl. Casablanca No. 67, Jakarta Selatan",
"tglBerlakuIzin": "2026-03-10"
},
{
"no": 8,
"nama": "UD. Pengolah Sampah Bersih",
"alamat": "Jl. Kramat No. 12, Jakarta Pusat",
"tglBerlakuIzin": "2025-08-18"
},
{
"no": 9,
"nama": "PT. Urban Waste Processing",
"alamat": "Jl. Sudirman No. 234, Jakarta Pusat",
"tglBerlakuIzin": "2026-04-05"
},
{
"no": 10,
"nama": "CV. Environmental Processing",
"alamat": "Jl. Tebet No. 78, Jakarta Selatan",
"tglBerlakuIzin": "2025-07-22"
},
{
"no": 11,
"nama": "PT. Sumber Daya Pengolahan",
"alamat": "Jl. Merdeka No. 101, Jakarta Barat",
"tglBerlakuIzin": "2026-05-12"
},
{
"no": 12,
"nama": "CV. Hijau Processing",
"alamat": "Jl. Mangga Dua No. 56, Jakarta Utara",
"tglBerlakuIzin": "2025-06-30"
},
{
"no": 13,
"nama": "PT. Lingkungan Processing",
"alamat": "Jl. Daan Mogot No. 88, Jakarta Barat",
"tglBerlakuIzin": "2026-07-19"
},
{
"no": 14,
"nama": "UD. Bersih Processing",
"alamat": "Jl. Salemba No. 23, Jakarta Pusat",
"tglBerlakuIzin": "2025-05-15"
},
{
"no": 15,
"nama": "PT. Eco Processing Nusantara",
"alamat": "Jl. Fatmawati No. 77, Jakarta Selatan",
"tglBerlakuIzin": "2026-08-25"
},
{
"no": 16,
"nama": "CV. Solusi Processing",
"alamat": "Jl. Pramuka No. 45, Jakarta Timur",
"tglBerlakuIzin": "2025-04-10"
},
{
"no": 17,
"nama": "PT. Lestari Processing",
"alamat": "Jl. Panjang No. 12, Jakarta Barat",
"tglBerlakuIzin": "2026-09-30"
},
{
"no": 18,
"nama": "UD. Hijau Processing",
"alamat": "Jl. Kemang No. 34, Jakarta Selatan",
"tglBerlakuIzin": "2025-03-18"
},
{
"no": 19,
"nama": "PT. Mitra Processing",
"alamat": "Jl. Pluit No. 56, Jakarta Utara",
"tglBerlakuIzin": "2026-10-11"
},
{
"no": 20,
"nama": "CV. Bersih Processing Jaya",
"alamat": "Jl. Pasar Minggu No. 89, Jakarta Selatan",
"tglBerlakuIzin": "2025-02-05"
},
{
"no": 21,
"nama": "PT. Processing Prima",
"alamat": "Jl. Sudirman No. 321, Jakarta Pusat",
"tglBerlakuIzin": "2026-11-01"
},
{
"no": 22,
"nama": "CV. Lingkungan Processing",
"alamat": "Jl. Thamrin No. 99, Jakarta Selatan",
"tglBerlakuIzin": "2025-12-12"
},
{
"no": 23,
"nama": "PT. Waste Processing Solution",
"alamat": "Jl. Gatot Subroto No. 88, Jakarta Selatan",
"tglBerlakuIzin": "2026-01-15"
},
{
"no": 24,
"nama": "UD. Sampah Processing",
"alamat": "Jl. Cikini No. 78, Jakarta Pusat",
"tglBerlakuIzin": "2025-10-10"
},
{
"no": 25,
"nama": "PT. Eco Processing Transportasi",
"alamat": "Jl. Kuningan No. 100, Jakarta Selatan",
"tglBerlakuIzin": "2026-02-20"
},
{
"no": 26,
"nama": "CV. Green Processing Solution",
"alamat": "Jl. Matraman No. 56, Jakarta Timur",
"tglBerlakuIzin": "2025-09-10"
},
{
"no": 27,
"nama": "PT. Clean Processing Indo",
"alamat": "Jl. Casablanca No. 88, Jakarta Selatan",
"tglBerlakuIzin": "2026-03-15"
},
{
"no": 28,
"nama": "UD. Waste Processing Pro",
"alamat": "Jl. Kramat No. 34, Jakarta Pusat",
"tglBerlakuIzin": "2025-08-10"
},
{
"no": 29,
"nama": "PT. Urban Processing Pro",
"alamat": "Jl. Sudirman No. 345, Jakarta Pusat",
"tglBerlakuIzin": "2026-04-10"
},
{
"no": 30,
"nama": "CV. Environmental Processing Solution",
"alamat": "Jl. Tebet No. 99, Jakarta Selatan",
"tglBerlakuIzin": "2025-07-10"
},
{
"no": 31,
"nama": "PT. Sumber Alam Processing",
"alamat": "Jl. Merdeka No. 200, Jakarta Barat",
"tglBerlakuIzin": "2026-05-20"
},
{
"no": 32,
"nama": "CV. Hijau Processing Bersama",
"alamat": "Jl. Mangga Dua No. 78, Jakarta Utara",
"tglBerlakuIzin": "2025-06-10"
},
{
"no": 33,
"nama": "PT. Lingkungan Processing Hijau",
"alamat": "Jl. Daan Mogot No. 99, Jakarta Barat",
"tglBerlakuIzin": "2026-07-10"
},
{
"no": 34,
"nama": "UD. Bersih Processing Lestari",
"alamat": "Jl. Salemba No. 45, Jakarta Pusat",
"tglBerlakuIzin": "2025-05-10"
},
{
"no": 35,
"nama": "PT. Eco Processing Nusantara",
"alamat": "Jl. Fatmawati No. 88, Jakarta Selatan",
"tglBerlakuIzin": "2026-08-10"
},
{
"no": 36,
"nama": "CV. Solusi Processing Hijau",
"alamat": "Jl. Pramuka No. 67, Jakarta Timur",
"tglBerlakuIzin": "2025-04-20"
},
{
"no": 37,
"nama": "PT. Lestari Processing Hijau",
"alamat": "Jl. Panjang No. 34, Jakarta Barat",
"tglBerlakuIzin": "2026-09-10"
},
{
"no": 38,
"nama": "UD. Hijau Processing Mandiri",
"alamat": "Jl. Kemang No. 56, Jakarta Selatan",
"tglBerlakuIzin": "2025-03-10"
},
{
"no": 39,
"nama": "PT. Mitra Processing Bersih",
"alamat": "Jl. Pluit No. 78, Jakarta Utara",
"tglBerlakuIzin": "2026-10-10"
},
{
"no": 40,
"nama": "CV. Bersih Processing Mandiri",
"alamat": "Jl. Pasar Minggu No. 100, Jakarta Selatan",
"tglBerlakuIzin": "2025-02-10"
}
]

View File

@ -0,0 +1,303 @@
document.addEventListener("DOMContentLoaded", function () {
initializePengangkutanDataTable();
});
function initializePengangkutanDataTable() {
if (!document.getElementById("pengangkutanTable")) return;
if (typeof $ !== "undefined" && $.fn.DataTable) {
$("#pengangkutanTable").DataTable({
ajax: {
url: "/website/data/pengangkutan-data.json",
type: "GET",
dataSrc: "",
},
columns: [
{
data: "no",
className: "px-6 py-4 text-sm text-gray-900 text-center font-medium",
title: "No",
width: "8%",
},
{
data: "nama",
className: "px-6 py-4 text-sm text-gray-900 font-medium",
title: "Nama Perusahaan",
width: "35%",
},
{
data: "alamat",
className: "px-6 py-4 text-sm text-gray-700",
title: "Alamat",
width: "40%",
},
{
data: "tglBerlakuIzin",
className: "px-6 py-4 text-sm text-gray-900 text-center",
title: "Berlaku Hingga",
width: "17%",
render: function (data, type, row) {
if (type === "display") {
const date = new Date(data);
const formattedDate = date.toLocaleDateString("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
const today = new Date();
const expiry = new Date(data);
const daysUntilExpiry = Math.ceil(
(expiry - today) / (1000 * 60 * 60 * 24)
);
let statusClass = "bg-green-100 text-green-800";
if (daysUntilExpiry < 30) {
statusClass = "bg-red-100 text-red-800";
} else if (daysUntilExpiry < 90) {
statusClass = "bg-yellow-100 text-yellow-800";
}
return `<div class="text-center">
<div class="text-sm font-medium text-gray-900 mb-1">${formattedDate}</div>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${statusClass}">
${
daysUntilExpiry > 0
? `${daysUntilExpiry} hari`
: "Expired"
}
</span>
</div>`;
}
return data;
},
},
],
language: {
search: "Cari:",
lengthMenu: "Tampilkan _MENU_ data per halaman",
info: "Menampilkan _START_ sampai _END_ dari _TOTAL_ data",
infoEmpty: "Menampilkan 0 sampai 0 dari 0 data",
infoFiltered: "(disaring dari _MAX_ total data)",
paginate: {
first: "Pertama",
last: "Terakhir",
next: "Selanjutnya",
previous: "Sebelumnya",
},
emptyTable: "Tidak ada data yang tersedia",
zeroRecords: "Tidak ditemukan data yang sesuai",
},
pageLength: 10,
responsive: false,
ordering: true,
searching: true,
paging: true,
info: true,
autoWidth: false,
scrollX: false,
layout: {
topStart: {
pageLength: {
text: "Tampilkan _MENU_ data",
},
},
topEnd: {
search: {
placeholder: "Cari perusahaan...",
},
},
bottomStart: "info",
bottomEnd: "paging",
},
initComplete: function () {
$("#loadingIndicator").hide();
const wrapper = $(".dataTables_wrapper");
wrapper
.find('input[type="search"]')
.addClass(
"block w-full px-4 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
)
.attr("placeholder", "Cari perusahaan...");
wrapper
.find("select")
.addClass(
"px-3 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
);
wrapper
.find(".dt-paging .dt-paging-button")
.addClass(
"px-3 py-2 mx-1 text-sm border border-gray-300 rounded-md bg-white text-gray-700 hover:bg-blue-50 hover:text-blue-600 hover:border-blue-300 transition-all duration-200"
);
wrapper
.find(".dt-paging .dt-paging-button.current")
.addClass("bg-blue-600 text-white border-blue-600 hover:bg-blue-700")
.removeClass("bg-white text-gray-700");
wrapper
.find(".dt-paging .dt-paging-button.disabled")
.addClass("opacity-50 cursor-not-allowed");
wrapper.find(".dt-length").addClass("flex items-center space-x-2");
wrapper.find(".dt-search").addClass("flex items-center space-x-2");
wrapper.find(".dt-info").addClass("text-sm text-gray-600");
$("#pengangkutanTable").removeClass("dataTable").addClass("w-full");
$("#pengangkutanTable thead th").addClass(
"bg-cyan-400 text-white font-semibold text-sm uppercase tracking-wider border-b"
);
wrapper.find(".dtr-control").remove();
$("#pengangkutanTable tbody tr").addClass(
"transition-all duration-200"
);
},
drawCallback: function () {
$("#pengangkutanTable tbody tr")
.removeClass("bg-blue-50")
.hover(
function () {
$(this).addClass(
"bg-blue-50 shadow-sm transform transition-all duration-200"
);
},
function () {
$(this).removeClass("bg-blue-50 shadow-sm transform");
}
);
$("#pengangkutanTable tbody tr:even").addClass("bg-gray-50");
$("#pengangkutanTable tbody tr:odd").addClass("bg-white");
},
});
} else {
loadPengangkutanDataManually();
}
}
function loadPengangkutanDataManually() {
fetch("/website/data/pengangkutan-data.json")
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((data) => {
const tbody = document.querySelector("#pengangkutanTable tbody");
tbody.innerHTML = "";
data.forEach((item, index) => {
const row = document.createElement("tr");
row.className = `${
index % 2 === 0 ? "bg-gray-50" : "bg-white"
} hover:bg-blue-50 transition-all duration-200`;
const date = new Date(item.tglBerlakuIzin);
const formattedDate = date.toLocaleDateString("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
const today = new Date();
const expiry = new Date(item.tglBerlakuIzin);
const daysUntilExpiry = Math.ceil(
(expiry - today) / (1000 * 60 * 60 * 24)
);
let statusClass = "bg-green-100 text-green-800";
let statusText = `${daysUntilExpiry} hari`;
if (daysUntilExpiry < 0) {
statusClass = "bg-red-100 text-red-800";
statusText = "Expired";
} else if (daysUntilExpiry < 30) {
statusClass = "bg-red-100 text-red-800";
} else if (daysUntilExpiry < 90) {
statusClass = "bg-yellow-100 text-yellow-800";
}
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 text-center font-medium">${item.no}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 font-medium">${item.nama}</td>
<td class="px-6 py-4 text-sm text-gray-700">${item.alamat}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 text-center">
<div class="text-sm font-medium text-gray-900">${formattedDate}</div>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${statusClass} mt-1">
${statusText}
</span>
</td>
`;
tbody.appendChild(row);
});
const loadingIndicator = document.getElementById("loadingIndicator");
if (loadingIndicator) {
loadingIndicator.style.display = "none";
}
addManualSearch(data);
})
.catch((error) => {
console.error("Error loading data:", error);
const loadingIndicator = document.getElementById("loadingIndicator");
if (loadingIndicator) {
loadingIndicator.innerHTML = `
<div class="text-red-500 text-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
Error memuat data: ${error.message}
</div>
`;
}
});
}
function addManualSearch(data) {
const tableContainer = document
.querySelector("#pengangkutanTable")
.closest(".bg-white");
if (!document.getElementById("manualSearchInput")) {
const searchContainer = document.createElement("div");
searchContainer.className = "mb-4 flex justify-end";
searchContainer.innerHTML = `
<div class="relative">
<input type="text" id="manualSearchInput" placeholder="Cari perusahaan..."
class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent pr-10">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</div>
</div>
`;
tableContainer.insertBefore(
searchContainer,
document.querySelector(".overflow-x-auto")
);
document
.getElementById("manualSearchInput")
.addEventListener("input", function (e) {
const searchTerm = e.target.value.toLowerCase();
const rows = document.querySelectorAll("#pengangkutanTable tbody tr");
rows.forEach((row) => {
const text = row.textContent.toLowerCase();
if (text.includes(searchTerm)) {
row.style.display = "";
} else {
row.style.display = "none";
}
});
});
}
}

View File

@ -0,0 +1,301 @@
document.addEventListener("DOMContentLoaded", function () {
initializePengolahanDataTable();
});
function initializePengolahanDataTable() {
if (!document.getElementById("pengolahanTable")) return;
if (typeof $ !== "undefined" && $.fn.DataTable) {
$("#pengolahanTable").DataTable({
ajax: {
url: "/website/data/pengolahan-data.json",
type: "GET",
dataSrc: "",
},
columns: [
{
data: "no",
className: "px-6 py-4 text-sm text-gray-900 text-center font-medium",
title: "No",
width: "8%",
},
{
data: "nama",
className: "px-6 py-4 text-sm text-gray-900 font-medium",
title: "Nama Perusahaan",
width: "28%",
},
{
data: "alamat",
className: "px-6 py-4 text-sm text-gray-700",
title: "Alamat",
width: "50%",
},
{
data: "tglBerlakuIzin",
className: "px-6 py-4 text-sm text-gray-900 text-center",
title: "Berlaku Hingga",
width: "25%",
render: function (data, type, row) {
if (type === "display") {
const date = new Date(data);
const formattedDate = date.toLocaleDateString("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
const today = new Date();
const expiry = new Date(data);
const daysUntilExpiry = Math.ceil(
(expiry - today) / (1000 * 60 * 60 * 24)
);
let statusClass = "bg-green-100 text-green-800";
if (daysUntilExpiry < 30) {
statusClass = "bg-red-100 text-red-800";
} else if (daysUntilExpiry < 90) {
statusClass = "bg-yellow-100 text-yellow-800";
}
return `<div class="text-center">
<div class="text-sm font-medium text-gray-900 mb-1">${formattedDate}</div>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${statusClass}">
${
daysUntilExpiry > 0
? `${daysUntilExpiry} hari`
: "Expired"
}
</span>
</div>`;
}
return data;
},
},
],
language: {
search: "Cari:",
lengthMenu: "Tampilkan _MENU_ data per halaman",
info: "Menampilkan _START_ sampai _END_ dari _TOTAL_ data",
infoEmpty: "Menampilkan 0 sampai 0 dari 0 data",
infoFiltered: "(disaring dari _MAX_ total data)",
paginate: {
first: "Pertama",
last: "Terakhir",
next: "Selanjutnya",
previous: "Sebelumnya",
},
emptyTable: "Tidak ada data yang tersedia",
zeroRecords: "Tidak ditemukan data yang sesuai",
},
pageLength: 10,
responsive: false,
ordering: true,
searching: true,
paging: true,
info: true,
autoWidth: false,
scrollX: false,
layout: {
topStart: {
pageLength: {
text: "Tampilkan _MENU_ data",
},
},
topEnd: {
search: {
placeholder: "Cari perusahaan pengolahan...",
},
},
bottomStart: "info",
bottomEnd: "paging",
},
initComplete: function () {
$("#loadingIndicator").hide();
const wrapper = $(".dataTables_wrapper");
wrapper
.find('input[type="search"]')
.addClass(
"block w-full px-4 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 w-full"
)
.attr("placeholder", "Cari perusahaan pengolahan...");
wrapper
.find("select")
.addClass(
"px-3 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
);
wrapper
.find(".dt-paging .dt-paging-button")
.addClass(
"px-3 py-2 mx-1 text-sm border border-gray-300 rounded-md bg-white text-gray-700 hover:bg-blue-50 hover:text-blue-600 hover:border-blue-300 transition-all duration-200"
);
wrapper
.find(".dt-paging .dt-paging-button.current")
.addClass("bg-blue-600 text-white border-blue-600 hover:bg-blue-700")
.removeClass("bg-white text-gray-700");
wrapper
.find(".dt-paging .dt-paging-button.disabled")
.addClass("opacity-50 cursor-not-allowed");
wrapper.find(".dt-length").addClass("flex items-center space-x-2");
wrapper.find(".dt-search").addClass("flex items-center space-x-2");
wrapper.find(".dt-info").addClass("text-sm text-gray-600");
$("#pengolahanTable").removeClass("dataTable").addClass("w-full");
$("#pengolahanTable thead th").addClass(
"bg-cyan-400 text-white font-semibold text-sm uppercase tracking-wider border-b"
);
wrapper.find(".dtr-control").remove();
$("#pengolahanTable tbody tr").addClass("transition-all duration-200");
},
drawCallback: function () {
$("#pengolahanTable tbody tr")
.removeClass("bg-blue-50")
.hover(
function () {
$(this).addClass(
"bg-blue-50 shadow-sm transform transition-all duration-200"
);
},
function () {
$(this).removeClass("bg-blue-50 shadow-sm transform");
}
);
$("#pengolahanTable tbody tr:even").addClass("bg-gray-50");
$("#pengolahanTable tbody tr:odd").addClass("bg-white");
},
});
} else {
loadPengolahanDataManually();
}
}
function loadPengolahanDataManually() {
fetch("/website/data/pengolahan-data.json")
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((data) => {
const tbody = document.querySelector("#pengolahanTable tbody");
tbody.innerHTML = "";
data.forEach((item, index) => {
const row = document.createElement("tr");
row.className = `${
index % 2 === 0 ? "bg-gray-50" : "bg-white"
} hover:bg-blue-50 transition-all duration-200`;
const date = new Date(item.tglBerlakuIzin);
const formattedDate = date.toLocaleDateString("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
const today = new Date();
const expiry = new Date(item.tglBerlakuIzin);
const daysUntilExpiry = Math.ceil(
(expiry - today) / (1000 * 60 * 60 * 24)
);
let statusClass = "bg-green-100 text-green-800";
let statusText = `${daysUntilExpiry} hari`;
if (daysUntilExpiry < 0) {
statusClass = "bg-red-100 text-red-800";
statusText = "Expired";
} else if (daysUntilExpiry < 30) {
statusClass = "bg-red-100 text-red-800";
} else if (daysUntilExpiry < 90) {
statusClass = "bg-yellow-100 text-yellow-800";
}
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 text-center font-medium">${item.no}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 font-medium">${item.nama}</td>
<td class="px-6 py-4 text-sm text-gray-700">${item.alamat}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 text-center">
<div class="text-sm font-medium text-gray-900">${formattedDate}</div>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${statusClass} mt-1">
${statusText}
</span>
</td>
`;
tbody.appendChild(row);
});
const loadingIndicator = document.getElementById("loadingIndicator");
if (loadingIndicator) {
loadingIndicator.style.display = "none";
}
addManualSearch(data);
})
.catch((error) => {
console.error("Error loading data:", error);
const loadingIndicator = document.getElementById("loadingIndicator");
if (loadingIndicator) {
loadingIndicator.innerHTML = `
<div class="text-red-500 text-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
Error memuat data: ${error.message}
</div>
`;
}
});
}
function addManualSearch(data) {
const tableContainer = document
.querySelector("#pengolahanTable")
.closest(".bg-white");
if (!document.getElementById("manualSearchInput")) {
const searchContainer = document.createElement("div");
searchContainer.className = "mb-4 flex justify-end";
searchContainer.innerHTML = `
<div class="relative">
<input type="text" id="manualSearchInput" placeholder="Cari perusahaan pengolahan..."
class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent pr-10">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</div>
</div>
`;
tableContainer.insertBefore(
searchContainer,
document.querySelector(".overflow-x-auto")
);
document
.getElementById("manualSearchInput")
.addEventListener("input", function (e) {
const searchTerm = e.target.value.toLowerCase();
const rows = document.querySelectorAll("#pengolahanTable tbody tr");
rows.forEach((row) => {
const text = row.textContent.toLowerCase();
if (text.includes(searchTerm)) {
row.style.display = "";
} else {
row.style.display = "none";
}
});
});
}
}

View File

@ -0,0 +1,199 @@
let activeDropdown = null;
let isAnimating = false;
function toggleDropdown(sectionId) {
if (isAnimating) return;
const content = document.getElementById(sectionId);
const header = content.previousElementSibling;
const icon = header.querySelector(".dropdown-icon");
isAnimating = true;
if (content.classList.contains("open")) {
closeDropdown(content, header, icon);
activeDropdown = null;
} else {
if (activeDropdown) {
const activeContent = document.getElementById(activeDropdown);
const activeHeader = activeContent.previousElementSibling;
const activeIcon = activeHeader.querySelector(".dropdown-icon");
closeDropdown(activeContent, activeHeader, activeIcon);
}
openDropdown(content, header, icon, sectionId);
activeDropdown = sectionId;
}
setTimeout(() => {
isAnimating = false;
}, 500);
}
function openDropdown(content, header, icon, sectionId) {
createRipple(header, event);
content.classList.add("opening");
header.classList.add("active");
content.style.maxHeight = content.scrollHeight + "px";
content.classList.add("open");
icon.style.transform = "rotate(180deg) scale(1.1)";
setTimeout(() => {
icon.style.transform = "rotate(180deg) scale(1)";
}, 150);
const items = content.querySelectorAll("h3, p, ul, table, .content-item");
items.forEach((item, index) => {
item.style.opacity = "0";
item.style.transform = "translateY(20px)";
setTimeout(() => {
item.style.opacity = "1";
item.style.transform = "translateY(0)";
}, 100 + index * 50);
});
setTimeout(() => {
content.classList.remove("opening");
}, 400);
}
function closeDropdown(content, header, icon) {
content.classList.add("closing");
header.classList.remove("active");
const items = content.querySelectorAll("h3, p, ul, table, .content-item");
items.forEach((item) => {
item.style.opacity = "0";
item.style.transform = "translateY(-10px)";
});
setTimeout(() => {
content.classList.remove("open");
content.style.maxHeight = "0px";
icon.style.transform = "rotate(0deg)";
}, 150);
setTimeout(() => {
content.classList.remove("closing");
}, 400);
}
function createRipple(element, event) {
const ripple = document.createElement("div");
ripple.className = "ripple-effect";
const rect = element.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
const x =
(event?.clientX || rect.left + rect.width / 2) - rect.left - size / 2;
const y =
(event?.clientY || rect.top + rect.height / 2) - rect.top - size / 2;
ripple.style.cssText = `
position: absolute;
width: ${size}px;
height: ${size}px;
left: ${x}px;
top: ${y}px;
background: radial-gradient(circle, rgba(59, 130, 246, 0.3) 0%, transparent 70%);
border-radius: 50%;
transform: scale(0);
pointer-events: none;
z-index: 1;
`;
element.style.position = "relative";
element.style.overflow = "hidden";
element.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
}
document.addEventListener("DOMContentLoaded", function () {
const style = document.createElement("style");
style.textContent = `
@keyframes ripple-animation {
to {
transform: scale(2);
opacity: 0;
}
}
@keyframes glow-pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); }
50% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); }
}
@keyframes slide-in {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
`;
document.head.appendChild(style);
const dropdownContents = document.querySelectorAll(".dropdown-content");
dropdownContents.forEach((content, index) => {
content.style.maxHeight = "0px";
content.style.overflow = "hidden";
content.style.transition =
"max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease";
content.style.animation = `slide-in 0.6s ease ${index * 0.1}s both`;
const items = content.querySelectorAll("h3, p, ul, table");
items.forEach((item) => {
if (!item.classList.contains("content-item")) {
item.classList.add("content-item");
}
});
});
const dropdownHeaders = document.querySelectorAll(".dropdown-header");
dropdownHeaders.forEach((header, index) => {
header.style.animation = `slide-in 0.6s ease ${index * 0.1}s both`;
header.addEventListener("mouseenter", function () {
this.style.transform = "translateY(-2px)";
});
header.addEventListener("mouseleave", function () {
this.style.transform = "translateY(0)";
});
});
});
document.addEventListener("click", function (event) {
if (
!event.target.closest(".dropdown-header") &&
!event.target.closest(".dropdown-content")
) {
if (activeDropdown && !isAnimating) {
const content = document.getElementById(activeDropdown);
const header = content.previousElementSibling;
const icon = header.querySelector(".dropdown-icon");
closeDropdown(content, header, icon);
activeDropdown = null;
}
}
});
document.addEventListener("keydown", function (event) {
if (event.key === "Escape" && activeDropdown) {
const content = document.getElementById(activeDropdown);
const header = content.previousElementSibling;
const icon = header.querySelector(".dropdown-icon");
closeDropdown(content, header, icon);
activeDropdown = null;
}
});

View File

@ -0,0 +1,382 @@
let isWhatsAppWidgetOpen = false;
document.addEventListener("DOMContentLoaded", function () {
updateCurrentTime();
setInterval(updateCurrentTime, 60000);
});
function toggleWhatsAppWidget() {
const popup = document.getElementById("whatsappPopup");
const button = document.querySelector(".whatsapp-button");
if (!isWhatsAppWidgetOpen) {
popup.classList.add("show");
button.style.transform = "rotate(360deg)";
isWhatsAppWidgetOpen = true;
setTimeout(() => {
const message = document.querySelector(".chat-message");
if (message) {
message.style.animation = "slideInUp 0.5s ease-out";
}
}, 200);
} else {
popup.classList.remove("show");
button.style.transform = "rotate(0deg)";
isWhatsAppWidgetOpen = false;
}
}
function sendWhatsAppMessage(prefilledMessage, helpdesk = "sistem") {
const helpdeskNumbers = {
sistem: "6285212436339",
blud: "6282211001180",
};
const phoneNumber = helpdeskNumbers[helpdesk];
const message =
prefilledMessage ||
`Halo, saya membutuhkan bantuan mengenai ${
helpdesk === "sistem" ? "Sistem Pesapakawan" : "BLUD UPST"
}.`;
const encodedMessage = encodeURIComponent(message);
const whatsappUrl = `https://wa.me/${phoneNumber}?text=${encodedMessage}`;
const button = document.querySelector(".whatsapp-chat-btn");
if (button) {
button.style.transform = "scale(0.95)";
setTimeout(() => {
button.style.transform = "scale(1)";
}, 150);
}
window.open(whatsappUrl, "_blank");
setTimeout(() => {
toggleWhatsAppWidget();
}, 300);
}
function showHelpdeskSelection(prefilledMessage) {
const modal = document.createElement("div");
modal.className = "helpdesk-modal";
modal.innerHTML = `
<div class="helpdesk-modal-content">
<h3>Pilih Helpdesk</h3>
<p>Silakan pilih helpdesk yang sesuai dengan kebutuhan Anda:</p>
<div class="helpdesk-options">
<button class="helpdesk-option" onclick="selectHelpdesk('sistem', '${prefilledMessage}')">
<div class="option-icon">💻</div>
<div class="option-details">
<h4>Help Desk Sistem Pesapakawan</h4>
<p>0852-1243-6339</p>
<small>Bantuan teknis aplikasi dan sistem</small>
</div>
</button>
<button class="helpdesk-option" onclick="selectHelpdesk('blud', '${prefilledMessage}')">
<div class="option-icon"></div>
<div class="option-details">
<h4>Helpdesk BLUD UPST</h4>
<p>0822-1100-1180</p>
<small>Bantuan layanan BLUD UPST</small>
</div>
</button>
</div>
<button class="close-modal" onclick="closeHelpdeskModal()">Tutup</button>
</div>
`;
document.body.appendChild(modal);
setTimeout(() => {
modal.classList.add("show");
}, 10);
}
function selectHelpdesk(helpdesk, message) {
closeHelpdeskModal();
sendWhatsAppMessage(message, helpdesk);
}
function closeHelpdeskModal() {
const modal = document.querySelector(".helpdesk-modal");
if (modal) {
modal.classList.remove("show");
setTimeout(() => {
modal.remove();
}, 300);
}
}
function updateCurrentTime() {
const timeElement = document.getElementById("currentTime");
if (timeElement) {
const now = new Date();
const timeString = now.toLocaleTimeString("id-ID", {
hour: "2-digit",
minute: "2-digit",
});
timeElement.textContent = timeString;
}
}
document.addEventListener("click", function (event) {
const widget = document.querySelector(".whatsapp-widget");
const popup = document.getElementById("whatsappPopup");
if (widget && !widget.contains(event.target) && isWhatsAppWidgetOpen) {
popup.classList.remove("show");
document.querySelector(".whatsapp-button").style.transform = "rotate(0deg)";
isWhatsAppWidgetOpen = false;
}
});
document.addEventListener("click", function (event) {
if (event.target.closest(".whatsapp-popup")) {
event.stopPropagation();
}
});
document.addEventListener("DOMContentLoaded", function () {
const optionButtons = document.querySelectorAll(".option-btn");
optionButtons.forEach((button, index) => {
button.style.animationDelay = `${index * 0.1}s`;
button.classList.add("fade-in-up");
});
});
const style = document.createElement("style");
style.textContent = `
.fade-in-up {
animation: fadeInUp 0.6s ease-out forwards;
opacity: 0;
transform: translateY(20px);
}
@keyframes fadeInUp {
to {
opacity: 1;
transform: translateY(0);
}
}
`;
document.head.appendChild(style);
function showTypingIndicator() {
const messageContainer = document.querySelector(".chat-message");
const typingIndicator = document.createElement("div");
typingIndicator.className = "typing-indicator";
typingIndicator.innerHTML = `
<div class="typing-dots">
<span></span>
<span></span>
<span></span>
</div>
`;
messageContainer.appendChild(typingIndicator);
setTimeout(() => {
typingIndicator.remove();
}, 2000);
}
document.addEventListener("DOMContentLoaded", function () {
const whatsappButton = document.querySelector(".whatsapp-button");
whatsappButton.addEventListener("mouseenter", function () {
this.style.animationPlayState = "paused";
});
whatsappButton.addEventListener("mouseleave", function () {
this.style.animationPlayState = "running";
});
});
function createRipple(event) {
const button = event.currentTarget;
const circle = document.createElement("span");
const diameter = Math.max(button.clientWidth, button.clientHeight);
const radius = diameter / 2;
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - button.offsetLeft - radius}px`;
circle.style.top = `${event.clientY - button.offsetTop - radius}px`;
circle.classList.add("ripple");
const ripple = button.getElementsByClassName("ripple")[0];
if (ripple) {
ripple.remove();
}
button.appendChild(circle);
}
document.addEventListener("DOMContentLoaded", function () {
const buttons = document.querySelectorAll(".option-btn, .whatsapp-chat-btn");
buttons.forEach((button) => {
button.addEventListener("click", createRipple);
});
});
const rippleStyle = document.createElement("style");
rippleStyle.textContent = `
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple 600ms linear;
background-color: rgba(255, 255, 255, 0.6);
pointer-events: none;
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
.option-btn, .whatsapp-chat-btn {
position: relative;
overflow: hidden;
}
/* Helpdesk Modal Styles */
.helpdesk-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 2000;
opacity: 0;
transition: opacity 0.3s ease;
}
.helpdesk-modal.show {
opacity: 1;
}
.helpdesk-modal-content {
background: white;
border-radius: 15px;
padding: 25px;
max-width: 450px;
width: 90%;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
transform: translateY(20px);
transition: transform 0.3s ease;
}
.helpdesk-modal.show .helpdesk-modal-content {
transform: translateY(0);
}
.helpdesk-modal h3 {
margin: 0 0 10px 0;
color: #333;
font-size: 20px;
font-weight: 600;
}
.helpdesk-modal p {
margin: 0 0 20px 0;
color: #666;
font-size: 14px;
}
.helpdesk-options {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 20px;
}
.helpdesk-option {
display: flex;
align-items: center;
gap: 15px;
padding: 15px;
border: 2px solid #e9ecef;
border-radius: 10px;
background: #f8f9fa;
cursor: pointer;
transition: all 0.3s ease;
text-align: left;
}
.helpdesk-option:hover {
border-color: #25D366;
background: #f0fff4;
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(37, 211, 102, 0.2);
}
.option-icon {
font-size: 24px;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: #25D366;
border-radius: 8px;
color: white;
}
.option-details h4 {
margin: 0 0 5px 0;
font-size: 16px;
font-weight: 600;
color: #333;
}
.option-details p {
margin: 0 0 5px 0;
font-size: 14px;
color: #25D366;
font-weight: 600;
}
.option-details small {
font-size: 12px;
color: #666;
}
.close-modal {
width: 100%;
padding: 12px;
background: #6c757d;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: background 0.3s ease;
}
.close-modal:hover {
background: #5a6268;
}
@media (max-width: 480px) {
.helpdesk-modal-content {
margin: 20px;
width: calc(100% - 40px);
}
.helpdesk-option {
flex-direction: column;
text-align: center;
gap: 10px;
}
}
`;
document.head.appendChild(rippleStyle);

View File

@ -1,4 +0,0 @@
// Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code.