move js to external file
parent
fddabb7fd8
commit
187ef5fd23
|
|
@ -40,9 +40,16 @@ namespace WebApplication2.Controllers.WebNew
|
|||
|
||||
var json = System.IO.File.ReadAllText(path);
|
||||
|
||||
var data = JsonNode.Parse(json).AsArray();
|
||||
var data = JsonNode.Parse(json);
|
||||
|
||||
var result = data.FirstOrDefault(x => (int)x["id"] == id);
|
||||
if (data == null)
|
||||
return NotFound();
|
||||
|
||||
var array = data.AsArray();
|
||||
|
||||
var result = array.FirstOrDefault(x =>
|
||||
x?["id"]?.GetValue<int>() == id
|
||||
);
|
||||
|
||||
if (result == null)
|
||||
return NotFound();
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ namespace WebApplication2.Models.ViewModels
|
|||
{
|
||||
public class BeritaViewModel
|
||||
{
|
||||
public string Judul { get; set; }
|
||||
public string Deskripsi { get; set; }
|
||||
public string Gambar { get; set; }
|
||||
public string Judul { get; set; } = "";
|
||||
public string Deskripsi { get; set; } = "";
|
||||
public string Gambar { get; set; } = "";
|
||||
public DateTime Tanggal { get; set; }
|
||||
public string Slug { get; set; }
|
||||
|
||||
public List<string> GambarList { get; set; }
|
||||
public string Slug { get; set; } = "";
|
||||
public List<string> GambarList { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,9 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/berita/berita.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/berita/berita.js"></script>
|
||||
}
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Hero.cshtml", "Berita")
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
|
@ -29,76 +32,3 @@
|
|||
<div class="row" id="beritaList"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function formatTanggal(dateStr) {
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadBerita() {
|
||||
|
||||
fetch('/WebNew/Berita/GetBerita')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
renderBerita(data);
|
||||
|
||||
document.getElementById("search").addEventListener("keyup", function () {
|
||||
const keyword = this.value.toLowerCase();
|
||||
const filtered = data.filter(x =>
|
||||
x.judul.toLowerCase().includes(keyword) ||
|
||||
x.deskripsi.toLowerCase().includes(keyword)
|
||||
);
|
||||
renderBerita(filtered);
|
||||
});
|
||||
|
||||
document.getElementById("filterDate").addEventListener("change", function () {
|
||||
const date = this.value;
|
||||
const filtered = data.filter(x => x.tanggal === date);
|
||||
renderBerita(filtered);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function renderBerita(list) {
|
||||
|
||||
let html = "";
|
||||
|
||||
list.forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100 shadow-sm">
|
||||
|
||||
<img src="${Array.isArray(item.gambar) ? item.gambar[0] : item.gambar}"
|
||||
class="card-img-top">
|
||||
|
||||
<div class="card-body">
|
||||
<small class="text-muted">${formatTanggal(item.tanggal)}</small>
|
||||
|
||||
<h6 class="fw-bold mt-2">${item.judul}</h6>
|
||||
|
||||
<p class="text-muted small">
|
||||
${item.deskripsi}
|
||||
</p>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${item.id}" class="text-primary fw-semibold">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("beritaList").innerHTML = html;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadBerita);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/berita/detailberita.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/berita/detail-berita.js"></script>
|
||||
}
|
||||
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
||||
|
|
@ -37,117 +43,3 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function getQueryParam(name) {
|
||||
return new URLSearchParams(window.location.search).get(name);
|
||||
}
|
||||
|
||||
function formatTanggal(dateStr) {
|
||||
return new Date(dateStr).toLocaleDateString("id-ID", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadDetail() {
|
||||
|
||||
const id = getQueryParam("id");
|
||||
|
||||
fetch(`/WebNew/Berita/GetDetail?id=${id}`)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error("Data tidak ditemukan");
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
|
||||
if (!data) {
|
||||
document.getElementById("judul").innerText = "Data tidak ditemukan";
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById("judul").innerText = data.judul || "-";
|
||||
document.getElementById("tanggal").innerText = formatTanggal(data.tanggal || "");
|
||||
|
||||
renderSlider(data.gambar);
|
||||
|
||||
document.getElementById("isi").innerHTML =
|
||||
(data.isi || "").replace(/\n/g, "<br>");
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
document.getElementById("judul").innerText = "Gagal load berita";
|
||||
});
|
||||
}
|
||||
|
||||
function loadSidebar() {
|
||||
|
||||
fetch('/WebNew/Berita/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.slice(0, 4).forEach(item => {
|
||||
|
||||
let gambar = Array.isArray(item.gambar) ? item.gambar[0] : item.gambar;
|
||||
|
||||
html += `
|
||||
<div class="sidebar-item">
|
||||
<img src="${Array.isArray(item.gambar) ? item.gambar[0] : item.gambar}" class="sidebar-img">
|
||||
|
||||
<div class="sidebar-content">
|
||||
<small class="sidebar-date">${formatTanggal(item.tanggal)}</small>
|
||||
|
||||
<div class="sidebar-title">${item.judul}</div>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${item.id}" class="sidebar-link">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("sidebar").innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
let currentIndex = 0;
|
||||
let sliderImages = [];
|
||||
|
||||
function renderSlider(images) {
|
||||
|
||||
if (!images || images.length === 0) return;
|
||||
|
||||
sliderImages = images;
|
||||
currentIndex = 0;
|
||||
|
||||
const slider = document.getElementById("slider");
|
||||
|
||||
slider.innerHTML = `
|
||||
<img id="slide-img" src="${images[0]}">
|
||||
|
||||
${images.length > 1 ? `
|
||||
<button class="slider-btn prev" onclick="prevSlide()">‹</button>
|
||||
<button class="slider-btn next" onclick="nextSlide()">›</button>
|
||||
` : ""}
|
||||
`;
|
||||
}
|
||||
|
||||
function nextSlide() {
|
||||
currentIndex = (currentIndex + 1) % sliderImages.length;
|
||||
document.getElementById("slide-img").src = sliderImages[currentIndex];
|
||||
}
|
||||
|
||||
function prevSlide() {
|
||||
currentIndex = (currentIndex - 1 + sliderImages.length) % sliderImages.length;
|
||||
document.getElementById("slide-img").src = sliderImages[currentIndex];
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
loadDetail();
|
||||
loadSidebar();
|
||||
});
|
||||
</script>
|
||||
|
|
@ -7,6 +7,11 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/Faq.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/faq.js"></script>
|
||||
}
|
||||
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
<section class="faq-section">
|
||||
|
|
@ -336,41 +341,3 @@
|
|||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
const tabs = document.querySelectorAll(".tab");
|
||||
const panes = document.querySelectorAll(".faq-pane");
|
||||
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener("click", () => {
|
||||
|
||||
tabs.forEach(t => t.classList.remove("active"));
|
||||
tab.classList.add("active");
|
||||
|
||||
panes.forEach(p => p.classList.remove("active"));
|
||||
|
||||
document.getElementById(tab.dataset.tab).classList.add("active");
|
||||
});
|
||||
});
|
||||
|
||||
const faqItems = document.querySelectorAll(".faq-item");
|
||||
|
||||
faqItems.forEach(item => {
|
||||
const header = item.querySelector(".faq-header");
|
||||
|
||||
header.addEventListener("click", () => {
|
||||
|
||||
faqItems.forEach(i => {
|
||||
if (i !== item) {
|
||||
i.classList.remove("active");
|
||||
i.querySelector(".faq-icon").innerText = "+";
|
||||
}
|
||||
});
|
||||
|
||||
item.classList.toggle("active");
|
||||
|
||||
const icon = item.querySelector(".faq-icon");
|
||||
icon.innerText = item.classList.contains("active") ? "−" : "+";
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -22,6 +22,11 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/formreview.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/form-review.js"></script>
|
||||
}
|
||||
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
||||
|
|
@ -138,106 +143,3 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
const form = document.getElementById("formUlasan");
|
||||
const pekerjaan = document.getElementById("pekerjaan");
|
||||
const pekerjaanLainnya = document.getElementById("pekerjaanLainnya");
|
||||
const successMsg = document.getElementById("successMsg");
|
||||
|
||||
pekerjaan.addEventListener("change", function () {
|
||||
if (this.value === "lainnya") {
|
||||
pekerjaanLainnya.classList.remove("d-none");
|
||||
} else {
|
||||
pekerjaanLainnya.classList.add("d-none");
|
||||
pekerjaanLainnya.value = "";
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll("input, select, textarea").forEach(el => {
|
||||
el.addEventListener("input", function () {
|
||||
const container = this.closest(".mb-3, .mb-4");
|
||||
const errorMsg = container?.querySelector(".error-msg");
|
||||
|
||||
this.classList.remove("is-invalid");
|
||||
if (errorMsg) errorMsg.classList.add("d-none");
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll("input[type=radio]").forEach(input => {
|
||||
input.addEventListener("change", function () {
|
||||
const card = this.closest(".question-card");
|
||||
const errorMsg = card.querySelector(".error-msg");
|
||||
|
||||
card.classList.remove("border", "border-danger");
|
||||
errorMsg.classList.add("d-none");
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
let isValid = true;
|
||||
const penilaian = {};
|
||||
|
||||
["gender", "usia", "pendidikan", "pekerjaan", "saran", "ulasan"].forEach(id => {
|
||||
const el = document.getElementById(id);
|
||||
const container = el.closest(".mb-3, .mb-4");
|
||||
const errorMsg = container.querySelector(".error-msg");
|
||||
|
||||
if (!el.value.trim()) {
|
||||
isValid = false;
|
||||
el.classList.add("is-invalid");
|
||||
errorMsg.classList.remove("d-none");
|
||||
}
|
||||
});
|
||||
|
||||
if (pekerjaan.value === "lainnya" && !pekerjaanLainnya.value.trim()) {
|
||||
isValid = false;
|
||||
pekerjaanLainnya.classList.add("is-invalid");
|
||||
}
|
||||
|
||||
document.querySelectorAll(".question-card").forEach(card => {
|
||||
const checked = card.querySelector("input:checked");
|
||||
const errorMsg = card.querySelector(".error-msg");
|
||||
|
||||
if (!checked) {
|
||||
isValid = false;
|
||||
card.classList.add("border", "border-danger");
|
||||
errorMsg.classList.remove("d-none");
|
||||
} else {
|
||||
const input = card.querySelector("input:checked");
|
||||
penilaian[input.name] = Number(input.value);
|
||||
}
|
||||
});
|
||||
|
||||
if (!isValid) return;
|
||||
|
||||
const data = {
|
||||
gender: document.getElementById("gender").value,
|
||||
usia: Number(document.getElementById("usia").value),
|
||||
pendidikan: document.getElementById("pendidikan").value,
|
||||
pekerjaan: pekerjaan.value === "lainnya"
|
||||
? pekerjaanLainnya.value
|
||||
: pekerjaan.value,
|
||||
saran: document.getElementById("saran").value,
|
||||
ulasan: document.getElementById("ulasan").value,
|
||||
penilaian: penilaian
|
||||
};
|
||||
|
||||
console.log("DATA FINAL:", data);
|
||||
|
||||
form.reset();
|
||||
pekerjaanLainnya.classList.add("d-none");
|
||||
|
||||
successMsg.classList.remove("d-none");
|
||||
|
||||
setTimeout(() => {
|
||||
successMsg.classList.add("d-none");
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
|
@ -7,6 +7,11 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/galeri.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/galeri.js"></script>
|
||||
}
|
||||
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
||||
|
|
@ -34,101 +39,3 @@
|
|||
<img class="lightbox-content" id="lightbox-img">
|
||||
<p id="lightbox-description"></p>
|
||||
</div>*@
|
||||
|
||||
<script>
|
||||
//function loadGaleri() {
|
||||
|
||||
// fetch('/Galeri/GetAll')
|
||||
// .then(res => res.json())
|
||||
// .then(data => {
|
||||
|
||||
// let html = "";
|
||||
|
||||
// data.forEach(item => {
|
||||
// html += `
|
||||
// <div class="col-md-4">
|
||||
|
||||
// <div class="galeri-card">
|
||||
// <img src="${item.gambar}" alt="${item.judul}" class="galeri-img">
|
||||
// </div>
|
||||
|
||||
// </div>
|
||||
// `;
|
||||
// });
|
||||
|
||||
// document.getElementById("galeri-list").innerHTML = html;
|
||||
|
||||
// document.querySelectorAll(".galeri-img").forEach(img => {
|
||||
// img.addEventListener("click", function () {
|
||||
// document.getElementById("lightbox").style.display = "block";
|
||||
// document.getElementById("lightbox-img").src = this.src;
|
||||
// document.getElementById("lightbox-description").innerText = this.alt;
|
||||
// });
|
||||
// });
|
||||
|
||||
// });
|
||||
|
||||
// document.querySelector(".lightbox .close").onclick = function () {
|
||||
// document.getElementById("lightbox").style.display = "none";
|
||||
// };
|
||||
|
||||
|
||||
// document.getElementById("lightbox").onclick = function (e) {
|
||||
// if (e.target.id === "lightbox") {
|
||||
// this.style.display = "none";
|
||||
// }
|
||||
// };
|
||||
//}
|
||||
|
||||
//document.addEventListener("DOMContentLoaded", loadGaleri);
|
||||
|
||||
function loadGaleri() {
|
||||
|
||||
fetch('/WebNew/Galeri/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-4">
|
||||
<div class="galeri-card">
|
||||
<img src="${item.gambar}"
|
||||
alt="${item.judul}"
|
||||
class="galeri-img"
|
||||
data-judul="${item.judul}"
|
||||
data-deskripsi="${item.deskripsi}">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("galeri-list").innerHTML = html;
|
||||
|
||||
document.querySelectorAll(".galeri-img").forEach(img => {
|
||||
img.addEventListener("click", function () {
|
||||
|
||||
document.getElementById("lightbox").style.display = "block";
|
||||
document.getElementById("lightbox-img").src = this.src;
|
||||
|
||||
document.getElementById("lightbox-title").innerText = this.dataset.judul;
|
||||
document.getElementById("lightbox-description").innerText = this.dataset.deskripsi;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
document.querySelector(".lightbox .close").onclick = function () {
|
||||
document.getElementById("lightbox").style.display = "none";
|
||||
};
|
||||
|
||||
document.getElementById("lightbox").onclick = function (e) {
|
||||
if (e.target.id === "lightbox") {
|
||||
this.style.display = "none";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadGaleri);
|
||||
</script>
|
||||
|
|
@ -2,6 +2,12 @@
|
|||
Layout = "~/Views/WebNew/Shared/_Layout.cshtml";
|
||||
ViewData["Title"] = "Beranda";
|
||||
}
|
||||
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/home/index.js"></script>
|
||||
}
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
||||
|
|
@ -45,7 +51,7 @@
|
|||
<div class="hero-slide"
|
||||
style="background-image:
|
||||
linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
|
||||
url('/webnew/assets/image/foto/llhd.jpeg');
|
||||
url('/webnew/assets/image/foto/gedungnew.jpeg');
|
||||
background-size:cover;
|
||||
background-position:center;
|
||||
background-repeat:no-repeat">
|
||||
|
|
@ -820,7 +826,7 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
</section>*@
|
||||
</section>*@
|
||||
|
||||
<!-- Video -->
|
||||
<section class="section-video">
|
||||
|
|
@ -858,402 +864,3 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
@section Scripts {
|
||||
<script>
|
||||
|
||||
let currentSlide = 0;
|
||||
let slides = document.querySelectorAll(".hero-slide");
|
||||
let wrapper = document.getElementById("hero-wrapper");
|
||||
let dotsContainer = document.getElementById("hero-dots");
|
||||
|
||||
function initSlider() {
|
||||
slides = document.querySelectorAll(".hero-slide");
|
||||
|
||||
slides.forEach((_, i) => {
|
||||
let dot = document.createElement("span");
|
||||
dot.onclick = () => goToSlide(i);
|
||||
dotsContainer.appendChild(dot);
|
||||
});
|
||||
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
function updateSlider() {
|
||||
wrapper.style.transform = `translateX(-${currentSlide * 100}%)`;
|
||||
|
||||
let dots = dotsContainer.querySelectorAll("span");
|
||||
dots.forEach(d => d.classList.remove("active"));
|
||||
dots[currentSlide].classList.add("active");
|
||||
}
|
||||
|
||||
function nextSlide() {
|
||||
currentSlide = (currentSlide + 1) % slides.length;
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
function prevSlide() {
|
||||
currentSlide = (currentSlide - 1 + slides.length) % slides.length;
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
function goToSlide(index) {
|
||||
currentSlide = index;
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
|
||||
setInterval(nextSlide, 6000);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", initSlider);
|
||||
|
||||
|
||||
//kompetensi
|
||||
|
||||
const swiper = new Swiper(".mySwiper", {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 20,
|
||||
loop: true,
|
||||
|
||||
speed: 5000,
|
||||
|
||||
autoplay: {
|
||||
delay: 0,
|
||||
disableOnInteraction: false,
|
||||
},
|
||||
|
||||
freeMode: true,
|
||||
freeModeMomentum: false,
|
||||
|
||||
breakpoints: {
|
||||
320: { slidesPerView: 1.2 },
|
||||
576: { slidesPerView: 2 },
|
||||
768: { slidesPerView: 3 },
|
||||
1200: { slidesPerView: 4 }
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
//data capaian
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
const counters = document.querySelectorAll('.counter');
|
||||
|
||||
const runCounter = (counter) => {
|
||||
const target = +counter.getAttribute('data-target');
|
||||
let count = 0;
|
||||
|
||||
const duration = 1500;
|
||||
const stepTime = 16;
|
||||
const totalSteps = duration / stepTime;
|
||||
const increment = target / totalSteps;
|
||||
|
||||
const update = () => {
|
||||
count += increment;
|
||||
|
||||
if (count < target) {
|
||||
counter.innerText = Math.floor(count).toLocaleString();
|
||||
requestAnimationFrame(update);
|
||||
} else {
|
||||
counter.innerText = target.toLocaleString();
|
||||
}
|
||||
};
|
||||
|
||||
update();
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver((entries, obs) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
runCounter(entry.target);
|
||||
obs.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.5 });
|
||||
|
||||
counters.forEach(counter => observer.observe(counter));
|
||||
|
||||
});
|
||||
|
||||
|
||||
const ctx = document.getElementById('chartSampel').getContext('2d');
|
||||
|
||||
const gradientBlue = ctx.createLinearGradient(0, 0, 0, 350);
|
||||
gradientBlue.addColorStop(0, 'rgba(59, 130, 246, 0.25)');
|
||||
gradientBlue.addColorStop(1, 'rgba(59, 130, 246, 0.02)');
|
||||
|
||||
const gradientTeal = ctx.createLinearGradient(0, 0, 0, 350);
|
||||
gradientTeal.addColorStop(0, 'rgba(20, 184, 166, 0.25)');
|
||||
gradientTeal.addColorStop(1, 'rgba(20, 184, 166, 0.02)');
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['Tahun 2025', 'Tahun 2024', 'Tahun 2023', 'Tahun 2022'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Internal',
|
||||
data: [1909, 1007, 1567, 1837],
|
||||
borderColor: '#3b82f6',
|
||||
backgroundColor: gradientBlue,
|
||||
fill: true,
|
||||
tension: 0.5,
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 6,
|
||||
pointBackgroundColor: '#fff',
|
||||
pointBorderColor: '#3b82f6',
|
||||
pointBorderWidth: 2
|
||||
},
|
||||
{
|
||||
label: 'Eksternal',
|
||||
data: [9078, 5828, 8069, 8554],
|
||||
borderColor: '#14b8a6',
|
||||
backgroundColor: gradientTeal,
|
||||
fill: true,
|
||||
tension: 0.5,
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 6,
|
||||
pointBackgroundColor: '#fff',
|
||||
pointBorderColor: '#14b8a6',
|
||||
pointBorderWidth: 2
|
||||
},
|
||||
{
|
||||
label: 'Total',
|
||||
data: [10987, 6835, 9636, 10391],
|
||||
borderColor: '#9ca3af',
|
||||
backgroundColor: 'rgba(156, 163, 175, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.5,
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 6,
|
||||
pointBackgroundColor: '#fff',
|
||||
pointBorderColor: '#9ca3af',
|
||||
pointBorderWidth: 2
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
|
||||
interaction: {
|
||||
mode: 'index',
|
||||
intersect: false
|
||||
},
|
||||
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
labels: {
|
||||
usePointStyle: true,
|
||||
pointStyle: 'circle',
|
||||
padding: 20
|
||||
}
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
backgroundColor: '#ffffff',
|
||||
titleColor: '#000',
|
||||
bodyColor: '#000',
|
||||
borderColor: '#e5e7eb',
|
||||
borderWidth: 1,
|
||||
padding: 10,
|
||||
displayColors: false,
|
||||
callbacks: {
|
||||
label: function (context) {
|
||||
return context.dataset.label + ': ' + context.raw.toLocaleString();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scales: {
|
||||
x: {
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
color: '#9ca3af'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
grid: {
|
||||
color: 'rgba(0,0,0,0.05)',
|
||||
drawBorder: false
|
||||
},
|
||||
ticks: {
|
||||
color: '#9ca3af',
|
||||
callback: function (value) {
|
||||
return value.toLocaleString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//mitra
|
||||
|
||||
function loadLogo() {
|
||||
fetch('/webnew/json/mitra.json')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(row => {
|
||||
|
||||
html += `
|
||||
<div class="logo-track move-${row.direction}">
|
||||
${renderGroup(row.logos)}
|
||||
${renderGroup(row.logos)}
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.querySelector(".logo-slider").innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
function renderGroup(logos) {
|
||||
let group = '<div class="logo-group">';
|
||||
|
||||
logos.forEach(src => {
|
||||
group += `<img src="${src}">`;
|
||||
});
|
||||
|
||||
group += '</div>';
|
||||
return group;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadLogo);
|
||||
|
||||
|
||||
//berita
|
||||
|
||||
function formatTanggal(dateStr) {
|
||||
return new Date(dateStr).toLocaleDateString("id-ID", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadLandingBerita() {
|
||||
fetch('/WebNew/Berita/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
if (!data || data.length === 0) return;
|
||||
|
||||
const featured = data[0];
|
||||
|
||||
document.getElementById("featured-berita").innerHTML = `
|
||||
<img src="${Array.isArray(featured.gambar) ? featured.gambar[0] : featured.gambar}" class="featured-img">
|
||||
|
||||
<small class="text-muted d-block mt-2">${formatTanggal(featured.tanggal)}</small>
|
||||
|
||||
<h5 class="fw-bold mt-2">${featured.judul}</h5>
|
||||
|
||||
<p class="text-muted">
|
||||
${featured.deskripsi}
|
||||
</p>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${featured.id}" class="text-primary fw-semibold">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
`;
|
||||
|
||||
let sidebarHTML = "";
|
||||
|
||||
data.slice(1, 5).forEach(item => {
|
||||
sidebarHTML += `
|
||||
<div class="d-flex landing-item mb-3">
|
||||
|
||||
<img src="${Array.isArray(item.gambar) ? item.gambar[0] : item.gambar}" class="landing-img">
|
||||
|
||||
<div>
|
||||
<small class="text-muted">${formatTanggal(item.tanggal)}</small>
|
||||
|
||||
<div class="landing-title">${item.judul}</div>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${item.id}" class="text-primary small">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("sidebar-berita").innerHTML = sidebarHTML;
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadLandingBerita);
|
||||
|
||||
function loadVideoPreview() {
|
||||
|
||||
fetch('/WebNew/Video/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.slice(0, 2).forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-5">
|
||||
|
||||
<div class="video-embed">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/${item.youtube}"
|
||||
frameborder="0"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("video-preview").innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadVideoPreview);
|
||||
|
||||
|
||||
//galeri
|
||||
function loadGaleriPreview() {
|
||||
|
||||
fetch('/WebNew/Galeri/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(item => {
|
||||
|
||||
html += `
|
||||
<div class="galeri-item">
|
||||
<img src="${item.gambar}" alt="${item.judul}">
|
||||
</div>
|
||||
`;
|
||||
|
||||
});
|
||||
|
||||
document.getElementById("galeri-preview").innerHTML = html;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadGaleriPreview);
|
||||
</script>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/layanan/detailitem.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/layanan/detail-item.js"></script>
|
||||
}
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
||||
|
|
@ -55,129 +60,3 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function getQueryParam(name) {
|
||||
return new URLSearchParams(window.location.search).get(name);
|
||||
}
|
||||
|
||||
function loadDetail() {
|
||||
|
||||
const kode = getQueryParam("kode");
|
||||
|
||||
let total = 0;
|
||||
let tbody = "";
|
||||
|
||||
fetch(`/WebNew/DetailItem/GetDetail?kode=${kode}`)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error("Data tidak ditemukan");
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
|
||||
document.getElementById("output").innerText = data.output || "-";
|
||||
document.getElementById("jenis").innerText = data.jenis || "-";
|
||||
|
||||
let thead = "<tr>";
|
||||
(data.table.columns || []).forEach(col => {
|
||||
thead += `<th>${col}</th>`;
|
||||
});
|
||||
thead += "</tr>";
|
||||
document.getElementById("thead").innerHTML = thead;
|
||||
|
||||
(data.table.data || []).forEach(row => {
|
||||
|
||||
tbody += "<tr>";
|
||||
|
||||
(data.table.fields || []).forEach(field => {
|
||||
|
||||
let value = row[field] ?? "-";
|
||||
|
||||
if (field.toLowerCase().includes("biaya")) {
|
||||
let num = Number(value) || 0;
|
||||
total += num;
|
||||
value = "Rp " + num.toLocaleString();
|
||||
}
|
||||
|
||||
tbody += `<td>${value}</td>`;
|
||||
});
|
||||
|
||||
tbody += "</tr>";
|
||||
});
|
||||
|
||||
tbody += `
|
||||
<tr style="background:#f3f4f6; font-weight:600;">
|
||||
<td colspan="${data.table.columns.length - 1}" class="text-end">
|
||||
Total
|
||||
</td>
|
||||
<td>
|
||||
Rp ${total.toLocaleString()}
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
document.getElementById("tbody").innerHTML = tbody;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
document.getElementById("tbody").innerHTML =
|
||||
"<tr><td colspan='7'>Data tidak ditemukan</td></tr>";
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
loadDetail();
|
||||
|
||||
const search = document.getElementById("search");
|
||||
|
||||
if (search) {
|
||||
search.addEventListener("keyup", function () {
|
||||
const keyword = this.value.toLowerCase();
|
||||
const rows = document.querySelectorAll("#tbody tr");
|
||||
|
||||
rows.forEach(row => {
|
||||
const text = row.innerText.toLowerCase();
|
||||
row.style.display = text.includes(keyword) ? "" : "none";
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function exportDetailExcel() {
|
||||
|
||||
const table = document.querySelector(".custom-table");
|
||||
|
||||
if (!table) {
|
||||
alert("Table tidak ditemukan");
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof XLSX === "undefined") {
|
||||
alert("Library XLSX belum ter-load");
|
||||
return;
|
||||
}
|
||||
|
||||
const output = document.getElementById("output").innerText;
|
||||
const jenis = document.getElementById("jenis").innerText;
|
||||
|
||||
const tahun = new Date().getFullYear();
|
||||
|
||||
const fileName = `detail-${output}-${tahun}.xlsx`
|
||||
.replace(/\s+/g, "-");
|
||||
|
||||
const wb = XLSX.utils.book_new();
|
||||
const ws = XLSX.utils.table_to_sheet(table);
|
||||
|
||||
XLSX.utils.sheet_add_aoa(ws, [
|
||||
["Rincian Analisis"],
|
||||
[`Output: ${output}`],
|
||||
[`Jenis: ${jenis}`],
|
||||
[]
|
||||
], { origin: "A1" });
|
||||
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Detail");
|
||||
|
||||
XLSX.writeFile(wb, fileName);
|
||||
}
|
||||
</script>
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
Download Excel
|
||||
</button>
|
||||
|
||||
<input type="text" id="searchTable-harga" placeholder="Cari...">
|
||||
<input type="text" id="searchTable-parameter" placeholder="Cari...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -89,281 +89,4 @@
|
|||
<span class="text-danger">* Parameter yang <b>tebal (bold)</b> telah terakreditasi oleh KAN</span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
let currentPage = {};
|
||||
const rowsPerPage = 5;
|
||||
|
||||
function getQueryParam(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
function changeService(btn, jenis) {
|
||||
window.history.pushState({}, "", `/WebNew/Layanan?jenis=${jenis}`);
|
||||
|
||||
document.querySelectorAll('.service-btn').forEach(b => b.classList.remove('active'));
|
||||
if (btn) btn.classList.add('active');
|
||||
|
||||
loadData(jenis);
|
||||
}
|
||||
|
||||
function loadData(jenis) {
|
||||
|
||||
if (!jenis) jenis = "air";
|
||||
|
||||
document.getElementById("judul").innerText = "Loading...";
|
||||
|
||||
fetch(`/WebNew/Layanan/GetData?jenis=${encodeURIComponent(jenis)}`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
// Informasi layanan
|
||||
document.getElementById("judul").innerText =
|
||||
data.judul || "-";
|
||||
|
||||
document.getElementById("gambar").src =
|
||||
data.gambar || "";
|
||||
|
||||
document.getElementById("deskripsi-singkat").innerText =
|
||||
data["deskripsi-singkat"] || "";
|
||||
|
||||
// Deskripsi list
|
||||
let desc = "";
|
||||
|
||||
(data.deskripsi || []).forEach(d => {
|
||||
desc += `<li>${d}</li>`;
|
||||
});
|
||||
|
||||
document.getElementById("deskripsi").innerHTML = desc;
|
||||
|
||||
|
||||
const judulTable1 =
|
||||
document.getElementById("judul-table1");
|
||||
|
||||
const judulTable2 =
|
||||
document.getElementById("judul-table2");
|
||||
|
||||
if (judulTable1) {
|
||||
judulTable1.innerText =
|
||||
data.judulTable1 || "Info Harga Baku Mutu";
|
||||
}
|
||||
|
||||
if (judulTable2) {
|
||||
judulTable2.innerText =
|
||||
data.judulTable2 || "Info Harga Per Parameter";
|
||||
}
|
||||
|
||||
renderTable("table1", data.table1);
|
||||
renderTable("table2", data.table2);
|
||||
|
||||
setupPagination("table1");
|
||||
setupPagination("table2");
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
console.error(error);
|
||||
|
||||
document.getElementById("judul").innerText =
|
||||
"Data tidak ditemukan";
|
||||
});
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
let jenis = getQueryParam("jenis") || "air";
|
||||
|
||||
loadData(jenis);
|
||||
|
||||
document.querySelectorAll('.service-btn').forEach(btn => {
|
||||
btn.classList.toggle('active', btn.dataset.jenis === jenis);
|
||||
});
|
||||
|
||||
setupSearch("searchTable-harga", "table1");
|
||||
setupSearch("searchTable-parameter", "table2");
|
||||
});
|
||||
|
||||
function renderTable(tableId, tableData) {
|
||||
|
||||
if (!tableData) return;
|
||||
|
||||
let thead = "<tr>";
|
||||
(tableData.columns || []).forEach(col => {
|
||||
thead += `<th>${col}</th>`;
|
||||
});
|
||||
thead += "</tr>";
|
||||
|
||||
document.querySelector(`#${tableId} thead`).innerHTML = thead;
|
||||
|
||||
let tbody = "";
|
||||
|
||||
(tableData.data || []).forEach(row => {
|
||||
tbody += "<tr>";
|
||||
|
||||
(tableData.fields || []).forEach(field => {
|
||||
let value = row[field] ?? "-";
|
||||
|
||||
if (typeof value === "number" && field.toLowerCase().includes("harga")) {
|
||||
value = "Rp " + value.toLocaleString();
|
||||
}
|
||||
|
||||
if (field === "aksi") {
|
||||
value = `
|
||||
<a href="/WebNew/Layanan/DetailItem?kode=${row.kode}"
|
||||
class="btn btn-sm btn-primary rounded-pill">
|
||||
Detail
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
tbody += `<td>${value}</td>`;
|
||||
});
|
||||
|
||||
tbody += "</tr>";
|
||||
});
|
||||
|
||||
document.querySelector(`#${tableId} tbody`).innerHTML = tbody;
|
||||
}
|
||||
|
||||
function setupPagination(tableId) {
|
||||
|
||||
const rows = Array.from(document.querySelectorAll(`#${tableId} tbody tr`))
|
||||
.filter(row => row.style.display !== "none");
|
||||
|
||||
let container = document.getElementById(`pagination-${tableId}`);
|
||||
|
||||
if (!container) {
|
||||
container = document.createElement("div");
|
||||
container.id = `pagination-${tableId}`;
|
||||
container.className = "pagination-wrapper";
|
||||
|
||||
document.querySelector(`#${tableId}`).parentElement.appendChild(container);
|
||||
}
|
||||
|
||||
const totalRows = rows.length;
|
||||
const totalPages = Math.ceil(totalRows / rowsPerPage) || 1;
|
||||
|
||||
let page = 1;
|
||||
|
||||
function showPage(p) {
|
||||
page = p;
|
||||
|
||||
rows.forEach((row, i) => {
|
||||
row.style.display =
|
||||
i >= (p - 1) * rowsPerPage &&
|
||||
i < p * rowsPerPage
|
||||
? ""
|
||||
: "none";
|
||||
});
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
function render() {
|
||||
container.innerHTML = "";
|
||||
|
||||
const start = (page - 1) * rowsPerPage + 1;
|
||||
const end = Math.min(page * rowsPerPage, totalRows);
|
||||
|
||||
const info = document.createElement("div");
|
||||
info.className = "pagination-info";
|
||||
info.innerText = `Showing ${start}–${end} of ${totalRows}`;
|
||||
|
||||
const controls = document.createElement("div");
|
||||
controls.className = "pagination-controls";
|
||||
|
||||
const prev = document.createElement("button");
|
||||
prev.innerText = "‹";
|
||||
prev.className = "page-btn" + (page === 1 ? " disabled" : "");
|
||||
prev.onclick = () => showPage(page - 1);
|
||||
controls.appendChild(prev);
|
||||
|
||||
let pages = [];
|
||||
|
||||
if (totalPages <= 5) {
|
||||
pages = [...Array(totalPages).keys()].map(i => i + 1);
|
||||
} else {
|
||||
pages = [1];
|
||||
|
||||
if (page > 3) pages.push("...");
|
||||
|
||||
for (let i = Math.max(2, page - 1); i <= Math.min(totalPages - 1, page + 1); i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
|
||||
if (page < totalPages - 2) pages.push("...");
|
||||
|
||||
pages.push(totalPages);
|
||||
}
|
||||
|
||||
pages.forEach(p => {
|
||||
const btn = document.createElement("button");
|
||||
|
||||
if (p === "...") {
|
||||
btn.innerText = "...";
|
||||
btn.className = "page-btn disabled";
|
||||
} else {
|
||||
btn.innerText = p;
|
||||
btn.className = "page-btn" + (p === page ? " active" : "");
|
||||
btn.onclick = () => showPage(p);
|
||||
}
|
||||
|
||||
controls.appendChild(btn);
|
||||
});
|
||||
|
||||
const next = document.createElement("button");
|
||||
next.innerText = "›";
|
||||
next.className = "page-btn" + (page === totalPages ? " disabled" : "");
|
||||
next.onclick = () => showPage(page + 1);
|
||||
controls.appendChild(next);
|
||||
|
||||
container.appendChild(info);
|
||||
container.appendChild(controls);
|
||||
}
|
||||
|
||||
showPage(1);
|
||||
}
|
||||
|
||||
function setupSearch(inputId, tableId) {
|
||||
|
||||
const input = document.getElementById(inputId);
|
||||
|
||||
input.addEventListener("keyup", function () {
|
||||
const keyword = input.value.toLowerCase();
|
||||
const rows = document.querySelectorAll(`#${tableId} tbody tr`);
|
||||
|
||||
rows.forEach(row => {
|
||||
const text = row.innerText.toLowerCase();
|
||||
row.style.display = text.includes(keyword) ? "" : "none";
|
||||
});
|
||||
|
||||
setupPagination(tableId);
|
||||
});
|
||||
}
|
||||
|
||||
function exportTableToExcel(tableId) {
|
||||
|
||||
const table = document.getElementById(tableId);
|
||||
|
||||
if (!table || typeof XLSX === "undefined") {
|
||||
alert("Export gagal");
|
||||
return;
|
||||
}
|
||||
|
||||
let jenis = getQueryParam("jenis") || "data";
|
||||
const tahun = new Date().getFullYear();
|
||||
|
||||
jenis = jenis.toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
const fileName = `${jenis}-${tableId}-${tahun}.xlsx`;
|
||||
|
||||
const wb = XLSX.utils.book_new();
|
||||
const ws = XLSX.utils.table_to_sheet(table);
|
||||
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Data");
|
||||
|
||||
XLSX.writeFile(wb, fileName);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script src="~/webnew/pages/layanan/detail-layanan.js"></script>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/layanan/layanan.js"></script>
|
||||
}
|
||||
|
||||
|
||||
<div class="layanan-page">
|
||||
|
||||
|
|
@ -106,31 +110,3 @@
|
|||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function getQueryParam(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
const jenis = getQueryParam("jenis");
|
||||
|
||||
if (jenis) {
|
||||
fetch(`/WebNew/Layanan/GetData?jenis=${jenis}`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
document.getElementById("content").innerHTML = `
|
||||
<div class="container mt-5">
|
||||
<h2>${data.judul}</h2>
|
||||
<ul>
|
||||
${data.deskripsi.map(d => `<li>${d}</li>`).join("")}
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/regulasi.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/regulasi.js"></script>
|
||||
}
|
||||
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Hero.cshtml", "Regulasi")
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
|
@ -54,276 +59,3 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
let allData = [];
|
||||
let filteredData = [];
|
||||
let currentKategori = "peraturan";
|
||||
let currentPage = 1;
|
||||
const perPage = 10;
|
||||
|
||||
function formatTanggal(dateStr) {
|
||||
return new Date(dateStr).toLocaleDateString("id-ID", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadRegulasi() {
|
||||
fetch('/WebNew/Regulasi/GetRegulasi')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
allData = data;
|
||||
filterData();
|
||||
});
|
||||
}
|
||||
|
||||
function filterData() {
|
||||
const keyword = document.getElementById("search").value.toLowerCase();
|
||||
const tahun = document.getElementById("tahun").value;
|
||||
|
||||
filteredData = allData.filter(item => {
|
||||
const kategori = (item.kategori || "").trim().toLowerCase();
|
||||
const judul = (item.judul || "").toLowerCase();
|
||||
|
||||
return (
|
||||
kategori === currentKategori &&
|
||||
judul.includes(keyword) &&
|
||||
(tahun === "" || item.tahun == tahun)
|
||||
);
|
||||
});
|
||||
|
||||
currentPage = 1;
|
||||
renderPagination();
|
||||
}
|
||||
|
||||
function renderPagination() {
|
||||
const start = (currentPage - 1) * perPage;
|
||||
const end = start + perPage;
|
||||
|
||||
const paginatedData = filteredData.slice(start, end);
|
||||
|
||||
renderData(paginatedData);
|
||||
renderPaginationControls();
|
||||
renderPaginationInfo(start, end);
|
||||
}
|
||||
|
||||
function renderData(data) {
|
||||
|
||||
let html = "";
|
||||
|
||||
if (data.length === 0) {
|
||||
html = `
|
||||
<p class="text-muted text-center">
|
||||
Data tidak ditemukan
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
|
||||
data.forEach((item, index) => {
|
||||
|
||||
let lampiranHtml = "";
|
||||
|
||||
if (item.lampiran && item.lampiran.length > 0) {
|
||||
|
||||
item.lampiran.forEach(l => {
|
||||
|
||||
lampiranHtml += `
|
||||
<div class="lampiran-item">
|
||||
|
||||
<span>
|
||||
<i class="bi bi-paperclip"></i>
|
||||
${l.judul}
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<a href="${l.file}"
|
||||
target="_blank"
|
||||
class="btn btn-light btn-sm me-2">
|
||||
|
||||
Lihat
|
||||
|
||||
</a>
|
||||
|
||||
<a href="${l.file}"
|
||||
download
|
||||
class="btn btn-primary btn-sm">
|
||||
|
||||
Unduh
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `
|
||||
|
||||
<div class="card regulasi-card mb-3">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap gap-3">
|
||||
|
||||
<div class="d-flex align-items-center regulasi-toggle"
|
||||
${item.lampiran?.length > 0
|
||||
? `data-bs-toggle="collapse"
|
||||
data-bs-target="#lampiran-${index}"`
|
||||
: ""}>
|
||||
|
||||
<div class="me-3">
|
||||
<i class="bi bi-file-earmark-pdf fs-2 text-primary file-icon"></i>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<h6 class="mb-1">
|
||||
${item.judul}
|
||||
</h6>
|
||||
|
||||
<small class="text-muted">
|
||||
${formatTanggal(item.tanggal)}
|
||||
|
|
||||
Diunduh ${item.download} kali
|
||||
</small>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
|
||||
<a href="${item.file}"
|
||||
target="_blank"
|
||||
class="btn btn-light btn-sm">
|
||||
|
||||
Lihat
|
||||
|
||||
</a>
|
||||
|
||||
<a href="${item.file}"
|
||||
download
|
||||
class="btn btn-primary btn-sm">
|
||||
|
||||
Unduh
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
${item.lampiran?.length > 0
|
||||
? `
|
||||
<button
|
||||
class="btn btn-outline-primary btn-sm btn-lampiran collapsed"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#lampiran-${index}">
|
||||
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
|
||||
</button>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
${item.lampiran?.length > 0
|
||||
? `
|
||||
<div class="collapse mt-3"
|
||||
id="lampiran-${index}">
|
||||
|
||||
${lampiranHtml}
|
||||
|
||||
</div>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("list-regulasi").innerHTML = html;
|
||||
}
|
||||
|
||||
function renderPaginationControls() {
|
||||
|
||||
const totalPages = Math.ceil(filteredData.length / perPage);
|
||||
|
||||
let html = "";
|
||||
|
||||
if (totalPages === 0) {
|
||||
document.getElementById("pagination").innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
html += `
|
||||
<button class="btn btn-sm btn-outline-primary me-1"
|
||||
${currentPage === 1 ? "disabled" : ""}
|
||||
onclick="changePage(${currentPage - 1})">
|
||||
«
|
||||
</button>
|
||||
`;
|
||||
|
||||
for (let i = 1; i <= totalPages; i++) {
|
||||
html += `
|
||||
<button
|
||||
class="btn btn-sm ${i === currentPage ? "btn-primary" : "btn-outline-primary"} mx-1"
|
||||
onclick="changePage(${i})">
|
||||
${i}
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
html += `
|
||||
<button class="btn btn-sm btn-outline-primary ms-1"
|
||||
${currentPage === totalPages ? "disabled" : ""}
|
||||
onclick="changePage(${currentPage + 1})">
|
||||
»
|
||||
</button>
|
||||
`;
|
||||
|
||||
document.getElementById("pagination").innerHTML = html;
|
||||
}
|
||||
|
||||
function renderPaginationInfo(start, end) {
|
||||
const total = filteredData.length;
|
||||
|
||||
if (total === 0) {
|
||||
document.getElementById("pagination-info").innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
const from = start + 1;
|
||||
const to = Math.min(end, total);
|
||||
|
||||
document.getElementById("pagination-info").innerHTML =
|
||||
`Show ${from}–${to} of ${total} data`;
|
||||
}
|
||||
|
||||
window.changePage = function (page) {
|
||||
currentPage = page;
|
||||
renderPagination();
|
||||
window.scrollTo({ top: 300, behavior: "smooth" });
|
||||
};
|
||||
|
||||
document.querySelectorAll(".filter-btn").forEach(btn => {
|
||||
btn.addEventListener("click", function () {
|
||||
document.querySelectorAll(".filter-btn").forEach(b => b.classList.remove("active"));
|
||||
this.classList.add("active");
|
||||
currentKategori = this.dataset.kategori;
|
||||
filterData();
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("search").addEventListener("keyup", filterData);
|
||||
document.getElementById("tahun").addEventListener("change", filterData);
|
||||
|
||||
loadRegulasi();
|
||||
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<footer class="footer-section"
|
||||
style="background-image: url(' /webnew/assets/image/footer.png');">
|
||||
">
|
||||
<div class="container py-5">
|
||||
|
||||
<div class="row">
|
||||
|
|
|
|||
|
|
@ -107,75 +107,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let allData = [];
|
||||
|
||||
async function loadSearchData() {
|
||||
const regulasi = await fetch('/WebNew/Regulasi/GetRegulasi').then(r => r.json());
|
||||
const berita = await fetch('/WebNew/Berita/GetAll').then(r => r.json());
|
||||
|
||||
allData = [
|
||||
...regulasi.map(x => ({ ...x, type: 'regulasi' })),
|
||||
...berita.map(x => ({ ...x, type: 'berita' })),
|
||||
];
|
||||
}
|
||||
|
||||
function searchData(keyword) {
|
||||
|
||||
keyword = keyword.toLowerCase();
|
||||
|
||||
const result = allData.filter(item =>
|
||||
item.judul.toLowerCase().includes(keyword)
|
||||
);
|
||||
|
||||
renderResult(result);
|
||||
}
|
||||
|
||||
function renderResult(data) {
|
||||
|
||||
let html = "";
|
||||
|
||||
if (data.length === 0) {
|
||||
html = "<p class='text-muted'>Tidak ditemukan</p>";
|
||||
}
|
||||
|
||||
data.slice(0, 5).forEach(item => {
|
||||
|
||||
let link = "#";
|
||||
|
||||
if (item.type === "berita") {
|
||||
link = `/WebNew/Berita/Detail?id=${item.id}`;
|
||||
}
|
||||
|
||||
if (item.type === "regulasi") {
|
||||
link = item.file;
|
||||
}
|
||||
|
||||
html += `
|
||||
<a href="${link}" class="search-item d-block mb-2 rounded p-2">
|
||||
<strong>${item.judul}</strong><br>
|
||||
<small class="text-muted">${item.type}</small>
|
||||
</a>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("searchResult").innerHTML = html;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
loadSearchData();
|
||||
|
||||
document.getElementById("searchInput").addEventListener("keyup", function () {
|
||||
const keyword = this.value;
|
||||
|
||||
if (keyword.length < 2) {
|
||||
document.getElementById("searchResult").innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
searchData(keyword);
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="~/webnew/pages/header.js"></script>
|
||||
|
|
@ -6,6 +6,11 @@
|
|||
<link rel="stylesheet" href="~/webnew/css/video.css" asp-append-version="true" />
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/webnew/pages/video.js"></script>
|
||||
}
|
||||
|
||||
|
||||
@await Html.PartialAsync("~/Views/WebNew/Shared/Section/_Helpdesk.cshtml")
|
||||
|
||||
|
||||
|
|
@ -24,48 +29,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadVideo() {
|
||||
|
||||
fetch('/WebNew/Video/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-4">
|
||||
<div class="youtube-wrapper">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/${item.youtube}"
|
||||
title="${item.judul}"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("video-list").innerHTML = html;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function openVideo(url) {
|
||||
document.getElementById("videoFrame").src = url;
|
||||
document.getElementById("videoModal").style.display = "flex";
|
||||
}
|
||||
|
||||
function closeVideo() {
|
||||
document.getElementById("videoFrame").src = "";
|
||||
document.getElementById("videoModal").style.display = "none";
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadVideo);
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 6.6 MiB |
|
|
@ -0,0 +1,70 @@
|
|||
function formatTanggal(dateStr) {
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadBerita() {
|
||||
|
||||
fetch('/WebNew/Berita/GetBerita')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
renderBerita(data);
|
||||
|
||||
document.getElementById("search").addEventListener("keyup", function () {
|
||||
const keyword = this.value.toLowerCase();
|
||||
const filtered = data.filter(x =>
|
||||
x.judul.toLowerCase().includes(keyword) ||
|
||||
x.deskripsi.toLowerCase().includes(keyword)
|
||||
);
|
||||
renderBerita(filtered);
|
||||
});
|
||||
|
||||
document.getElementById("filterDate").addEventListener("change", function () {
|
||||
const date = this.value;
|
||||
const filtered = data.filter(x => x.tanggal === date);
|
||||
renderBerita(filtered);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function renderBerita(list) {
|
||||
|
||||
let html = "";
|
||||
|
||||
list.forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100 shadow-sm">
|
||||
|
||||
<img src="${Array.isArray(item.gambar) ? item.gambar[0] : item.gambar}"
|
||||
class="card-img-top">
|
||||
|
||||
<div class="card-body">
|
||||
<small class="text-muted">${formatTanggal(item.tanggal)}</small>
|
||||
|
||||
<h6 class="fw-bold mt-2">${item.judul}</h6>
|
||||
|
||||
<p class="text-muted small">
|
||||
${item.deskripsi}
|
||||
</p>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${item.id}" class="text-primary fw-semibold">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("beritaList").innerHTML = html;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadBerita);
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
function getQueryParam(name) {
|
||||
return new URLSearchParams(window.location.search).get(name);
|
||||
}
|
||||
|
||||
function formatTanggal(dateStr) {
|
||||
return new Date(dateStr).toLocaleDateString("id-ID", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadDetail() {
|
||||
|
||||
const id = getQueryParam("id");
|
||||
|
||||
fetch(`/WebNew/Berita/GetDetail?id=${id}`)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error("Data tidak ditemukan");
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
|
||||
if (!data) {
|
||||
document.getElementById("judul").innerText = "Data tidak ditemukan";
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById("judul").innerText = data.judul || "-";
|
||||
document.getElementById("tanggal").innerText = formatTanggal(data.tanggal || "");
|
||||
|
||||
renderSlider(data.gambar);
|
||||
|
||||
document.getElementById("isi").innerHTML =
|
||||
(data.isi || "").replace(/\n/g, "<br>");
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
document.getElementById("judul").innerText = "Gagal load berita";
|
||||
});
|
||||
}
|
||||
|
||||
function loadSidebar() {
|
||||
|
||||
fetch('/WebNew/Berita/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.slice(0, 4).forEach(item => {
|
||||
|
||||
let gambar = Array.isArray(item.gambar) ? item.gambar[0] : item.gambar;
|
||||
|
||||
html += `
|
||||
<div class="sidebar-item">
|
||||
<img src="${Array.isArray(item.gambar) ? item.gambar[0] : item.gambar}" class="sidebar-img">
|
||||
|
||||
<div class="sidebar-content">
|
||||
<small class="sidebar-date">${formatTanggal(item.tanggal)}</small>
|
||||
|
||||
<div class="sidebar-title">${item.judul}</div>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${item.id}" class="sidebar-link">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("sidebar").innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
let currentIndex = 0;
|
||||
let sliderImages = [];
|
||||
|
||||
function renderSlider(images) {
|
||||
|
||||
if (!images || images.length === 0) return;
|
||||
|
||||
sliderImages = images;
|
||||
currentIndex = 0;
|
||||
|
||||
const slider = document.getElementById("slider");
|
||||
|
||||
slider.innerHTML = `
|
||||
<img id="slide-img" src="${images[0]}">
|
||||
|
||||
${images.length > 1 ? `
|
||||
<button class="slider-btn prev" onclick="prevSlide()">‹</button>
|
||||
<button class="slider-btn next" onclick="nextSlide()">›</button>
|
||||
` : ""}
|
||||
`;
|
||||
}
|
||||
|
||||
function nextSlide() {
|
||||
currentIndex = (currentIndex + 1) % sliderImages.length;
|
||||
document.getElementById("slide-img").src = sliderImages[currentIndex];
|
||||
}
|
||||
|
||||
function prevSlide() {
|
||||
currentIndex = (currentIndex - 1 + sliderImages.length) % sliderImages.length;
|
||||
document.getElementById("slide-img").src = sliderImages[currentIndex];
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
loadDetail();
|
||||
loadSidebar();
|
||||
});
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
const tabs = document.querySelectorAll(".tab");
|
||||
const panes = document.querySelectorAll(".faq-pane");
|
||||
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener("click", () => {
|
||||
|
||||
tabs.forEach(t => t.classList.remove("active"));
|
||||
tab.classList.add("active");
|
||||
|
||||
panes.forEach(p => p.classList.remove("active"));
|
||||
|
||||
document.getElementById(tab.dataset.tab).classList.add("active");
|
||||
});
|
||||
});
|
||||
|
||||
const faqItems = document.querySelectorAll(".faq-item");
|
||||
|
||||
faqItems.forEach(item => {
|
||||
const header = item.querySelector(".faq-header");
|
||||
|
||||
header.addEventListener("click", () => {
|
||||
|
||||
faqItems.forEach(i => {
|
||||
if (i !== item) {
|
||||
i.classList.remove("active");
|
||||
i.querySelector(".faq-icon").innerText = "+";
|
||||
}
|
||||
});
|
||||
|
||||
item.classList.toggle("active");
|
||||
|
||||
const icon = item.querySelector(".faq-icon");
|
||||
icon.innerText = item.classList.contains("active") ? "−" : "+";
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
const form = document.getElementById("formUlasan");
|
||||
const pekerjaan = document.getElementById("pekerjaan");
|
||||
const pekerjaanLainnya = document.getElementById("pekerjaanLainnya");
|
||||
const successMsg = document.getElementById("successMsg");
|
||||
|
||||
pekerjaan.addEventListener("change", function () {
|
||||
if (this.value === "lainnya") {
|
||||
pekerjaanLainnya.classList.remove("d-none");
|
||||
} else {
|
||||
pekerjaanLainnya.classList.add("d-none");
|
||||
pekerjaanLainnya.value = "";
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll("input, select, textarea").forEach(el => {
|
||||
el.addEventListener("input", function () {
|
||||
const container = this.closest(".mb-3, .mb-4");
|
||||
const errorMsg = container?.querySelector(".error-msg");
|
||||
|
||||
this.classList.remove("is-invalid");
|
||||
if (errorMsg) errorMsg.classList.add("d-none");
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll("input[type=radio]").forEach(input => {
|
||||
input.addEventListener("change", function () {
|
||||
const card = this.closest(".question-card");
|
||||
const errorMsg = card.querySelector(".error-msg");
|
||||
|
||||
card.classList.remove("border", "border-danger");
|
||||
errorMsg.classList.add("d-none");
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
let isValid = true;
|
||||
const penilaian = {};
|
||||
|
||||
["gender", "usia", "pendidikan", "pekerjaan", "saran", "ulasan"].forEach(id => {
|
||||
const el = document.getElementById(id);
|
||||
const container = el.closest(".mb-3, .mb-4");
|
||||
const errorMsg = container.querySelector(".error-msg");
|
||||
|
||||
if (!el.value.trim()) {
|
||||
isValid = false;
|
||||
el.classList.add("is-invalid");
|
||||
errorMsg.classList.remove("d-none");
|
||||
}
|
||||
});
|
||||
|
||||
if (pekerjaan.value === "lainnya" && !pekerjaanLainnya.value.trim()) {
|
||||
isValid = false;
|
||||
pekerjaanLainnya.classList.add("is-invalid");
|
||||
}
|
||||
|
||||
document.querySelectorAll(".question-card").forEach(card => {
|
||||
const checked = card.querySelector("input:checked");
|
||||
const errorMsg = card.querySelector(".error-msg");
|
||||
|
||||
if (!checked) {
|
||||
isValid = false;
|
||||
card.classList.add("border", "border-danger");
|
||||
errorMsg.classList.remove("d-none");
|
||||
} else {
|
||||
const input = card.querySelector("input:checked");
|
||||
penilaian[input.name] = Number(input.value);
|
||||
}
|
||||
});
|
||||
|
||||
if (!isValid) return;
|
||||
|
||||
const data = {
|
||||
gender: document.getElementById("gender").value,
|
||||
usia: Number(document.getElementById("usia").value),
|
||||
pendidikan: document.getElementById("pendidikan").value,
|
||||
pekerjaan: pekerjaan.value === "lainnya"
|
||||
? pekerjaanLainnya.value
|
||||
: pekerjaan.value,
|
||||
saran: document.getElementById("saran").value,
|
||||
ulasan: document.getElementById("ulasan").value,
|
||||
penilaian: penilaian
|
||||
};
|
||||
|
||||
console.log("DATA FINAL:", data);
|
||||
|
||||
form.reset();
|
||||
pekerjaanLainnya.classList.add("d-none");
|
||||
|
||||
successMsg.classList.remove("d-none");
|
||||
|
||||
setTimeout(() => {
|
||||
successMsg.classList.add("d-none");
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
function loadGaleri() {
|
||||
|
||||
fetch('/WebNew/Galeri/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-4">
|
||||
<div class="galeri-card">
|
||||
<img src="${item.gambar}"
|
||||
alt="${item.judul}"
|
||||
class="galeri-img"
|
||||
data-judul="${item.judul}"
|
||||
data-deskripsi="${item.deskripsi}">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("galeri-list").innerHTML = html;
|
||||
|
||||
document.querySelectorAll(".galeri-img").forEach(img => {
|
||||
img.addEventListener("click", function () {
|
||||
|
||||
document.getElementById("lightbox").style.display = "block";
|
||||
document.getElementById("lightbox-img").src = this.src;
|
||||
|
||||
document.getElementById("lightbox-title").innerText = this.dataset.judul;
|
||||
document.getElementById("lightbox-description").innerText = this.dataset.deskripsi;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
document.querySelector(".lightbox .close").onclick = function () {
|
||||
document.getElementById("lightbox").style.display = "none";
|
||||
};
|
||||
|
||||
document.getElementById("lightbox").onclick = function (e) {
|
||||
if (e.target.id === "lightbox") {
|
||||
this.style.display = "none";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadGaleri);
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
let allData = [];
|
||||
|
||||
async function loadSearchData() {
|
||||
const regulasi = await fetch('/WebNew/Regulasi/GetRegulasi').then(r => r.json());
|
||||
const berita = await fetch('/WebNew/Berita/GetAll').then(r => r.json());
|
||||
|
||||
allData = [
|
||||
...regulasi.map(x => ({ ...x, type: 'regulasi' })),
|
||||
...berita.map(x => ({ ...x, type: 'berita' })),
|
||||
];
|
||||
}
|
||||
|
||||
function searchData(keyword) {
|
||||
|
||||
keyword = keyword.toLowerCase();
|
||||
|
||||
const result = allData.filter(item =>
|
||||
item.judul.toLowerCase().includes(keyword)
|
||||
);
|
||||
|
||||
renderResult(result);
|
||||
}
|
||||
|
||||
function renderResult(data) {
|
||||
|
||||
let html = "";
|
||||
|
||||
if (data.length === 0) {
|
||||
html = "<p class='text-muted'>Tidak ditemukan</p>";
|
||||
}
|
||||
|
||||
data.slice(0, 5).forEach(item => {
|
||||
|
||||
let link = "#";
|
||||
|
||||
if (item.type === "berita") {
|
||||
link = `/WebNew/Berita/Detail?id=${item.id}`;
|
||||
}
|
||||
|
||||
if (item.type === "regulasi") {
|
||||
link = item.file;
|
||||
}
|
||||
|
||||
html += `
|
||||
<a href="${link}" class="search-item d-block mb-2 rounded p-2">
|
||||
<strong>${item.judul}</strong><br>
|
||||
<small class="text-muted">${item.type}</small>
|
||||
</a>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("searchResult").innerHTML = html;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
loadSearchData();
|
||||
|
||||
document.getElementById("searchInput").addEventListener("keyup", function () {
|
||||
const keyword = this.value;
|
||||
|
||||
if (keyword.length < 2) {
|
||||
document.getElementById("searchResult").innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
searchData(keyword);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,395 @@
|
|||
|
||||
let currentSlide = 0;
|
||||
let slides = document.querySelectorAll(".hero-slide");
|
||||
let wrapper = document.getElementById("hero-wrapper");
|
||||
let dotsContainer = document.getElementById("hero-dots");
|
||||
|
||||
function initSlider() {
|
||||
slides = document.querySelectorAll(".hero-slide");
|
||||
|
||||
slides.forEach((_, i) => {
|
||||
let dot = document.createElement("span");
|
||||
dot.onclick = () => goToSlide(i);
|
||||
dotsContainer.appendChild(dot);
|
||||
});
|
||||
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
function updateSlider() {
|
||||
wrapper.style.transform = `translateX(-${currentSlide * 100}%)`;
|
||||
|
||||
let dots = dotsContainer.querySelectorAll("span");
|
||||
dots.forEach(d => d.classList.remove("active"));
|
||||
dots[currentSlide].classList.add("active");
|
||||
}
|
||||
|
||||
function nextSlide() {
|
||||
currentSlide = (currentSlide + 1) % slides.length;
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
function prevSlide() {
|
||||
currentSlide = (currentSlide - 1 + slides.length) % slides.length;
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
function goToSlide(index) {
|
||||
currentSlide = index;
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
|
||||
setInterval(nextSlide, 6000);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", initSlider);
|
||||
|
||||
|
||||
//kompetensi
|
||||
|
||||
const swiper = new Swiper(".mySwiper", {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 20,
|
||||
loop: true,
|
||||
|
||||
speed: 5000,
|
||||
|
||||
autoplay: {
|
||||
delay: 0,
|
||||
disableOnInteraction: false,
|
||||
},
|
||||
|
||||
freeMode: true,
|
||||
freeModeMomentum: false,
|
||||
|
||||
breakpoints: {
|
||||
320: { slidesPerView: 1.2 },
|
||||
576: { slidesPerView: 2 },
|
||||
768: { slidesPerView: 3 },
|
||||
1200: { slidesPerView: 4 }
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
//data capaian
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
const counters = document.querySelectorAll('.counter');
|
||||
|
||||
const runCounter = (counter) => {
|
||||
const target = +counter.getAttribute('data-target');
|
||||
let count = 0;
|
||||
|
||||
const duration = 1500;
|
||||
const stepTime = 16;
|
||||
const totalSteps = duration / stepTime;
|
||||
const increment = target / totalSteps;
|
||||
|
||||
const update = () => {
|
||||
count += increment;
|
||||
|
||||
if (count < target) {
|
||||
counter.innerText = Math.floor(count).toLocaleString();
|
||||
requestAnimationFrame(update);
|
||||
} else {
|
||||
counter.innerText = target.toLocaleString();
|
||||
}
|
||||
};
|
||||
|
||||
update();
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver((entries, obs) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
runCounter(entry.target);
|
||||
obs.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.5 });
|
||||
|
||||
counters.forEach(counter => observer.observe(counter));
|
||||
|
||||
});
|
||||
|
||||
|
||||
const ctx = document.getElementById('chartSampel').getContext('2d');
|
||||
|
||||
const gradientBlue = ctx.createLinearGradient(0, 0, 0, 350);
|
||||
gradientBlue.addColorStop(0, 'rgba(59, 130, 246, 0.25)');
|
||||
gradientBlue.addColorStop(1, 'rgba(59, 130, 246, 0.02)');
|
||||
|
||||
const gradientTeal = ctx.createLinearGradient(0, 0, 0, 350);
|
||||
gradientTeal.addColorStop(0, 'rgba(20, 184, 166, 0.25)');
|
||||
gradientTeal.addColorStop(1, 'rgba(20, 184, 166, 0.02)');
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['Tahun 2025', 'Tahun 2024', 'Tahun 2023', 'Tahun 2022'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Internal',
|
||||
data: [1909, 1007, 1567, 1837],
|
||||
borderColor: '#3b82f6',
|
||||
backgroundColor: gradientBlue,
|
||||
fill: true,
|
||||
tension: 0.5,
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 6,
|
||||
pointBackgroundColor: '#fff',
|
||||
pointBorderColor: '#3b82f6',
|
||||
pointBorderWidth: 2
|
||||
},
|
||||
{
|
||||
label: 'Eksternal',
|
||||
data: [9078, 5828, 8069, 8554],
|
||||
borderColor: '#14b8a6',
|
||||
backgroundColor: gradientTeal,
|
||||
fill: true,
|
||||
tension: 0.5,
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 6,
|
||||
pointBackgroundColor: '#fff',
|
||||
pointBorderColor: '#14b8a6',
|
||||
pointBorderWidth: 2
|
||||
},
|
||||
{
|
||||
label: 'Total',
|
||||
data: [10987, 6835, 9636, 10391],
|
||||
borderColor: '#9ca3af',
|
||||
backgroundColor: 'rgba(156, 163, 175, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.5,
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 6,
|
||||
pointBackgroundColor: '#fff',
|
||||
pointBorderColor: '#9ca3af',
|
||||
pointBorderWidth: 2
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
|
||||
interaction: {
|
||||
mode: 'index',
|
||||
intersect: false
|
||||
},
|
||||
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
labels: {
|
||||
usePointStyle: true,
|
||||
pointStyle: 'circle',
|
||||
padding: 20
|
||||
}
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
backgroundColor: '#ffffff',
|
||||
titleColor: '#000',
|
||||
bodyColor: '#000',
|
||||
borderColor: '#e5e7eb',
|
||||
borderWidth: 1,
|
||||
padding: 10,
|
||||
displayColors: false,
|
||||
callbacks: {
|
||||
label: function (context) {
|
||||
return context.dataset.label + ': ' + context.raw.toLocaleString();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scales: {
|
||||
x: {
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
color: '#9ca3af'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
grid: {
|
||||
color: 'rgba(0,0,0,0.05)',
|
||||
drawBorder: false
|
||||
},
|
||||
ticks: {
|
||||
color: '#9ca3af',
|
||||
callback: function (value) {
|
||||
return value.toLocaleString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//mitra
|
||||
|
||||
function loadLogo() {
|
||||
fetch('/webnew/json/mitra.json')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(row => {
|
||||
|
||||
html += `
|
||||
<div class="logo-track move-${row.direction}">
|
||||
${renderGroup(row.logos)}
|
||||
${renderGroup(row.logos)}
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.querySelector(".logo-slider").innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
function renderGroup(logos) {
|
||||
let group = '<div class="logo-group">';
|
||||
|
||||
logos.forEach(src => {
|
||||
group += `<img src="${src}">`;
|
||||
});
|
||||
|
||||
group += '</div>';
|
||||
return group;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadLogo);
|
||||
|
||||
|
||||
//berita
|
||||
|
||||
function formatTanggal(dateStr) {
|
||||
return new Date(dateStr).toLocaleDateString("id-ID", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadLandingBerita() {
|
||||
fetch('/WebNew/Berita/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
if (!data || data.length === 0) return;
|
||||
|
||||
const featured = data[0];
|
||||
|
||||
document.getElementById("featured-berita").innerHTML = `
|
||||
<img src="${Array.isArray(featured.gambar) ? featured.gambar[0] : featured.gambar}" class="featured-img">
|
||||
|
||||
<small class="text-muted d-block mt-2">${formatTanggal(featured.tanggal)}</small>
|
||||
|
||||
<h5 class="fw-bold mt-2">${featured.judul}</h5>
|
||||
|
||||
<p class="text-muted">
|
||||
${featured.deskripsi}
|
||||
</p>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${featured.id}" class="text-primary fw-semibold">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
`;
|
||||
|
||||
let sidebarHTML = "";
|
||||
|
||||
data.slice(1, 5).forEach(item => {
|
||||
sidebarHTML += `
|
||||
<div class="d-flex landing-item mb-3">
|
||||
<img src="${Array.isArray(item.gambar) ? item.gambar[0] : item.gambar}" class="landing-img">
|
||||
<div>
|
||||
<small class="text-muted">${formatTanggal(item.tanggal)}</small>
|
||||
|
||||
<div class="landing-title">${item.judul}</div>
|
||||
|
||||
<a href="/WebNew/Berita/Detail?id=${item.id}" class="text-primary small">
|
||||
Baca Selengkapnya
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
`;
|
||||
|
||||
});
|
||||
|
||||
document.getElementById("sidebar-berita").innerHTML = sidebarHTML;
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadLandingBerita);
|
||||
|
||||
function loadVideoPreview() {
|
||||
|
||||
fetch('/WebNew/Video/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.slice(0, 2).forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-5">
|
||||
|
||||
<div class="video-embed">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/${item.youtube}"
|
||||
frameborder="0"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("video-preview").innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadVideoPreview);
|
||||
|
||||
|
||||
//galeri
|
||||
function loadGaleriPreview() {
|
||||
|
||||
fetch('/WebNew/Galeri/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(item => {
|
||||
|
||||
html += `
|
||||
<div class="galeri-item">
|
||||
<img src="${item.gambar}" alt="${item.judul}">
|
||||
</div>
|
||||
`;
|
||||
|
||||
});
|
||||
|
||||
document.getElementById("galeri-preview").innerHTML = html;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadGaleriPreview);
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
function getQueryParam(name) {
|
||||
return new URLSearchParams(window.location.search).get(name);
|
||||
}
|
||||
|
||||
function loadDetail() {
|
||||
|
||||
const kode = getQueryParam("kode");
|
||||
|
||||
let total = 0;
|
||||
let tbody = "";
|
||||
|
||||
fetch(`/WebNew/DetailItem/GetDetail?kode=${kode}`)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error("Data tidak ditemukan");
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
|
||||
document.getElementById("output").innerText = data.output || "-";
|
||||
document.getElementById("jenis").innerText = data.jenis || "-";
|
||||
|
||||
let thead = "<tr>";
|
||||
(data.table.columns || []).forEach(col => {
|
||||
thead += `<th>${col}</th>`;
|
||||
});
|
||||
thead += "</tr>";
|
||||
document.getElementById("thead").innerHTML = thead;
|
||||
|
||||
(data.table.data || []).forEach(row => {
|
||||
|
||||
tbody += "<tr>";
|
||||
|
||||
(data.table.fields || []).forEach(field => {
|
||||
|
||||
let value = row[field] ?? "-";
|
||||
|
||||
if (field.toLowerCase().includes("biaya")) {
|
||||
let num = Number(value) || 0;
|
||||
total += num;
|
||||
value = "Rp " + num.toLocaleString();
|
||||
}
|
||||
|
||||
tbody += `<td>${value}</td>`;
|
||||
});
|
||||
|
||||
tbody += "</tr>";
|
||||
});
|
||||
|
||||
tbody += `
|
||||
<tr style="background:#f3f4f6; font-weight:600;">
|
||||
<td colspan="${data.table.columns.length - 1}" class="text-end">
|
||||
Total
|
||||
</td>
|
||||
<td>
|
||||
Rp ${total.toLocaleString()}
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
document.getElementById("tbody").innerHTML = tbody;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
document.getElementById("tbody").innerHTML =
|
||||
"<tr><td colspan='7'>Data tidak ditemukan</td></tr>";
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
loadDetail();
|
||||
|
||||
const search = document.getElementById("search");
|
||||
|
||||
if (search) {
|
||||
search.addEventListener("keyup", function () {
|
||||
const keyword = this.value.toLowerCase();
|
||||
const rows = document.querySelectorAll("#tbody tr");
|
||||
|
||||
rows.forEach(row => {
|
||||
const text = row.innerText.toLowerCase();
|
||||
row.style.display = text.includes(keyword) ? "" : "none";
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function exportDetailExcel() {
|
||||
|
||||
const table = document.querySelector(".custom-table");
|
||||
|
||||
if (!table) {
|
||||
alert("Table tidak ditemukan");
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof XLSX === "undefined") {
|
||||
alert("Library XLSX belum ter-load");
|
||||
return;
|
||||
}
|
||||
|
||||
const output = document.getElementById("output").innerText;
|
||||
const jenis = document.getElementById("jenis").innerText;
|
||||
|
||||
const tahun = new Date().getFullYear();
|
||||
|
||||
const fileName = `detail-${output}-${tahun}.xlsx`
|
||||
.replace(/\s+/g, "-");
|
||||
|
||||
const wb = XLSX.utils.book_new();
|
||||
const ws = XLSX.utils.table_to_sheet(table);
|
||||
|
||||
XLSX.utils.sheet_add_aoa(ws, [
|
||||
["Rincian Analisis"],
|
||||
[`Output: ${output}`],
|
||||
[`Jenis: ${jenis}`],
|
||||
[]
|
||||
], { origin: "A1" });
|
||||
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Detail");
|
||||
|
||||
XLSX.writeFile(wb, fileName);
|
||||
}
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
let currentPage = {};
|
||||
const rowsPerPage = 5;
|
||||
|
||||
function getQueryParam(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
function changeService(btn, jenis) {
|
||||
window.history.pushState({}, "", `/WebNew/Layanan?jenis=${jenis}`);
|
||||
|
||||
document.querySelectorAll('.service-btn').forEach(b => b.classList.remove('active'));
|
||||
if (btn) btn.classList.add('active');
|
||||
|
||||
loadData(jenis);
|
||||
}
|
||||
|
||||
function loadData(jenis) {
|
||||
|
||||
if (!jenis) jenis = "air";
|
||||
|
||||
document.getElementById("judul").innerText = "Loading...";
|
||||
|
||||
fetch(`/WebNew/Layanan/GetData?jenis=${encodeURIComponent(jenis)}`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
// Informasi layanan
|
||||
document.getElementById("judul").innerText =
|
||||
data.judul || "-";
|
||||
|
||||
document.getElementById("gambar").src =
|
||||
data.gambar || "";
|
||||
|
||||
document.getElementById("deskripsi-singkat").innerText =
|
||||
data["deskripsi-singkat"] || "";
|
||||
|
||||
// Deskripsi list
|
||||
let desc = "";
|
||||
|
||||
(data.deskripsi || []).forEach(d => {
|
||||
desc += `<li>${d}</li>`;
|
||||
});
|
||||
|
||||
document.getElementById("deskripsi").innerHTML = desc;
|
||||
|
||||
|
||||
const judulTable1 =
|
||||
document.getElementById("judul-table1");
|
||||
|
||||
const judulTable2 =
|
||||
document.getElementById("judul-table2");
|
||||
|
||||
if (judulTable1) {
|
||||
judulTable1.innerText =
|
||||
data.judulTable1 || "Info Harga Baku Mutu";
|
||||
}
|
||||
|
||||
if (judulTable2) {
|
||||
judulTable2.innerText =
|
||||
data.judulTable2 || "Info Harga Per Parameter";
|
||||
}
|
||||
|
||||
renderTable("table1", data.table1);
|
||||
renderTable("table2", data.table2);
|
||||
|
||||
setupPagination("table1");
|
||||
setupPagination("table2");
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
console.error(error);
|
||||
|
||||
document.getElementById("judul").innerText =
|
||||
"Data tidak ditemukan";
|
||||
});
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
let jenis = getQueryParam("jenis") || "air";
|
||||
|
||||
loadData(jenis);
|
||||
|
||||
document.querySelectorAll('.service-btn').forEach(btn => {
|
||||
btn.classList.toggle('active', btn.dataset.jenis === jenis);
|
||||
});
|
||||
|
||||
setupSearch("searchTable-harga", "table1");
|
||||
setupSearch("searchTable-parameter", "table2");
|
||||
});
|
||||
|
||||
function renderTable(tableId, tableData) {
|
||||
|
||||
if (!tableData) return;
|
||||
|
||||
let thead = "<tr>";
|
||||
(tableData.columns || []).forEach(col => {
|
||||
thead += `<th>${col}</th>`;
|
||||
});
|
||||
thead += "</tr>";
|
||||
|
||||
document.querySelector(`#${tableId} thead`).innerHTML = thead;
|
||||
|
||||
let tbody = "";
|
||||
|
||||
(tableData.data || []).forEach(row => {
|
||||
tbody += "<tr>";
|
||||
|
||||
(tableData.fields || []).forEach(field => {
|
||||
let value = row[field] ?? "-";
|
||||
|
||||
if (typeof value === "number" && field.toLowerCase().includes("harga")) {
|
||||
value = "Rp " + value.toLocaleString();
|
||||
}
|
||||
|
||||
if (field === "aksi") {
|
||||
value = `
|
||||
<a href="/WebNew/Layanan/DetailItem?kode=${row.kode}"
|
||||
class="btn btn-sm btn-primary rounded-pill">
|
||||
Detail
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
tbody += `<td>${value}</td>`;
|
||||
});
|
||||
|
||||
tbody += "</tr>";
|
||||
});
|
||||
|
||||
document.querySelector(`#${tableId} tbody`).innerHTML = tbody;
|
||||
}
|
||||
|
||||
function setupPagination(tableId) {
|
||||
|
||||
const rows = Array.from(document.querySelectorAll(`#${tableId} tbody tr`))
|
||||
.filter(row => row.style.display !== "none");
|
||||
|
||||
let container = document.getElementById(`pagination-${tableId}`);
|
||||
|
||||
if (!container) {
|
||||
container = document.createElement("div");
|
||||
container.id = `pagination-${tableId}`;
|
||||
container.className = "pagination-wrapper";
|
||||
|
||||
document.querySelector(`#${tableId}`).parentElement.appendChild(container);
|
||||
}
|
||||
|
||||
const totalRows = rows.length;
|
||||
const totalPages = Math.ceil(totalRows / rowsPerPage) || 1;
|
||||
|
||||
let page = 1;
|
||||
|
||||
function showPage(p) {
|
||||
|
||||
page = p;
|
||||
|
||||
rows.forEach((row, i) => {
|
||||
row.style.display =
|
||||
i >= (p - 1) * rowsPerPage &&
|
||||
i < p * rowsPerPage
|
||||
? ""
|
||||
: "none";
|
||||
});
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
container.innerHTML = "";
|
||||
|
||||
const start = totalRows === 0
|
||||
? 0
|
||||
: (page - 1) * rowsPerPage + 1;
|
||||
|
||||
const end = Math.min(page * rowsPerPage, totalRows);
|
||||
|
||||
const info = document.createElement("div");
|
||||
info.className = "pagination-info";
|
||||
info.innerText = `Showing ${start}-${end} of ${totalRows}`;
|
||||
|
||||
const controls = document.createElement("div");
|
||||
controls.className = "pagination-controls";
|
||||
|
||||
// Tombol Previous
|
||||
const prev = document.createElement("button");
|
||||
prev.innerHTML = '<i class="bi bi-chevron-left"></i>';
|
||||
prev.className = "page-btn" + (page === 1 ? " disabled" : "");
|
||||
prev.disabled = page === 1;
|
||||
prev.onclick = () => showPage(page - 1);
|
||||
|
||||
controls.appendChild(prev);
|
||||
|
||||
let pages = [];
|
||||
|
||||
if (totalPages <= 5) {
|
||||
pages = [...Array(totalPages).keys()].map(i => i + 1);
|
||||
} else {
|
||||
|
||||
pages = [1];
|
||||
|
||||
if (page > 3)
|
||||
pages.push("...");
|
||||
|
||||
for (
|
||||
let i = Math.max(2, page - 1);
|
||||
i <= Math.min(totalPages - 1, page + 1);
|
||||
i++
|
||||
) {
|
||||
pages.push(i);
|
||||
}
|
||||
|
||||
if (page < totalPages - 2)
|
||||
pages.push("...");
|
||||
|
||||
pages.push(totalPages);
|
||||
}
|
||||
|
||||
pages.forEach(p => {
|
||||
|
||||
const btn = document.createElement("button");
|
||||
|
||||
if (p === "...") {
|
||||
|
||||
btn.innerText = "...";
|
||||
btn.className = "page-btn disabled";
|
||||
btn.disabled = true;
|
||||
|
||||
} else {
|
||||
|
||||
btn.innerText = p;
|
||||
btn.className = "page-btn" + (p === page ? " active" : "");
|
||||
btn.onclick = () => showPage(p);
|
||||
|
||||
}
|
||||
|
||||
controls.appendChild(btn);
|
||||
});
|
||||
|
||||
// Tombol Next
|
||||
const next = document.createElement("button");
|
||||
next.innerHTML = '<i class="bi bi-chevron-right"></i>';
|
||||
next.className = "page-btn" + (page === totalPages ? " disabled" : "");
|
||||
next.disabled = page === totalPages;
|
||||
next.onclick = () => showPage(page + 1);
|
||||
|
||||
controls.appendChild(next);
|
||||
|
||||
container.appendChild(info);
|
||||
container.appendChild(controls);
|
||||
}
|
||||
|
||||
showPage(1);
|
||||
}
|
||||
|
||||
function setupSearch(inputId, tableId) {
|
||||
|
||||
const input = document.getElementById(inputId);
|
||||
|
||||
input.addEventListener("keyup", function () {
|
||||
const keyword = input.value.toLowerCase();
|
||||
const rows = document.querySelectorAll(`#${tableId} tbody tr`);
|
||||
|
||||
rows.forEach(row => {
|
||||
const text = row.innerText.toLowerCase();
|
||||
row.style.display = text.includes(keyword) ? "" : "none";
|
||||
});
|
||||
|
||||
setupPagination(tableId);
|
||||
});
|
||||
}
|
||||
|
||||
function exportTableToExcel(tableId) {
|
||||
|
||||
const table = document.getElementById(tableId);
|
||||
|
||||
if (!table || typeof XLSX === "undefined") {
|
||||
alert("Export gagal");
|
||||
return;
|
||||
}
|
||||
|
||||
let jenis = getQueryParam("jenis") || "data";
|
||||
const tahun = new Date().getFullYear();
|
||||
|
||||
jenis = jenis.toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
const fileName = `${jenis}-${tableId}-${tahun}.xlsx`;
|
||||
|
||||
const wb = XLSX.utils.book_new();
|
||||
const ws = XLSX.utils.table_to_sheet(table);
|
||||
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Data");
|
||||
|
||||
XLSX.writeFile(wb, fileName);
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
function getQueryParam(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
const jenis = getQueryParam("jenis");
|
||||
|
||||
if (jenis) {
|
||||
fetch(`/WebNew/Layanan/GetData?jenis=${jenis}`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
document.getElementById("content").innerHTML = `
|
||||
<div class="container mt-5">
|
||||
<h2>${data.judul}</h2>
|
||||
<ul>
|
||||
${data.deskripsi.map(d => `<li>${d}</li>`).join("")}
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
let allData = [];
|
||||
let filteredData = [];
|
||||
let currentKategori = "peraturan";
|
||||
let currentPage = 1;
|
||||
const perPage = 10;
|
||||
|
||||
function formatTanggal(dateStr) {
|
||||
return new Date(dateStr).toLocaleDateString("id-ID", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
}
|
||||
|
||||
function loadRegulasi() {
|
||||
fetch('/WebNew/Regulasi/GetRegulasi')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
allData = data;
|
||||
filterData();
|
||||
});
|
||||
}
|
||||
|
||||
function filterData() {
|
||||
const keyword = document.getElementById("search").value.toLowerCase();
|
||||
const tahun = document.getElementById("tahun").value;
|
||||
|
||||
filteredData = allData.filter(item => {
|
||||
const kategori = (item.kategori || "").trim().toLowerCase();
|
||||
const judul = (item.judul || "").toLowerCase();
|
||||
|
||||
return (
|
||||
kategori === currentKategori &&
|
||||
judul.includes(keyword) &&
|
||||
(tahun === "" || item.tahun == tahun)
|
||||
);
|
||||
});
|
||||
|
||||
currentPage = 1;
|
||||
renderPagination();
|
||||
}
|
||||
|
||||
function renderPagination() {
|
||||
const start = (currentPage - 1) * perPage;
|
||||
const end = start + perPage;
|
||||
|
||||
const paginatedData = filteredData.slice(start, end);
|
||||
|
||||
renderData(paginatedData);
|
||||
renderPaginationControls();
|
||||
renderPaginationInfo(start, end);
|
||||
}
|
||||
|
||||
function renderData(data) {
|
||||
|
||||
let html = "";
|
||||
|
||||
if (data.length === 0) {
|
||||
html = `
|
||||
<p class="text-muted text-center">
|
||||
Data tidak ditemukan
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
|
||||
data.forEach((item, index) => {
|
||||
|
||||
let lampiranHtml = "";
|
||||
|
||||
if (item.lampiran && item.lampiran.length > 0) {
|
||||
|
||||
item.lampiran.forEach(l => {
|
||||
|
||||
lampiranHtml += `
|
||||
<div class="lampiran-item">
|
||||
|
||||
<span>
|
||||
<i class="bi bi-paperclip"></i>
|
||||
${l.judul}
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<a href="${l.file}"
|
||||
target="_blank"
|
||||
class="btn btn-light btn-sm me-2">
|
||||
|
||||
Lihat
|
||||
|
||||
</a>
|
||||
|
||||
<a href="${l.file}"
|
||||
download
|
||||
class="btn btn-primary btn-sm">
|
||||
|
||||
Unduh
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `
|
||||
|
||||
<div class="card regulasi-card mb-3">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap gap-3">
|
||||
|
||||
<div class="d-flex align-items-center regulasi-toggle"
|
||||
${item.lampiran?.length > 0
|
||||
? `data-bs-toggle="collapse"
|
||||
data-bs-target="#lampiran-${index}"`
|
||||
: ""}>
|
||||
|
||||
<div class="me-3">
|
||||
<i class="bi bi-file-earmark-pdf fs-2 text-primary file-icon"></i>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<h6 class="mb-1">
|
||||
${item.judul}
|
||||
</h6>
|
||||
|
||||
<small class="text-muted">
|
||||
${formatTanggal(item.tanggal)}
|
||||
|
|
||||
Diunduh ${item.download} kali
|
||||
</small>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
|
||||
<a href="${item.file}"
|
||||
target="_blank"
|
||||
class="btn btn-light btn-sm">
|
||||
|
||||
Lihat
|
||||
|
||||
</a>
|
||||
|
||||
<a href="${item.file}"
|
||||
download
|
||||
class="btn btn-primary btn-sm">
|
||||
|
||||
Unduh
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
${item.lampiran?.length > 0
|
||||
? `
|
||||
<button
|
||||
class="btn btn-outline-primary btn-sm btn-lampiran collapsed"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#lampiran-${index}">
|
||||
|
||||
<i class="bi bi-chevron-down"></i>
|
||||
|
||||
</button>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
${item.lampiran?.length > 0
|
||||
? `
|
||||
<div class="collapse mt-3"
|
||||
id="lampiran-${index}">
|
||||
|
||||
${lampiranHtml}
|
||||
|
||||
</div>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("list-regulasi").innerHTML = html;
|
||||
}
|
||||
|
||||
function renderPaginationControls() {
|
||||
|
||||
const totalPages = Math.ceil(filteredData.length / perPage);
|
||||
|
||||
let html = "";
|
||||
|
||||
if (totalPages === 0) {
|
||||
document.getElementById("pagination").innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
html += `
|
||||
<button class="btn btn-sm btn-outline-primary me-1"
|
||||
${currentPage === 1 ? "disabled" : ""}
|
||||
onclick="changePage(${currentPage - 1})">
|
||||
<i class="bi bi-chevron-left"></i>
|
||||
</button>
|
||||
`;
|
||||
|
||||
for (let i = 1; i <= totalPages; i++) {
|
||||
html += `
|
||||
<button
|
||||
class="btn btn-sm ${i === currentPage ? "btn-primary" : "btn-outline-primary"} mx-1"
|
||||
onclick="changePage(${i})">
|
||||
${i}
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
html += `
|
||||
<button class="btn btn-sm btn-outline-primary ms-1"
|
||||
${currentPage === totalPages ? "disabled" : ""}
|
||||
onclick="changePage(${currentPage + 1})">
|
||||
<i class="bi bi-chevron-right"></i>
|
||||
</button>
|
||||
`;
|
||||
|
||||
document.getElementById("pagination").innerHTML = html;
|
||||
}
|
||||
|
||||
function renderPaginationInfo(start, end) {
|
||||
const total = filteredData.length;
|
||||
|
||||
if (total === 0) {
|
||||
document.getElementById("pagination-info").innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
const from = start + 1;
|
||||
const to = Math.min(end, total);
|
||||
|
||||
document.getElementById("pagination-info").innerHTML =
|
||||
`Show ${from}–${to} of ${total} data`;
|
||||
}
|
||||
|
||||
window.changePage = function (page) {
|
||||
currentPage = page;
|
||||
renderPagination();
|
||||
window.scrollTo({ top: 300, behavior: "smooth" });
|
||||
};
|
||||
|
||||
document.querySelectorAll(".filter-btn").forEach(btn => {
|
||||
btn.addEventListener("click", function () {
|
||||
document.querySelectorAll(".filter-btn").forEach(b => b.classList.remove("active"));
|
||||
this.classList.add("active");
|
||||
currentKategori = this.dataset.kategori;
|
||||
filterData();
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("search").addEventListener("keyup", filterData);
|
||||
document.getElementById("tahun").addEventListener("change", filterData);
|
||||
|
||||
loadRegulasi();
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
function loadVideo() {
|
||||
|
||||
fetch('/WebNew/Video/GetAll')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(item => {
|
||||
html += `
|
||||
<div class="col-md-4">
|
||||
<div class="youtube-wrapper">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/${item.youtube}"
|
||||
title="${item.judul}"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
1 </div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("video-list").innerHTML = html;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function openVideo(url) {
|
||||
document.getElementById("videoFrame").src = url;
|
||||
document.getElementById("videoModal").style.display = "flex";
|
||||
}
|
||||
|
||||
function closeVideo() {
|
||||
document.getElementById("videoFrame").src = "";
|
||||
document.getElementById("videoModal").style.display = "none";
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadVideo);
|
||||
Loading…
Reference in New Issue