refactor: menu maggot & komposting
parent
0f1b8f5235
commit
34c1cd289b
|
|
@ -14,14 +14,47 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Table([FromQuery] string? bulan)
|
||||
public IActionResult Table([FromQuery] string? bulan, [FromQuery] string? tahun)
|
||||
{
|
||||
var data = ReduksiSampahDataStore
|
||||
.GetItems(Jenis)
|
||||
.Where(item => ReduksiSampahDataStore.MatchesBulan(item, bulan))
|
||||
.Select(ReduksiSampahDataStore.ToResponse);
|
||||
.Where(item => ReduksiSampahDataStore.MatchesPeriode(item, bulan, tahun))
|
||||
.Select(ReduksiSampahDataStore.ToDetailedResponse);
|
||||
|
||||
return Json(new { data });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Update([FromBody] MaggotController.MaggotUpdateRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return BadRequest(new { message = "Permintaan tidak valid." });
|
||||
}
|
||||
|
||||
var updated = ReduksiSampahDataStore.UpdateReduksiValues(
|
||||
Jenis,
|
||||
request.Id,
|
||||
request.Status,
|
||||
request.B1,
|
||||
request.B2,
|
||||
request.B3,
|
||||
request.B4,
|
||||
request.B5,
|
||||
request.B6,
|
||||
request.B7,
|
||||
request.B8,
|
||||
request.B9,
|
||||
request.B10,
|
||||
request.B11,
|
||||
request.B12);
|
||||
|
||||
if (!updated)
|
||||
{
|
||||
return NotFound(new { message = "Data komposting tidak ditemukan." });
|
||||
}
|
||||
|
||||
return Ok(new { message = "Data komposting berhasil diperbarui." });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,65 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Table([FromQuery] string? bulan)
|
||||
public IActionResult Table([FromQuery] string? bulan, [FromQuery] string? tahun)
|
||||
{
|
||||
var data = ReduksiSampahDataStore
|
||||
.GetItems(Jenis)
|
||||
.Where(item => ReduksiSampahDataStore.MatchesBulan(item, bulan))
|
||||
.Select(ReduksiSampahDataStore.ToResponse);
|
||||
.Where(item => ReduksiSampahDataStore.MatchesPeriode(item, bulan, tahun))
|
||||
.Select(ReduksiSampahDataStore.ToDetailedResponse);
|
||||
|
||||
return Json(new { data });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Update([FromBody] MaggotUpdateRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return BadRequest(new { message = "Permintaan tidak valid." });
|
||||
}
|
||||
|
||||
var updated = ReduksiSampahDataStore.UpdateReduksiValues(
|
||||
Jenis,
|
||||
request.Id,
|
||||
request.Status,
|
||||
request.B1,
|
||||
request.B2,
|
||||
request.B3,
|
||||
request.B4,
|
||||
request.B5,
|
||||
request.B6,
|
||||
request.B7,
|
||||
request.B8,
|
||||
request.B9,
|
||||
request.B10,
|
||||
request.B11,
|
||||
request.B12);
|
||||
|
||||
if (!updated)
|
||||
{
|
||||
return NotFound(new { message = "Data maggot tidak ditemukan." });
|
||||
}
|
||||
|
||||
return Ok(new { message = "Data maggot berhasil diperbarui." });
|
||||
}
|
||||
|
||||
public class MaggotUpdateRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string? Status { get; set; }
|
||||
public decimal? B1 { get; set; }
|
||||
public decimal? B2 { get; set; }
|
||||
public decimal? B3 { get; set; }
|
||||
public decimal? B4 { get; set; }
|
||||
public decimal? B5 { get; set; }
|
||||
public decimal? B6 { get; set; }
|
||||
public decimal? B7 { get; set; }
|
||||
public decimal? B8 { get; set; }
|
||||
public decimal? B9 { get; set; }
|
||||
public decimal? B10 { get; set; }
|
||||
public decimal? B11 { get; set; }
|
||||
public decimal? B12 { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,25 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Maggot",
|
||||
BeratReduksi = 8,
|
||||
BeratSampah = 15,
|
||||
Alamat = AddressBlock("Tanah Abang", "Cideng", "002", "001")
|
||||
Kecamatan = "Tanah Abang",
|
||||
Kelurahan = "Cideng",
|
||||
Rt = "002",
|
||||
Rw = "001",
|
||||
DetailAlamat = "Jl. Kebersihan No. 12",
|
||||
Status = "Aktif",
|
||||
B1 = 12.5m,
|
||||
B2 = 13.2m,
|
||||
B3 = 11.8m,
|
||||
B4 = 14.4m,
|
||||
B5 = 15.1m,
|
||||
B6 = 12.9m,
|
||||
B7 = 13.5m,
|
||||
B8 = 12.3m,
|
||||
B9 = 14.1m,
|
||||
B10 = 13.7m,
|
||||
B11 = 12.8m,
|
||||
B12 = 13.0m,
|
||||
Alamat = AddressBlock("Tanah Abang", "Cideng", "002", "001", "Jl. Kebersihan No. 12")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -26,7 +44,25 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Maggot",
|
||||
BeratReduksi = 10,
|
||||
BeratSampah = 20,
|
||||
Alamat = AddressBlock("Palmerah", "Kemanggisan", "003", "004")
|
||||
Kecamatan = "Palmerah",
|
||||
Kelurahan = "Kemanggisan",
|
||||
Rt = "003",
|
||||
Rw = "004",
|
||||
DetailAlamat = "Jl. Kemanggisan Raya No. 9",
|
||||
Status = "Aktif",
|
||||
B1 = 10.2m,
|
||||
B2 = 11.4m,
|
||||
B3 = 10.8m,
|
||||
B4 = 12.6m,
|
||||
B5 = 13.3m,
|
||||
B6 = 11.9m,
|
||||
B7 = 12.8m,
|
||||
B8 = 11.1m,
|
||||
B9 = 12.4m,
|
||||
B10 = 11.9m,
|
||||
B11 = 11.4m,
|
||||
B12 = 12.0m,
|
||||
Alamat = AddressBlock("Palmerah", "Kemanggisan", "003", "004", "Jl. Kemanggisan Raya No. 9")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -36,7 +72,25 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Maggot",
|
||||
BeratReduksi = 7,
|
||||
BeratSampah = 14,
|
||||
Alamat = AddressBlock("Tebet", "Manggarai", "001", "002")
|
||||
Kecamatan = "Tebet",
|
||||
Kelurahan = "Manggarai",
|
||||
Rt = "001",
|
||||
Rw = "002",
|
||||
DetailAlamat = "Jl. Manggarai Utara No. 7",
|
||||
Status = "Tidak Aktif",
|
||||
B1 = 9.5m,
|
||||
B2 = 9.9m,
|
||||
B3 = 10.1m,
|
||||
B4 = 10.5m,
|
||||
B5 = 10.2m,
|
||||
B6 = 9.7m,
|
||||
B7 = 9.9m,
|
||||
B8 = 10.0m,
|
||||
B9 = 9.8m,
|
||||
B10 = 10.1m,
|
||||
B11 = 9.6m,
|
||||
B12 = 9.9m,
|
||||
Alamat = AddressBlock("Tebet", "Manggarai", "001", "002", "Jl. Manggarai Utara No. 7")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -46,7 +100,25 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Maggot",
|
||||
BeratReduksi = 6,
|
||||
BeratSampah = 12,
|
||||
Alamat = AddressBlock("Cakung", "Jatinegara", "004", "006")
|
||||
Kecamatan = "Cakung",
|
||||
Kelurahan = "Jatinegara",
|
||||
Rt = "004",
|
||||
Rw = "006",
|
||||
DetailAlamat = "Jl. Industri Hijau No. 5",
|
||||
Status = "Aktif",
|
||||
B1 = 14.6m,
|
||||
B2 = 13.9m,
|
||||
B3 = 14.1m,
|
||||
B4 = 14.8m,
|
||||
B5 = 15.3m,
|
||||
B6 = 14.5m,
|
||||
B7 = 15.0m,
|
||||
B8 = 14.2m,
|
||||
B9 = 15.1m,
|
||||
B10 = 14.7m,
|
||||
B11 = 14.3m,
|
||||
B12 = 14.9m,
|
||||
Alamat = AddressBlock("Cakung", "Jatinegara", "004", "006", "Jl. Industri Hijau No. 5")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -56,7 +128,25 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Maggot",
|
||||
BeratReduksi = 9,
|
||||
BeratSampah = 16,
|
||||
Alamat = AddressBlock("Koja", "Lagoa", "005", "003")
|
||||
Kecamatan = "Koja",
|
||||
Kelurahan = "Lagoa",
|
||||
Rt = "005",
|
||||
Rw = "003",
|
||||
DetailAlamat = "Jl. Lagoa Mas No. 3",
|
||||
Status = "Aktif",
|
||||
B1 = 11.7m,
|
||||
B2 = 11.3m,
|
||||
B3 = 11.1m,
|
||||
B4 = 11.8m,
|
||||
B5 = 12.4m,
|
||||
B6 = 11.5m,
|
||||
B7 = 11.9m,
|
||||
B8 = 11.2m,
|
||||
B9 = 12.0m,
|
||||
B10 = 11.6m,
|
||||
B11 = 11.3m,
|
||||
B12 = 11.9m,
|
||||
Alamat = AddressBlock("Koja", "Lagoa", "005", "003", "Jl. Lagoa Mas No. 3")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -66,7 +156,12 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Komposting",
|
||||
BeratReduksi = 11,
|
||||
BeratSampah = 18,
|
||||
Alamat = AddressBlock("Beji", "Beji Timur", "006", "002")
|
||||
Kecamatan = "Beji",
|
||||
Kelurahan = "Beji Timur",
|
||||
Rt = "006",
|
||||
Rw = "002",
|
||||
DetailAlamat = "Jl. Melati Hijau No. 10",
|
||||
Alamat = AddressBlock("Beji", "Beji Timur", "006", "002", "Jl. Melati Hijau No. 10")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -76,7 +171,12 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Komposting",
|
||||
BeratReduksi = 13,
|
||||
BeratSampah = 21,
|
||||
Alamat = AddressBlock("Bekasi Timur", "Margahayu", "009", "005")
|
||||
Kecamatan = "Bekasi Timur",
|
||||
Kelurahan = "Margahayu",
|
||||
Rt = "009",
|
||||
Rw = "005",
|
||||
DetailAlamat = "Jl. Margahayu Harmonis No. 8",
|
||||
Alamat = AddressBlock("Bekasi Timur", "Margahayu", "009", "005", "Jl. Margahayu Harmonis No. 8")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -86,7 +186,12 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Komposting",
|
||||
BeratReduksi = 9,
|
||||
BeratSampah = 15,
|
||||
Alamat = AddressBlock("Bogor Utara", "Kedunghalang", "001", "004")
|
||||
Kecamatan = "Bogor Utara",
|
||||
Kelurahan = "Kedunghalang",
|
||||
Rt = "001",
|
||||
Rw = "004",
|
||||
DetailAlamat = "Jl. Kedunghalang Sejahtera No. 2",
|
||||
Alamat = AddressBlock("Bogor Utara", "Kedunghalang", "001", "004", "Jl. Kedunghalang Sejahtera No. 2")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -96,7 +201,12 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Komposting",
|
||||
BeratReduksi = 8,
|
||||
BeratSampah = 13,
|
||||
Alamat = AddressBlock("Karawaci", "Nusa Jaya", "008", "003")
|
||||
Kecamatan = "Karawaci",
|
||||
Kelurahan = "Nusa Jaya",
|
||||
Rt = "008",
|
||||
Rw = "003",
|
||||
DetailAlamat = "Jl. Nusa Jaya Indah No. 11",
|
||||
Alamat = AddressBlock("Karawaci", "Nusa Jaya", "008", "003", "Jl. Nusa Jaya Indah No. 11")
|
||||
},
|
||||
new()
|
||||
{
|
||||
|
|
@ -106,7 +216,12 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
JenisLokasi = "Komposting",
|
||||
BeratReduksi = 12,
|
||||
BeratSampah = 19,
|
||||
Alamat = AddressBlock("Ciwandan", "Kebonsari", "010", "002")
|
||||
Kecamatan = "Ciwandan",
|
||||
Kelurahan = "Kebonsari",
|
||||
Rt = "010",
|
||||
Rw = "002",
|
||||
DetailAlamat = "Jl. Kebonsari Permai No. 4",
|
||||
Alamat = AddressBlock("Ciwandan", "Kebonsari", "010", "002", "Jl. Kebonsari Permai No. 4")
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -133,6 +248,21 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
return item.PeriodeBulan.Contains(bulan.Trim(), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static bool MatchesPeriode(ReduksiSampahItem item, string? bulan, string? tahun)
|
||||
{
|
||||
if (!MatchesBulan(item, bulan))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tahun))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return item.PeriodeBulan.EndsWith(tahun.Trim(), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static object ToResponse(ReduksiSampahItem item) => new
|
||||
{
|
||||
id = item.Id,
|
||||
|
|
@ -146,7 +276,78 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
aksi = ActionButtons
|
||||
};
|
||||
|
||||
private static string AddressBlock(string kecamatan, string kelurahan, string rt, string rw)
|
||||
public static object ToDetailedResponse(ReduksiSampahItem item) => new
|
||||
{
|
||||
id = item.Id,
|
||||
periode = item.PeriodeBulan,
|
||||
kecamatan = item.Kecamatan,
|
||||
kelurahan = item.Kelurahan,
|
||||
rt = item.Rt,
|
||||
rw = item.Rw,
|
||||
detail_alamat = item.DetailAlamat,
|
||||
status = item.Status,
|
||||
b1 = item.B1,
|
||||
b2 = item.B2,
|
||||
b3 = item.B3,
|
||||
b4 = item.B4,
|
||||
b5 = item.B5,
|
||||
b6 = item.B6,
|
||||
b7 = item.B7,
|
||||
b8 = item.B8,
|
||||
b9 = item.B9,
|
||||
b10 = item.B10,
|
||||
b11 = item.B11,
|
||||
b12 = item.B12
|
||||
};
|
||||
|
||||
public static bool UpdateReduksiValues(
|
||||
string jenisLokasi,
|
||||
int id,
|
||||
string? status,
|
||||
decimal? b1,
|
||||
decimal? b2,
|
||||
decimal? b3,
|
||||
decimal? b4,
|
||||
decimal? b5,
|
||||
decimal? b6,
|
||||
decimal? b7,
|
||||
decimal? b8,
|
||||
decimal? b9,
|
||||
decimal? b10,
|
||||
decimal? b11,
|
||||
decimal? b12)
|
||||
{
|
||||
var item = Items.FirstOrDefault(x =>
|
||||
x.Id == id &&
|
||||
string.Equals(x.JenisLokasi, jenisLokasi, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
{
|
||||
item.Status = status;
|
||||
}
|
||||
|
||||
if (b1.HasValue) item.B1 = b1.Value;
|
||||
if (b2.HasValue) item.B2 = b2.Value;
|
||||
if (b3.HasValue) item.B3 = b3.Value;
|
||||
if (b4.HasValue) item.B4 = b4.Value;
|
||||
if (b5.HasValue) item.B5 = b5.Value;
|
||||
if (b6.HasValue) item.B6 = b6.Value;
|
||||
if (b7.HasValue) item.B7 = b7.Value;
|
||||
if (b8.HasValue) item.B8 = b8.Value;
|
||||
if (b9.HasValue) item.B9 = b9.Value;
|
||||
if (b10.HasValue) item.B10 = b10.Value;
|
||||
if (b11.HasValue) item.B11 = b11.Value;
|
||||
if (b12.HasValue) item.B12 = b12.Value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string AddressBlock(string kecamatan, string kelurahan, string rt, string rw, string detailAlamat)
|
||||
{
|
||||
return $@"
|
||||
<div class=""flex flex-col gap-1"">
|
||||
|
|
@ -156,6 +357,7 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
<span>RT {rt}</span>
|
||||
<span>RW {rw}</span>
|
||||
</div>
|
||||
<span class=""text-xs text-gray-500"">{detailAlamat}</span>
|
||||
</div>";
|
||||
}
|
||||
|
||||
|
|
@ -165,9 +367,27 @@ namespace BankSampahApp.Controllers.ReduksiSampah
|
|||
public string PeriodeBulan { get; set; } = string.Empty;
|
||||
public string NamaLokasi { get; set; } = string.Empty;
|
||||
public string Alamat { get; set; } = string.Empty;
|
||||
public string DetailAlamat { get; set; } = string.Empty;
|
||||
public string Kecamatan { get; set; } = string.Empty;
|
||||
public string Kelurahan { get; set; } = string.Empty;
|
||||
public string Rt { get; set; } = string.Empty;
|
||||
public string Rw { get; set; } = string.Empty;
|
||||
public string JenisLokasi { get; set; } = string.Empty;
|
||||
public string Status { get; set; } = "Aktif";
|
||||
public double BeratReduksi { get; set; }
|
||||
public double BeratSampah { get; set; }
|
||||
public decimal B1 { get; set; }
|
||||
public decimal B2 { get; set; }
|
||||
public decimal B3 { get; set; }
|
||||
public decimal B4 { get; set; }
|
||||
public decimal B5 { get; set; }
|
||||
public decimal B6 { get; set; }
|
||||
public decimal B7 { get; set; }
|
||||
public decimal B8 { get; set; }
|
||||
public decimal B9 { get; set; }
|
||||
public decimal B10 { get; set; }
|
||||
public decimal B11 { get; set; }
|
||||
public decimal B12 { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,249 +5,200 @@
|
|||
}
|
||||
|
||||
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:gap-0 items-center">
|
||||
<div class="prose">
|
||||
<div class="prose md:w-1/2 w-full">
|
||||
<span class="text-xl font-semibold text-black">
|
||||
Reduksi Sampah - @jenis
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-2 items-center">
|
||||
<select class="select rounded-full">
|
||||
<option disabled selected>Pilih Tahun</option>
|
||||
<option>2025</option>
|
||||
<option>2024</option>
|
||||
<option>2023</option>
|
||||
<option>2022</option>
|
||||
<option>2021</option>
|
||||
<option>2020</option>
|
||||
<div class="flex flex-wrap items-center gap-2 md:w-1/2 w-full justify-end">
|
||||
<select id="filter_tahun" class="select md:w-44 w-full rounded-full select-sm">
|
||||
<option value="">Semua Tahun</option>
|
||||
<option value="2025">2025</option>
|
||||
<option value="2024">2024</option>
|
||||
<option value="2023">2023</option>
|
||||
</select>
|
||||
<button type="button" class="btn btn-sm bg-bank-sampah-primary-500 rounded-full text-white"
|
||||
onclick="modal_tambah.showModal()"><i class="ph ph-plus"></i>Tambah</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal History -->
|
||||
<dialog id="modal_history" class="modal">
|
||||
<div class="modal-box max-w-md">
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
||||
</form>
|
||||
<h3 class="text-lg font-bold">History Data</h3>
|
||||
<p class="py-4 text-base font-['Plus Jakarta Sans']">Terdapat 30 History perubahan data</p>
|
||||
<div class="px-3 pt-4 pb-8 bg-gray-50">
|
||||
<div class="flex flex-col gap-4 pl-4 border-l-2 border-gray-300">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-primary-500 text-base">Current Version</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">12:26 pm</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">24 Nov 2025, 12:26 pm</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">23 Nov 2025, 12:26 pm</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">22 Nov 2025, 12:26 pm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
<!-- End Modal History -->
|
||||
|
||||
<!-- Modal Validasi Data -->
|
||||
<dialog id="modal_validasi" class="modal modal-bottom sm:modal-middle">
|
||||
<div
|
||||
class="modal-box w-full max-w-[591px] p-6 bg-white rounded-2xl inline-flex flex-col justify-center items-end gap-6">
|
||||
<div class="self-stretch inline-flex justify-between items-center">
|
||||
<div class="flex-1 justify-start text-gray-900 text-xl font-semibold font-['Plus Jakarta Sans'] leading-8">
|
||||
Validasi Data</div>
|
||||
<button type="button" class="w-5 h-5 relative" onclick="closeValidasiModal()">
|
||||
<i class="ph ph-x text-gray-500 text-xl"></i>
|
||||
<button class="btn btn-sm rounded-full bg-bank-sampah-primary-500 text-white hover:bg-bank-sampah-primary-600"
|
||||
onclick="modal_tambah.showModal()">
|
||||
<i class="ph ph-plus"></i>
|
||||
Tambah Lokasi
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="self-stretch flex flex-col justify-center items-center">
|
||||
<div class="self-stretch px-3 pt-3 pb-8 bg-gray-50 rounded-lg inline-flex justify-start items-start gap-4">
|
||||
<div class="flex-1 inline-flex flex-col justify-start items-start gap-1">
|
||||
<div
|
||||
class="self-stretch justify-start text-gray-500 text-xs font-normal font-['Plus Jakarta Sans'] leading-4">
|
||||
Periode</div>
|
||||
<div id="val_periode"
|
||||
class="self-stretch justify-start text-slate-600 text-base font-normal font-['Plus Jakarta Sans'] leading-6">
|
||||
29 Jul 2024</div>
|
||||
</div>
|
||||
<div class="flex-1 inline-flex flex-col justify-start items-start gap-1">
|
||||
<div
|
||||
class="self-stretch justify-start text-gray-500 text-xs font-normal font-['Plus Jakarta Sans'] leading-4">
|
||||
Nama Lokasi</div>
|
||||
<div id="val_nama_lokasi"
|
||||
class="self-stretch justify-start text-slate-600 text-base font-normal font-['Plus Jakarta Sans'] leading-6">
|
||||
Jakarta Selatan</div>
|
||||
</div>
|
||||
<div class="flex-1 inline-flex flex-col justify-start items-start gap-1">
|
||||
<div
|
||||
class="self-stretch justify-start text-gray-500 text-xs font-normal font-['Plus Jakarta Sans'] leading-4">
|
||||
Jenis Lokasi</div>
|
||||
<div id="val_jenis_lokasi"
|
||||
class="self-stretch justify-start text-slate-600 text-base font-normal font-['Plus Jakarta Sans'] leading-6">
|
||||
Maggot</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="self-stretch justify-start text-slate-800 text-base font-semibold font-['Plus Jakarta Sans'] leading-6">
|
||||
Anda yakin ingin melakukan validasi data ?</div>
|
||||
|
||||
<div class="self-stretch inline-flex justify-end items-center gap-3">
|
||||
<button type="button" class="btn btn-outline btn-sm rounded-full flex justify-center items-center gap-2"
|
||||
onclick="confirmTolakValidasi()">
|
||||
<div class="justify-start text-slate-800 text-sm font-semibold font-['Plus Jakarta Sans'] leading-5">
|
||||
Tolak Validasi</div>
|
||||
<button class="btn btn-sm rounded-full btn-neutral" onclick="modal_validasi.showModal()">
|
||||
<i class="ph ph-check-circle"></i>
|
||||
Validasi Data
|
||||
</button>
|
||||
<button type="button" class="btn btn-success btn-sm rounded-full flex justify-center items-center gap-2"
|
||||
onclick="confirmValidasi()">
|
||||
<div class="justify-start text-white text-sm font-semibold font-['Plus Jakarta Sans'] leading-5">Ya
|
||||
</div>
|
||||
<button class="btn btn-sm rounded-full btn-info" onclick="modal_history.showModal()">
|
||||
<i class="ph ph-clock-counter-clockwise"></i>
|
||||
History
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
<!-- /modal validasi -->
|
||||
|
||||
<!-- Modal Tambah/Edit Data -->
|
||||
<dialog id="modal_tambah" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-2xl p-6 bg-white rounded-2xl">
|
||||
<h3 id="modal_title" class="text-gray-900 text-xl font-semibold font-['Plus Jakarta Sans'] leading-8 mb-8">
|
||||
Tambah Reduksi Sampah</h3>
|
||||
<form id="formTambah" onsubmit="submitForm(event)">
|
||||
<input type="hidden" id="edit_mode" value="false">
|
||||
<input type="hidden" id="reduksi_sampah_id" value="">
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Jenis Lokasi
|
||||
<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<select id="jenis_lokasi" class="select w-full" required>
|
||||
<option value="Komposting">Komposting</option>
|
||||
<option value="Maggot">Maggot</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div id="formDetail" class="flex flex-col gap-6">
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Lokasi<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<select id="lokasi" class="select w-full" required>
|
||||
<option value="" disabled selected>Pilih salah satu</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Alamat
|
||||
</legend>
|
||||
<textarea id="alamat" rows="4" readonly class="textarea w-full"></textarea>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Bukti Kegiatan
|
||||
<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<input type="file" class="file-input file w-full" />
|
||||
<label class="label">Ukuran Maksimal 5MB</label>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Keterangan Kegiatan<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<textarea id="keterangan_kegiatan" rows="4" required placeholder="Keterangan Kegiatan"
|
||||
class="textarea w-full"></textarea>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Tanggal Pelaksanaan Kegiatan
|
||||
<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<input type="date" id="tgl_pelaksanaan_kegiatan" class="input w-full" required />
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Pelaksana Kegiatan<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<input type="text" id="preview" class="input w-full" placeholder="Pelaksana Kegiatan"
|
||||
required />
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-3 justify-end">
|
||||
<button type="button" class="btn btn-outline rounded-full w-full sm:w-auto" onclick="closeModal()">
|
||||
Batal
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="btn bg-bank-sampah-primary-500 rounded-full text-white w-full sm:w-auto">
|
||||
Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
<!-- /modal tambah/edit -->
|
||||
|
||||
<div class="h-6"></div>
|
||||
|
||||
<!-- Modal Tambah -->
|
||||
<dialog id="modal_tambah" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-3xl p-6 bg-white rounded-2xl">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Tambah Lokasi Komposting</h3>
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
||||
</form>
|
||||
</div>
|
||||
<form class="space-y-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Nama Lokasi</legend>
|
||||
<input type="text" class="input w-full" placeholder="Nama Lokasi" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Periode</legend>
|
||||
<input type="month" class="input w-full" />
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Kecamatan</legend>
|
||||
<input type="text" class="input w-full" placeholder="Kecamatan" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Kelurahan</legend>
|
||||
<input type="text" class="input w-full" placeholder="Kelurahan" />
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">RT</legend>
|
||||
<input type="text" class="input w-full" placeholder="RT" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">RW</legend>
|
||||
<input type="text" class="input w-full" placeholder="RW" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Status</legend>
|
||||
<select class="select w-full">
|
||||
<option>Aktif</option>
|
||||
<option>Tidak Aktif</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
</div>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Bukti</legend>
|
||||
<input type="file" class="file-input w-full" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Detail Alamat</legend>
|
||||
<textarea class="textarea w-full" rows="3"></textarea>
|
||||
</fieldset>
|
||||
<div class="flex justify-end gap-2 pt-4">
|
||||
<button type="button" class="btn btn-ghost rounded-full" onclick="modal_tambah.close()">Batal</button>
|
||||
<button type="submit" class="btn bg-bank-sampah-primary-500 text-white rounded-full">Simpan</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<!-- Modal Validasi -->
|
||||
<dialog id="modal_validasi" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-xl p-6 bg-white rounded-2xl">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Validasi Data Komposting</h3>
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div class="bg-gray-50 rounded-xl p-4">
|
||||
<div class="text-sm text-gray-500">Periode</div>
|
||||
<div class="text-base font-semibold text-gray-900">Jan 2025</div>
|
||||
<div class="mt-2 text-sm text-gray-500">Nama Lokasi</div>
|
||||
<div class="text-base font-semibold text-gray-900">Jakarta Pusat</div>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row gap-3">
|
||||
<button class="btn btn-outline btn-error rounded-full w-full sm:w-1/2" type="button">
|
||||
Tolak
|
||||
</button>
|
||||
<button class="btn btn-success text-white rounded-full w-full sm:w-1/2" type="button">
|
||||
Setujui
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<!-- Modal History -->
|
||||
<dialog id="modal_history" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-xl p-6 bg-white rounded-2xl">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">History Perubahan Data</h3>
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="max-h-80 overflow-y-auto">
|
||||
<ul class="timeline timeline-vertical">
|
||||
<li>
|
||||
<div class="timeline-start">Hari ini</div>
|
||||
<div class="timeline-middle">
|
||||
<i class="ph ph-check-circle text-green-600"></i>
|
||||
</div>
|
||||
<div class="timeline-end timeline-box">
|
||||
Validasi data oleh Admin Subandri
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="timeline-start">3 hari lalu</div>
|
||||
<div class="timeline-middle">
|
||||
<i class="ph ph-pen text-amber-500"></i>
|
||||
</div>
|
||||
<div class="timeline-end timeline-box">
|
||||
Pembaruan data B3 dan B4
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="timeline-start">1 minggu lalu</div>
|
||||
<div class="timeline-middle">
|
||||
<i class="ph ph-plus-circle text-blue-500"></i>
|
||||
</div>
|
||||
<div class="timeline-end timeline-box">
|
||||
Penambahan lokasi baru Jakarta Utara
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<div class="card bg-white shadow-sm">
|
||||
<div class="card-body p-2">
|
||||
<div class="w-full overflow-x-auto">
|
||||
<table class="table-zebra table w-full" id="example">
|
||||
<table class="table w-full text-center" id="example">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Periode</th>
|
||||
<th>Nama Lokasi</th>
|
||||
<th>Alamat</th>
|
||||
<th>Jenis Lokasi</th>
|
||||
<th>Berat Reduksi (Kg)</th>
|
||||
<th>Berat Sampah (Kg)</th>
|
||||
<th>Bukti Kegiatan</th>
|
||||
<th>Aksi</th>
|
||||
<th rowspan="2">No</th>
|
||||
<th colspan="5">Lokasi Rumah Komposting</th>
|
||||
<th rowspan="2">Status</th>
|
||||
<th colspan="12">Jumlah Sampah yang di Reduksi (Kg/Bulan)</th>
|
||||
<th rowspan="2">Aksi</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kecamatan</th>
|
||||
<th>Kelurahan</th>
|
||||
<th>RT</th>
|
||||
<th>RW</th>
|
||||
<th>Detail Alamat</th>
|
||||
<th>B1</th>
|
||||
<th>B2</th>
|
||||
<th>B3</th>
|
||||
<th>B4</th>
|
||||
<th>B5</th>
|
||||
<th>B6</th>
|
||||
<th>B7</th>
|
||||
<th>B8</th>
|
||||
<th>B9</th>
|
||||
<th>B10</th>
|
||||
<th>B11</th>
|
||||
<th>B12</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -257,166 +208,232 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
const jenisReduksi = '@jenis';
|
||||
const tableAjaxUrl = '@tableUrl';
|
||||
var table;
|
||||
var allLokasi = [];
|
||||
const updateUrl = '@Url.Content("~/ReduksiSampah/Komposting/Update")';
|
||||
const decimalFields = ['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10', 'b11', 'b12'];
|
||||
let table;
|
||||
|
||||
$(document).ready(function () {
|
||||
$.ajax({
|
||||
url: '/ReduksiSampah/Lokasi/Table',
|
||||
method: 'GET',
|
||||
success: function (response) {
|
||||
allLokasi = (response.data || []).map(item => ({
|
||||
jenis_lokasi: item.jenis_lokasi,
|
||||
nama_lokasi: item.nama_lokasi,
|
||||
kecamatan: item.kecamatan,
|
||||
kelurahan: item.kelurahan,
|
||||
detail_alamat: item.detail_alamat,
|
||||
rt: item.rt,
|
||||
rw: item.rw
|
||||
}));
|
||||
|
||||
$('#jenis_lokasi').val(jenisReduksi).trigger('change');
|
||||
$('#jenis_lokasi').prop('disabled', true);
|
||||
const columns = [
|
||||
{ data: null, render: function (data, type, row, meta) { return meta.row + 1; }, orderable: false, searchable: false },
|
||||
{ data: 'kecamatan', defaultContent: '-' },
|
||||
{ data: 'kelurahan', defaultContent: '-' },
|
||||
{ data: 'rt', defaultContent: '-' },
|
||||
{ data: 'rw', defaultContent: '-' },
|
||||
{ data: 'detail_alamat', defaultContent: '-' },
|
||||
{
|
||||
data: 'status',
|
||||
render: function (data, type, row) {
|
||||
return buildStatusSelect(row.id, data);
|
||||
},
|
||||
error: function () {
|
||||
console.error("Gagal mengambil data lokasi dari /ReduksiSampah/Lokasi/Table");
|
||||
orderable: false,
|
||||
searchable: false
|
||||
}
|
||||
];
|
||||
|
||||
decimalFields.forEach(function (field) {
|
||||
columns.push({
|
||||
data: field,
|
||||
defaultContent: null,
|
||||
render: function (data, type, row) {
|
||||
return buildDecimalInput(row.id, field, data);
|
||||
},
|
||||
orderable: false,
|
||||
searchable: false
|
||||
});
|
||||
});
|
||||
|
||||
columns.push({
|
||||
data: null,
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, row) {
|
||||
return `<div class="flex items-center justify-center gap-2">
|
||||
<button type="button"
|
||||
class="btn btn-square btn-sm btn-warning text-white btn-edit-row tooltip tooltip-left tooltip-warning"
|
||||
data-tip="Edit"
|
||||
data-id="${row.id}">
|
||||
<i class="ph ph-note-pencil"></i>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-square btn-sm btn-success text-white btn-save-row tooltip tooltip-left tooltip-success"
|
||||
data-id="${row.id}"
|
||||
data-tip="Simpan"
|
||||
disabled>
|
||||
<i class="ph ph-floppy-disk"></i>
|
||||
</button>
|
||||
</div>`;
|
||||
}
|
||||
});
|
||||
|
||||
table = new DataTable('#example', {
|
||||
ajax: tableAjaxUrl,
|
||||
ajax: {
|
||||
url: tableAjaxUrl,
|
||||
data: function (d) {
|
||||
d.tahun = $('#filter_tahun').val();
|
||||
},
|
||||
dataSrc: 'data',
|
||||
error: function (xhr, status, err) {
|
||||
console.error('Gagal memuat data komposting:', err);
|
||||
}
|
||||
},
|
||||
scrollX: true,
|
||||
scrollCollapse: true,
|
||||
autoWidth: false,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
paging: false,
|
||||
info: false,
|
||||
columns: columns,
|
||||
fixedColumns: {
|
||||
left: 6
|
||||
},
|
||||
createdRow: function (row, data) {
|
||||
$(row).attr('data-row-id', data.id);
|
||||
},
|
||||
initComplete: function () {
|
||||
$('div.dt-scroll-body thead').css('visibility', 'collapse');
|
||||
},
|
||||
columns: [
|
||||
{ data: null, render: (d, t, r, m) => m.row + 1, orderable: false, searchable: false },
|
||||
{ data: 'periode_bulan' },
|
||||
{ data: 'nama_lokasi' },
|
||||
{ data: 'alamat' },
|
||||
{ data: 'jenis_lokasi' },
|
||||
{ data: 'berat_reduksi' },
|
||||
{ data: 'berat_sampah' },
|
||||
{ data: 'gambar', orderable: false, searchable: false },
|
||||
{ data: 'aksi', orderable: false, searchable: false },
|
||||
]
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-history', function (e) {
|
||||
e.preventDefault();
|
||||
modal_history.showModal();
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-validation', function (e) {
|
||||
e.preventDefault();
|
||||
const row = table.row($(this).parents('tr')).data();
|
||||
if (row) {
|
||||
$('#val_periode').text(row.periode_bulan);
|
||||
$('#val_nama_lokasi').text(row.nama_lokasi);
|
||||
$('#val_jenis_lokasi').text(row.jenis_lokasi);
|
||||
}
|
||||
modal_validasi.showModal();
|
||||
});
|
||||
|
||||
$('#jenis_lokasi').on('change', function () {
|
||||
const jenisLokasi = $(this).val();
|
||||
|
||||
if (jenisLokasi) {
|
||||
$('#formDetail').removeClass('hidden').hide().fadeIn(300);
|
||||
populateNamaLokasiDropdown(jenisLokasi);
|
||||
} else {
|
||||
$('#formDetail').fadeOut(300);
|
||||
}
|
||||
});
|
||||
|
||||
$('#lokasi').on('change', function () {
|
||||
const nama = $(this).val();
|
||||
$('#example').on('click', '.btn-edit-row', function () {
|
||||
const rowId = $(this).data('id');
|
||||
setRowEditingState(rowId, true);
|
||||
});
|
||||
|
||||
if (!nama) {
|
||||
$('#alamat').val('');
|
||||
$('#example').on('click', '.btn-save-row', function () {
|
||||
const rowId = $(this).data('id');
|
||||
saveRowChanges(rowId);
|
||||
});
|
||||
|
||||
$('#filter_tahun').on('change', function () {
|
||||
table.ajax.reload();
|
||||
});
|
||||
});
|
||||
|
||||
function buildStatusSelect(rowId, currentValue) {
|
||||
const options = ['Aktif', 'Tidak Aktif']
|
||||
.map(function (option) {
|
||||
const selected = option === currentValue ? 'selected' : '';
|
||||
return `<option value="${option}" ${selected}>${option}</option>`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
return `<div class="flex justify-center">
|
||||
<select class="select select-warning select-sm w-32 text-black"
|
||||
data-field="status"
|
||||
data-id="${rowId}"
|
||||
name="status-${rowId}"
|
||||
disabled>
|
||||
${options}
|
||||
</select>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function buildDecimalInput(rowId, fieldName, value) {
|
||||
const displayValue = (typeof value === 'number' || typeof value === 'string') ? value : '';
|
||||
|
||||
return `<div class="flex justify-center">
|
||||
<input type="number"
|
||||
step="0.01"
|
||||
min="0"
|
||||
data-id="${rowId}"
|
||||
data-field="${fieldName}"
|
||||
name="${fieldName}-${rowId}"
|
||||
value="${displayValue}"
|
||||
class="input input-warning input-sm w-24 text-right text-black"
|
||||
disabled />
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function getRowById(rowId) {
|
||||
return $(`#example tbody tr[data-row-id="${rowId}"]`);
|
||||
}
|
||||
|
||||
function setRowEditingState(rowId, enableEditing) {
|
||||
const $row = getRowById(rowId);
|
||||
if ($row.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lokasi = allLokasi.find(item => item.nama_lokasi === nama);
|
||||
$row.toggleClass('editing', enableEditing);
|
||||
$row.find('select[data-field], input[data-field]').prop('disabled', !enableEditing);
|
||||
$row.find('.btn-edit-row').prop('disabled', enableEditing);
|
||||
$row.find('.btn-save-row').prop('disabled', !enableEditing);
|
||||
|
||||
if (lokasi) {
|
||||
const formattedAlamat = `${lokasi.kecamatan}, ${lokasi.kelurahan}, RT ${lokasi.rt}, RW ${lokasi.rw}, ${lokasi.detail_alamat}`;
|
||||
$('#alamat').val(formattedAlamat);
|
||||
if (enableEditing) {
|
||||
const $firstInput = $row.find('input[data-field]').first();
|
||||
if ($firstInput.length) {
|
||||
$firstInput.trigger('focus');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function collectRowPayload(rowId) {
|
||||
const id = parseInt(rowId, 10);
|
||||
if (Number.isNaN(id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const $row = getRowById(rowId);
|
||||
if ($row.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
Id: id,
|
||||
Status: $row.find('select[data-field="status"]').val()
|
||||
};
|
||||
|
||||
decimalFields.forEach(function (field) {
|
||||
const $input = $row.find(`input[data-field="${field}"]`);
|
||||
const rawValue = ($input.val() || '').trim();
|
||||
payload[field.toUpperCase()] = rawValue === '' ? null : parseFloat(rawValue);
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-edit', function (e) {
|
||||
e.preventDefault();
|
||||
return payload;
|
||||
}
|
||||
|
||||
var row = table.row($(this).parents('tr')).data();
|
||||
|
||||
$('#edit_mode').val('true');
|
||||
$('#reduksi_sampah_id').val(row.id);
|
||||
$('#modal_title').text('Edit Reduksi Sampah');
|
||||
modal_tambah.showModal();
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-delete', function (e) {
|
||||
e.preventDefault();
|
||||
const row = table.row($(this).parents('tr')).data();
|
||||
function saveRowChanges(rowId) {
|
||||
const payload = collectRowPayload(rowId);
|
||||
if (!payload) {
|
||||
Swal.fire({
|
||||
title: 'Hapus data?',
|
||||
text: `Data ${row?.nama_lokasi || ''} akan dihapus secara permanen.`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ya, hapus',
|
||||
cancelButtonText: 'Batal'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
Swal.fire('Terhapus', 'Data berhasil dihapus (simulasi).', 'success');
|
||||
table.ajax.reload();
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: 'Data tidak valid untuk disimpan.'
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function populateNamaLokasiDropdown(jenisLokasi) {
|
||||
let options = '<option value=\"\">Pilih salah satu</option>';
|
||||
|
||||
if (jenisLokasi) {
|
||||
const filtered = allLokasi.filter(item => item.jenis_lokasi === jenisLokasi);
|
||||
|
||||
filtered.forEach(item => {
|
||||
options += `<option value="${item.nama_lokasi}">${item.nama_lokasi}</option>`;
|
||||
$.ajax({
|
||||
url: updateUrl,
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(payload),
|
||||
success: function (response) {
|
||||
const successMessage = (response && response.message) ? response.message : 'Data berhasil disimpan.';
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: successMessage
|
||||
}).then(function () {
|
||||
setRowEditingState(rowId, false);
|
||||
table.ajax.reload(null, false);
|
||||
});
|
||||
},
|
||||
error: function (xhr) {
|
||||
const message = (xhr && xhr.responseJSON && xhr.responseJSON.message)
|
||||
? xhr.responseJSON.message
|
||||
: 'Terjadi kesalahan saat menyimpan data.';
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: message
|
||||
});
|
||||
}
|
||||
|
||||
$('#lokasi').html(options);
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
$('#formTambah')[0].reset();
|
||||
$('#edit_mode').val('false');
|
||||
$('#modal_title').text('Tambah Reduksi Sampah');
|
||||
$('#jenis_lokasi').val(jenisReduksi);
|
||||
modal_tambah.close();
|
||||
}
|
||||
|
||||
function closeValidasiModal() {
|
||||
modal_validasi.close();
|
||||
}
|
||||
|
||||
function confirmValidasi() {
|
||||
closeValidasiModal();
|
||||
table.ajax.reload();
|
||||
}
|
||||
|
||||
function confirmTolakValidasi() {
|
||||
closeValidasiModal();
|
||||
table.ajax.reload();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
||||
|
|
@ -5,249 +5,200 @@ ViewData["Title"] = $"Reduksi Sampah - {jenis}";
|
|||
}
|
||||
|
||||
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:gap-0 items-center">
|
||||
<div class="prose">
|
||||
<div class="prose md:w-1/2 w-full">
|
||||
<span class="text-xl font-semibold text-black">
|
||||
Reduksi Sampah - @jenis
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-2 items-center">
|
||||
<select class="select rounded-full">
|
||||
<option disabled selected>Pilih Tahun</option>
|
||||
<option>2025</option>
|
||||
<option>2024</option>
|
||||
<option>2023</option>
|
||||
<option>2022</option>
|
||||
<option>2021</option>
|
||||
<option>2020</option>
|
||||
<div class="flex flex-wrap items-center gap-2 md:w-1/2 w-full justify-end">
|
||||
<select id="filter_tahun" class="select md:w-44 w-full rounded-full select-sm">
|
||||
<option value="">Semua Tahun</option>
|
||||
<option value="2025">2025</option>
|
||||
<option value="2024">2024</option>
|
||||
<option value="2023">2023</option>
|
||||
</select>
|
||||
<button type="button" class="btn btn-sm bg-bank-sampah-primary-500 rounded-full text-white"
|
||||
onclick="modal_tambah.showModal()"><i class="ph ph-plus"></i>Tambah</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal History -->
|
||||
<dialog id="modal_history" class="modal">
|
||||
<div class="modal-box max-w-md">
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
||||
</form>
|
||||
<h3 class="text-lg font-bold">History Data</h3>
|
||||
<p class="py-4 text-base font-['Plus Jakarta Sans']">Terdapat 30 History perubahan data</p>
|
||||
<div class="px-3 pt-4 pb-8 bg-gray-50">
|
||||
<div class="flex flex-col gap-4 pl-4 border-l-2 border-gray-300">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-primary-500 text-base">Current Version</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">12:26 pm</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">24 Nov 2025, 12:26 pm</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">23 Nov 2025, 12:26 pm</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-gray-500 text-xs leading-4">Admin Subandri</div>
|
||||
<div class="text-gray-600 text-base">22 Nov 2025, 12:26 pm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
<!-- End Modal History -->
|
||||
|
||||
<!-- Modal Validasi Data -->
|
||||
<dialog id="modal_validasi" class="modal modal-bottom sm:modal-middle">
|
||||
<div
|
||||
class="modal-box w-full max-w-[591px] p-6 bg-white rounded-2xl inline-flex flex-col justify-center items-end gap-6">
|
||||
<div class="self-stretch inline-flex justify-between items-center">
|
||||
<div class="flex-1 justify-start text-gray-900 text-xl font-semibold font-['Plus Jakarta Sans'] leading-8">
|
||||
Validasi Data</div>
|
||||
<button type="button" class="w-5 h-5 relative" onclick="closeValidasiModal()">
|
||||
<i class="ph ph-x text-gray-500 text-xl"></i>
|
||||
<button class="btn btn-sm rounded-full bg-bank-sampah-primary-500 text-white hover:bg-bank-sampah-primary-600"
|
||||
onclick="modal_tambah.showModal()">
|
||||
<i class="ph ph-plus"></i>
|
||||
Tambah Lokasi
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="self-stretch flex flex-col justify-center items-center">
|
||||
<div class="self-stretch px-3 pt-3 pb-8 bg-gray-50 rounded-lg inline-flex justify-start items-start gap-4">
|
||||
<div class="flex-1 inline-flex flex-col justify-start items-start gap-1">
|
||||
<div
|
||||
class="self-stretch justify-start text-gray-500 text-xs font-normal font-['Plus Jakarta Sans'] leading-4">
|
||||
Periode</div>
|
||||
<div id="val_periode"
|
||||
class="self-stretch justify-start text-slate-600 text-base font-normal font-['Plus Jakarta Sans'] leading-6">
|
||||
29 Jul 2024</div>
|
||||
</div>
|
||||
<div class="flex-1 inline-flex flex-col justify-start items-start gap-1">
|
||||
<div
|
||||
class="self-stretch justify-start text-gray-500 text-xs font-normal font-['Plus Jakarta Sans'] leading-4">
|
||||
Nama Lokasi</div>
|
||||
<div id="val_nama_lokasi"
|
||||
class="self-stretch justify-start text-slate-600 text-base font-normal font-['Plus Jakarta Sans'] leading-6">
|
||||
Jakarta Selatan</div>
|
||||
</div>
|
||||
<div class="flex-1 inline-flex flex-col justify-start items-start gap-1">
|
||||
<div
|
||||
class="self-stretch justify-start text-gray-500 text-xs font-normal font-['Plus Jakarta Sans'] leading-4">
|
||||
Jenis Lokasi</div>
|
||||
<div id="val_jenis_lokasi"
|
||||
class="self-stretch justify-start text-slate-600 text-base font-normal font-['Plus Jakarta Sans'] leading-6">
|
||||
Maggot</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="self-stretch justify-start text-slate-800 text-base font-semibold font-['Plus Jakarta Sans'] leading-6">
|
||||
Anda yakin ingin melakukan validasi data ?</div>
|
||||
|
||||
<div class="self-stretch inline-flex justify-end items-center gap-3">
|
||||
<button type="button" class="btn btn-outline btn-sm rounded-full flex justify-center items-center gap-2"
|
||||
onclick="confirmTolakValidasi()">
|
||||
<div class="justify-start text-slate-800 text-sm font-semibold font-['Plus Jakarta Sans'] leading-5">
|
||||
Tolak Validasi</div>
|
||||
<button class="btn btn-sm rounded-full btn-neutral" onclick="modal_validasi.showModal()">
|
||||
<i class="ph ph-check-circle"></i>
|
||||
Validasi Data
|
||||
</button>
|
||||
<button type="button" class="btn btn-success btn-sm rounded-full flex justify-center items-center gap-2"
|
||||
onclick="confirmValidasi()">
|
||||
<div class="justify-start text-white text-sm font-semibold font-['Plus Jakarta Sans'] leading-5">Ya
|
||||
</div>
|
||||
<button class="btn btn-sm rounded-full btn-info" onclick="modal_history.showModal()">
|
||||
<i class="ph ph-clock-counter-clockwise"></i>
|
||||
History
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
<!-- /modal validasi -->
|
||||
|
||||
<!-- Modal Tambah/Edit Data -->
|
||||
<dialog id="modal_tambah" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-2xl p-6 bg-white rounded-2xl">
|
||||
<h3 id="modal_title" class="text-gray-900 text-xl font-semibold font-['Plus Jakarta Sans'] leading-8 mb-8">
|
||||
Tambah Reduksi Sampah</h3>
|
||||
<form id="formTambah" onsubmit="submitForm(event)">
|
||||
<input type="hidden" id="edit_mode" value="false">
|
||||
<input type="hidden" id="reduksi_sampah_id" value="">
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Jenis Lokasi
|
||||
<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<select id="jenis_lokasi" class="select w-full" required>
|
||||
<option value="Komposting">Komposting</option>
|
||||
<option value="Maggot">Maggot</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div id="formDetail" class="flex flex-col gap-6">
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Lokasi<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<select id="lokasi" class="select w-full" required>
|
||||
<option value="" disabled selected>Pilih salah satu</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Alamat
|
||||
</legend>
|
||||
<textarea id="alamat" rows="4" readonly class="textarea w-full"></textarea>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Bukti Kegiatan
|
||||
<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<input type="file" class="file-input file w-full" />
|
||||
<label class="label">Ukuran Maksimal 5MB</label>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Keterangan Kegiatan<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<textarea id="keterangan_kegiatan" rows="4" required placeholder="Keterangan Kegiatan"
|
||||
class="textarea w-full"></textarea>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Tanggal Pelaksanaan Kegiatan
|
||||
<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<input type="date" id="tgl_pelaksanaan_kegiatan" class="input w-full" required />
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">
|
||||
Pelaksana Kegiatan<span class="text-red-500">*</span>
|
||||
</legend>
|
||||
<input type="text" id="preview" class="input w-full" placeholder="Pelaksana Kegiatan"
|
||||
required />
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-3 justify-end">
|
||||
<button type="button" class="btn btn-outline rounded-full w-full sm:w-auto" onclick="closeModal()">
|
||||
Batal
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="btn bg-bank-sampah-primary-500 rounded-full text-white w-full sm:w-auto">
|
||||
Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
<!-- /modal tambah/edit -->
|
||||
|
||||
<div class="h-6"></div>
|
||||
|
||||
<!-- Modal Tambah -->
|
||||
<dialog id="modal_tambah" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-3xl p-6 bg-white rounded-2xl">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Tambah Lokasi Maggot</h3>
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
||||
</form>
|
||||
</div>
|
||||
<form class="space-y-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Nama Lokasi</legend>
|
||||
<input type="text" class="input w-full" placeholder="Nama Lokasi" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Periode</legend>
|
||||
<input type="month" class="input w-full" />
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Kecamatan</legend>
|
||||
<input type="text" class="input w-full" placeholder="Kecamatan" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Kelurahan</legend>
|
||||
<input type="text" class="input w-full" placeholder="Kelurahan" />
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">RT</legend>
|
||||
<input type="text" class="input w-full" placeholder="RT" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">RW</legend>
|
||||
<input type="text" class="input w-full" placeholder="RW" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Status</legend>
|
||||
<select class="select w-full">
|
||||
<option>Aktif</option>
|
||||
<option>Tidak Aktif</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
</div>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Bukti</legend>
|
||||
<input type="file" class="file-input w-full" />
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Detail Alamat</legend>
|
||||
<textarea class="textarea w-full" rows="3"></textarea>
|
||||
</fieldset>
|
||||
<div class="flex justify-end gap-2 pt-4">
|
||||
<button type="button" class="btn btn-ghost rounded-full" onclick="modal_tambah.close()">Batal</button>
|
||||
<button type="submit" class="btn bg-bank-sampah-primary-500 text-white rounded-full">Simpan</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<!-- Modal Validasi -->
|
||||
<dialog id="modal_validasi" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-xl p-6 bg-white rounded-2xl">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Validasi Data Maggot</h3>
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div class="bg-gray-50 rounded-xl p-4">
|
||||
<div class="text-sm text-gray-500">Periode</div>
|
||||
<div class="text-base font-semibold text-gray-900">Jan 2025</div>
|
||||
<div class="mt-2 text-sm text-gray-500">Nama Lokasi</div>
|
||||
<div class="text-base font-semibold text-gray-900">Jakarta Pusat</div>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row gap-3">
|
||||
<button class="btn btn-outline btn-error rounded-full w-full sm:w-1/2" type="button">
|
||||
Tolak
|
||||
</button>
|
||||
<button class="btn btn-success text-white rounded-full w-full sm:w-1/2" type="button">
|
||||
Setujui
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<!-- Modal History -->
|
||||
<dialog id="modal_history" class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box w-full max-w-xl p-6 bg-white rounded-2xl">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">History Perubahan Data</h3>
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="max-h-80 overflow-y-auto">
|
||||
<ul class="timeline timeline-vertical">
|
||||
<li>
|
||||
<div class="timeline-start">Hari ini</div>
|
||||
<div class="timeline-middle">
|
||||
<i class="ph ph-check-circle text-green-600"></i>
|
||||
</div>
|
||||
<div class="timeline-end timeline-box">
|
||||
Validasi data oleh Admin Subandri
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="timeline-start">3 hari lalu</div>
|
||||
<div class="timeline-middle">
|
||||
<i class="ph ph-pen text-amber-500"></i>
|
||||
</div>
|
||||
<div class="timeline-end timeline-box">
|
||||
Pembaruan data B3 dan B4
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="timeline-start">1 minggu lalu</div>
|
||||
<div class="timeline-middle">
|
||||
<i class="ph ph-plus-circle text-blue-500"></i>
|
||||
</div>
|
||||
<div class="timeline-end timeline-box">
|
||||
Penambahan lokasi baru Jakarta Utara
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<div class="card bg-white shadow-sm">
|
||||
<div class="card-body p-2">
|
||||
<div class="w-full overflow-x-auto">
|
||||
<table class="table-zebra table w-full" id="example">
|
||||
<thead>
|
||||
<table class="table w-full" id="example">
|
||||
<thead class="text-black">
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Periode</th>
|
||||
<th>Nama Lokasi</th>
|
||||
<th>Alamat</th>
|
||||
<th>Jenis Lokasi</th>
|
||||
<th>Berat Reduksi (Kg)</th>
|
||||
<th>Berat Sampah (Kg)</th>
|
||||
<th>Bukti Kegiatan</th>
|
||||
<th>Aksi</th>
|
||||
<th rowspan="2">No</th>
|
||||
<th colspan="5">Lokasi Rumah Komposting</th>
|
||||
<th rowspan="2">Status</th>
|
||||
<th colspan="12">Jumlah Sampah yang di Reduksi (Kg/Bulan)</th>
|
||||
<th rowspan="2">Aksi</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kecamatan</th>
|
||||
<th>Kelurahan</th>
|
||||
<th>RT</th>
|
||||
<th>RW</th>
|
||||
<th>Detail Alamat</th>
|
||||
<th>B1</th>
|
||||
<th>B2</th>
|
||||
<th>B3</th>
|
||||
<th>B4</th>
|
||||
<th>B5</th>
|
||||
<th>B6</th>
|
||||
<th>B7</th>
|
||||
<th>B8</th>
|
||||
<th>B9</th>
|
||||
<th>B10</th>
|
||||
<th>B11</th>
|
||||
<th>B12</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -257,166 +208,229 @@ ViewData["Title"] = $"Reduksi Sampah - {jenis}";
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
const jenisReduksi = '@jenis';
|
||||
const tableAjaxUrl = '@tableUrl';
|
||||
var table;
|
||||
var allLokasi = [];
|
||||
const updateUrl = '@Url.Content("~/ReduksiSampah/Maggot/Update")';
|
||||
const decimalFields = ['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10', 'b11', 'b12'];
|
||||
let table;
|
||||
|
||||
$(document).ready(function () {
|
||||
$.ajax({
|
||||
url: '/ReduksiSampah/Lokasi/Table',
|
||||
method: 'GET',
|
||||
success: function (response) {
|
||||
allLokasi = (response.data || []).map(item => ({
|
||||
jenis_lokasi: item.jenis_lokasi,
|
||||
nama_lokasi: item.nama_lokasi,
|
||||
kecamatan: item.kecamatan,
|
||||
kelurahan: item.kelurahan,
|
||||
detail_alamat: item.detail_alamat,
|
||||
rt: item.rt,
|
||||
rw: item.rw
|
||||
}));
|
||||
|
||||
$('#jenis_lokasi').val(jenisReduksi).trigger('change');
|
||||
$('#jenis_lokasi').prop('disabled', true);
|
||||
const columns = [
|
||||
{ data: null, render: function (data, type, row, meta) { return meta.row + 1; }, orderable: false, searchable: false },
|
||||
{ data: 'kecamatan', defaultContent: '-' },
|
||||
{ data: 'kelurahan', defaultContent: '-' },
|
||||
{ data: 'rt', defaultContent: '-' },
|
||||
{ data: 'rw', defaultContent: '-' },
|
||||
{ data: 'detail_alamat', defaultContent: '-' },
|
||||
{
|
||||
data: 'status',
|
||||
render: function (data, type, row) {
|
||||
return buildStatusSelect(row.id, data);
|
||||
},
|
||||
error: function () {
|
||||
console.error("Gagal mengambil data lokasi dari /ReduksiSampah/Lokasi/Table");
|
||||
orderable: false,
|
||||
searchable: false
|
||||
}
|
||||
];
|
||||
|
||||
decimalFields.forEach(function (field) {
|
||||
columns.push({
|
||||
data: field,
|
||||
defaultContent: null,
|
||||
render: function (data, type, row) {
|
||||
return buildDecimalInput(row.id, field, data);
|
||||
},
|
||||
orderable: false,
|
||||
searchable: false
|
||||
});
|
||||
});
|
||||
|
||||
columns.push({
|
||||
data: null,
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, row) {
|
||||
return `<div class="flex items-center justify-center gap-2">
|
||||
<button type="button"
|
||||
class="btn btn-square btn-sm btn-warning text-white btn-edit-row tooltip tooltip-left tooltip-warning"
|
||||
data-tip="Edit"
|
||||
data-id="${row.id}">
|
||||
<i class="ph ph-note-pencil"></i>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-square btn-sm btn-success text-white btn-save-row tooltip tooltip-left tooltip-success"
|
||||
data-id="${row.id}"
|
||||
data-tip="Simpan"
|
||||
disabled>
|
||||
<i class="ph ph-floppy-disk"></i>
|
||||
</button>
|
||||
</div>`;
|
||||
}
|
||||
});
|
||||
|
||||
table = new DataTable('#example', {
|
||||
ajax: tableAjaxUrl,
|
||||
ajax: {
|
||||
url: tableAjaxUrl,
|
||||
data: function (d) {
|
||||
d.tahun = $('#filter_tahun').val();
|
||||
},
|
||||
dataSrc: 'data',
|
||||
error: function (xhr, status, err) {
|
||||
console.error('Gagal memuat data maggot:', err);
|
||||
}
|
||||
},
|
||||
scrollX: true,
|
||||
scrollCollapse: true,
|
||||
autoWidth: false,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
paging: false,
|
||||
info: false,
|
||||
columns: columns,
|
||||
fixedColumns: {
|
||||
left: 6
|
||||
},
|
||||
createdRow: function (row, data) {
|
||||
$(row).attr('data-row-id', data.id);
|
||||
},
|
||||
initComplete: function () {
|
||||
$('div.dt-scroll-body thead').css('visibility', 'collapse');
|
||||
},
|
||||
columns: [
|
||||
{ data: null, render: (d, t, r, m) => m.row + 1, orderable: false, searchable: false },
|
||||
{ data: 'periode_bulan' },
|
||||
{ data: 'nama_lokasi' },
|
||||
{ data: 'alamat' },
|
||||
{ data: 'jenis_lokasi' },
|
||||
{ data: 'berat_reduksi' },
|
||||
{ data: 'berat_sampah' },
|
||||
{ data: 'gambar', orderable: false, searchable: false },
|
||||
{ data: 'aksi', orderable: false, searchable: false },
|
||||
]
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-history', function (e) {
|
||||
e.preventDefault();
|
||||
modal_history.showModal();
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-validation', function (e) {
|
||||
e.preventDefault();
|
||||
const row = table.row($(this).parents('tr')).data();
|
||||
if (row) {
|
||||
$('#val_periode').text(row.periode_bulan);
|
||||
$('#val_nama_lokasi').text(row.nama_lokasi);
|
||||
$('#val_jenis_lokasi').text(row.jenis_lokasi);
|
||||
}
|
||||
modal_validasi.showModal();
|
||||
});
|
||||
|
||||
$('#jenis_lokasi').on('change', function () {
|
||||
const jenisLokasi = $(this).val();
|
||||
|
||||
if (jenisLokasi) {
|
||||
$('#formDetail').removeClass('hidden').hide().fadeIn(300);
|
||||
populateNamaLokasiDropdown(jenisLokasi);
|
||||
} else {
|
||||
$('#formDetail').fadeOut(300);
|
||||
}
|
||||
});
|
||||
|
||||
$('#lokasi').on('change', function () {
|
||||
const nama = $(this).val();
|
||||
$('#example').on('click', '.btn-edit-row', function () {
|
||||
const rowId = $(this).data('id');
|
||||
setRowEditingState(rowId, true);
|
||||
});
|
||||
|
||||
if (!nama) {
|
||||
$('#alamat').val('');
|
||||
$('#example').on('click', '.btn-save-row', function () {
|
||||
const rowId = $(this).data('id');
|
||||
saveRowChanges(rowId);
|
||||
});
|
||||
|
||||
$('#filter_tahun').on('change', function () {
|
||||
table.ajax.reload();
|
||||
});
|
||||
});
|
||||
|
||||
function buildStatusSelect(rowId, currentValue) {
|
||||
const options = ['Aktif', 'Tidak Aktif']
|
||||
.map(function (option) {
|
||||
const selected = option === currentValue ? 'selected' : '';
|
||||
return `<option value="${option}" ${selected}>${option}</option>`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
return `<div class="flex justify-center"><select class="select select-sm select-warning text-black w-32"
|
||||
data-field="status"
|
||||
data-id="${rowId}"
|
||||
name="status-${rowId}"
|
||||
disabled>
|
||||
${options}
|
||||
</select>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function buildDecimalInput(rowId, fieldName, value) {
|
||||
const displayValue = (typeof value === 'number' || typeof value === 'string') ? value : '';
|
||||
|
||||
return `<div class="flex justify-center">
|
||||
<input type="number"
|
||||
step="0.01"
|
||||
min="0"
|
||||
data-id="${rowId}"
|
||||
data-field="${fieldName}"
|
||||
name="${fieldName}-${rowId}" value="${displayValue}"
|
||||
class="input input-sm input-warning w-24 text-right text-black" disabled />
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function getRowById(rowId) {
|
||||
return $(`#example tbody tr[data-row-id="${rowId}"]`);
|
||||
}
|
||||
|
||||
function setRowEditingState(rowId, enableEditing) {
|
||||
const $row = getRowById(rowId);
|
||||
if ($row.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lokasi = allLokasi.find(item => item.nama_lokasi === nama);
|
||||
$row.toggleClass('editing', enableEditing);
|
||||
$row.find('select[data-field], input[data-field]').prop('disabled', !enableEditing);
|
||||
$row.find('.btn-edit-row').prop('disabled', enableEditing);
|
||||
$row.find('.btn-save-row').prop('disabled', !enableEditing);
|
||||
|
||||
if (lokasi) {
|
||||
const formattedAlamat = `${lokasi.kecamatan}, ${lokasi.kelurahan}, RT ${lokasi.rt}, RW ${lokasi.rw}, ${lokasi.detail_alamat}`;
|
||||
$('#alamat').val(formattedAlamat);
|
||||
if (enableEditing) {
|
||||
const $firstInput = $row.find('input[data-field]').first();
|
||||
if ($firstInput.length) {
|
||||
$firstInput.trigger('focus');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function collectRowPayload(rowId) {
|
||||
const id = parseInt(rowId, 10);
|
||||
if (Number.isNaN(id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const $row = getRowById(rowId);
|
||||
if ($row.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
Id: id,
|
||||
Status: $row.find('select[data-field="status"]').val()
|
||||
};
|
||||
|
||||
decimalFields.forEach(function (field) {
|
||||
const $input = $row.find(`input[data-field="${field}"]`);
|
||||
const rawValue = ($input.val() || '').trim();
|
||||
payload[field.toUpperCase()] = rawValue === '' ? null : parseFloat(rawValue);
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-edit', function (e) {
|
||||
e.preventDefault();
|
||||
return payload;
|
||||
}
|
||||
|
||||
var row = table.row($(this).parents('tr')).data();
|
||||
|
||||
$('#edit_mode').val('true');
|
||||
$('#reduksi_sampah_id').val(row.id);
|
||||
$('#modal_title').text('Edit Reduksi Sampah');
|
||||
modal_tambah.showModal();
|
||||
});
|
||||
|
||||
$('#example').on('click', '.btn-delete', function (e) {
|
||||
e.preventDefault();
|
||||
const row = table.row($(this).parents('tr')).data();
|
||||
function saveRowChanges(rowId) {
|
||||
const payload = collectRowPayload(rowId);
|
||||
if (!payload) {
|
||||
Swal.fire({
|
||||
title: 'Hapus data?',
|
||||
text: `Data ${row?.nama_lokasi || ''} akan dihapus secara permanen.`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ya, hapus',
|
||||
cancelButtonText: 'Batal'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
Swal.fire('Terhapus', 'Data berhasil dihapus (simulasi).', 'success');
|
||||
table.ajax.reload();
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: 'Data tidak valid untuk disimpan.'
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function populateNamaLokasiDropdown(jenisLokasi) {
|
||||
let options = '<option value=\"\">Pilih salah satu</option>';
|
||||
|
||||
if (jenisLokasi) {
|
||||
const filtered = allLokasi.filter(item => item.jenis_lokasi === jenisLokasi);
|
||||
|
||||
filtered.forEach(item => {
|
||||
options += `<option value="${item.nama_lokasi}">${item.nama_lokasi}</option>`;
|
||||
$.ajax({
|
||||
url: updateUrl,
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(payload),
|
||||
success: function (response) {
|
||||
const successMessage = (response && response.message) ? response.message : 'Data berhasil disimpan.';
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: successMessage
|
||||
}).then(function () {
|
||||
setRowEditingState(rowId, false);
|
||||
table.ajax.reload(null, false);
|
||||
});
|
||||
},
|
||||
error: function (xhr) {
|
||||
const message = (xhr && xhr.responseJSON && xhr.responseJSON.message)
|
||||
? xhr.responseJSON.message
|
||||
: 'Terjadi kesalahan saat menyimpan data.';
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: message
|
||||
});
|
||||
}
|
||||
|
||||
$('#lokasi').html(options);
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
$('#formTambah')[0].reset();
|
||||
$('#edit_mode').val('false');
|
||||
$('#modal_title').text('Tambah Reduksi Sampah');
|
||||
$('#jenis_lokasi').val(jenisReduksi);
|
||||
modal_tambah.close();
|
||||
}
|
||||
|
||||
function closeValidasiModal() {
|
||||
modal_validasi.close();
|
||||
}
|
||||
|
||||
function confirmValidasi() {
|
||||
closeValidasiModal();
|
||||
table.ajax.reload();
|
||||
}
|
||||
|
||||
function confirmTolakValidasi() {
|
||||
closeValidasiModal();
|
||||
table.ajax.reload();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/2.3.4/css/dataTables.tailwindcss.css" />
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/fixedcolumns/5.0.1/css/fixedColumns.dataTables.min.css" />
|
||||
@await RenderSectionAsync("Styles", required: false)
|
||||
|
||||
<!-- Select2 -->
|
||||
|
|
@ -69,6 +70,7 @@
|
|||
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script src="https://cdn.datatables.net/2.3.4/js/dataTables.js"></script>
|
||||
<script src="https://cdn.datatables.net/fixedcolumns/5.0.1/js/dataTables.fixedColumns.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<script src="/plugins/datatables/dataTables.tailwindcss.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/2.3.4/css/dataTables.tailwindcss.css" />
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/fixedcolumns/5.0.1/css/fixedColumns.dataTables.min.css" />
|
||||
@await RenderSectionAsync("Styles", required: false)
|
||||
|
||||
<!-- Select2 -->
|
||||
|
|
@ -63,6 +64,7 @@
|
|||
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script src="https://cdn.datatables.net/2.3.4/js/dataTables.js"></script>
|
||||
<script src="https://cdn.datatables.net/fixedcolumns/5.0.1/js/dataTables.fixedColumns.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<script src="/plugins/datatables/dataTables.tailwindcss.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue