2025-09-16 08:29:07 +00:00
|
|
|
|
"use client";
|
|
|
|
|
|
|
2025-10-31 16:21:05 +00:00
|
|
|
|
import { useState, useEffect } from "react";
|
2025-09-16 08:29:07 +00:00
|
|
|
|
import { format } from "date-fns";
|
|
|
|
|
|
import { Calendar } from "@/components/ui/calendar";
|
|
|
|
|
|
import {
|
|
|
|
|
|
Popover,
|
|
|
|
|
|
PopoverContent,
|
|
|
|
|
|
PopoverTrigger,
|
|
|
|
|
|
} from "@/components/ui/popover";
|
|
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
|
|
import { Input } from "@/components/ui/input";
|
|
|
|
|
|
import { CalendarIcon, ChevronRight } from "lucide-react";
|
|
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
|
import {
|
|
|
|
|
|
Select,
|
|
|
|
|
|
SelectTrigger,
|
|
|
|
|
|
SelectValue,
|
|
|
|
|
|
SelectContent,
|
|
|
|
|
|
SelectItem,
|
|
|
|
|
|
} from "@/components/ui/select";
|
|
|
|
|
|
import { Badge } from "@/components/ui/badge";
|
2025-10-31 16:21:05 +00:00
|
|
|
|
import { getAllSchedules } from "@/service/landing/landing";
|
2025-12-11 04:45:26 +00:00
|
|
|
|
import { getPublicClients } from "@/service/client/public-clients";
|
2025-09-16 08:29:07 +00:00
|
|
|
|
|
|
|
|
|
|
export default function Schedule() {
|
|
|
|
|
|
const [search, setSearch] = useState("");
|
2025-10-31 16:21:05 +00:00
|
|
|
|
const [startDate, setStartDate] = useState<Date | undefined>(new Date());
|
|
|
|
|
|
const [endDate, setEndDate] = useState<Date | undefined>(new Date());
|
2025-09-16 08:29:07 +00:00
|
|
|
|
const [selectedCategory, setSelectedCategory] = useState("SEMUA");
|
2025-12-11 04:45:26 +00:00
|
|
|
|
const [selectedSlug, setSelectedSlug] = useState<string | undefined>(
|
|
|
|
|
|
undefined
|
|
|
|
|
|
);
|
2025-10-31 16:21:05 +00:00
|
|
|
|
const [scheduleData, setScheduleData] = useState<any[]>([]);
|
2025-12-11 04:45:26 +00:00
|
|
|
|
const [clients, setClients] = useState<any[]>([]);
|
2025-10-31 16:21:05 +00:00
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
|
|
2025-12-11 04:45:26 +00:00
|
|
|
|
// 🔹 Fetch daftar client
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
async function fetchClients() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await getPublicClients();
|
|
|
|
|
|
if (res?.data?.success && res.data.data) {
|
|
|
|
|
|
setClients(res.data.data);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
setClients([]);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("Error fetching clients:", error);
|
|
|
|
|
|
setClients([]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
fetchClients();
|
|
|
|
|
|
}, []);
|
2025-10-31 16:21:05 +00:00
|
|
|
|
|
2025-12-11 04:45:26 +00:00
|
|
|
|
// 🔹 Fetch jadwal dari API (termasuk clientSlug)
|
2025-10-31 16:21:05 +00:00
|
|
|
|
const fetchSchedules = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setLoading(true);
|
|
|
|
|
|
const params = {
|
|
|
|
|
|
title: search || undefined,
|
|
|
|
|
|
startDate: startDate ? format(startDate, "yyyy-MM-dd") : undefined,
|
|
|
|
|
|
endDate: endDate ? format(endDate, "yyyy-MM-dd") : undefined,
|
2025-12-11 04:45:26 +00:00
|
|
|
|
clientSlug: selectedSlug, // 🔥 Tambahkan clientSlug untuk filter
|
2025-10-31 16:21:05 +00:00
|
|
|
|
page: 1,
|
|
|
|
|
|
limit: 50,
|
|
|
|
|
|
sortBy: "startDate",
|
|
|
|
|
|
sort: "asc",
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const res = await getAllSchedules(params);
|
|
|
|
|
|
|
|
|
|
|
|
if (!res.error) {
|
|
|
|
|
|
const apiData = Array.isArray(res.data)
|
|
|
|
|
|
? res.data
|
|
|
|
|
|
: Array.isArray(res.data?.data)
|
|
|
|
|
|
? res.data.data
|
|
|
|
|
|
: Array.isArray(res.data?.records)
|
|
|
|
|
|
? res.data.records
|
|
|
|
|
|
: [];
|
|
|
|
|
|
setScheduleData(apiData);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.error("Gagal memuat jadwal:", res.message);
|
|
|
|
|
|
setScheduleData([]);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("Error fetching schedules:", error);
|
|
|
|
|
|
setScheduleData([]);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-12-11 04:45:26 +00:00
|
|
|
|
// 🔹 Re-fetch setiap kali filter berubah
|
2025-10-31 16:21:05 +00:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
fetchSchedules();
|
2025-12-11 04:45:26 +00:00
|
|
|
|
}, [startDate, endDate, search, selectedSlug]);
|
2025-09-16 08:29:07 +00:00
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="p-6 max-w-[1350px] mx-auto">
|
|
|
|
|
|
{/* Filter Bar */}
|
|
|
|
|
|
<div className="flex flex-wrap gap-4 items-center mb-6">
|
|
|
|
|
|
<Input
|
|
|
|
|
|
placeholder="Pencarian"
|
|
|
|
|
|
className="w-70 mt-7"
|
|
|
|
|
|
value={search}
|
|
|
|
|
|
onChange={(e) => setSearch(e.target.value)}
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Tanggal Mulai */}
|
|
|
|
|
|
<div className="flex flex-col gap-2">
|
|
|
|
|
|
<label className="text-sm font-medium">Tanggal Mulai</label>
|
|
|
|
|
|
<Popover>
|
|
|
|
|
|
<PopoverTrigger asChild>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant="outline"
|
|
|
|
|
|
className="w-[160px] justify-start text-left"
|
|
|
|
|
|
>
|
|
|
|
|
|
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
|
|
|
|
{startDate ? format(startDate, "dd MMM yyyy") : "Pilih"}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</PopoverTrigger>
|
|
|
|
|
|
<PopoverContent className="w-auto p-0">
|
|
|
|
|
|
<Calendar
|
|
|
|
|
|
mode="single"
|
|
|
|
|
|
selected={startDate}
|
|
|
|
|
|
onSelect={setStartDate}
|
|
|
|
|
|
initialFocus
|
|
|
|
|
|
/>
|
|
|
|
|
|
</PopoverContent>
|
|
|
|
|
|
</Popover>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Tanggal Selesai */}
|
|
|
|
|
|
<div className="flex flex-col gap-2">
|
|
|
|
|
|
<label className="text-sm font-medium">Tanggal Selesai</label>
|
|
|
|
|
|
<Popover>
|
|
|
|
|
|
<PopoverTrigger asChild>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant="outline"
|
|
|
|
|
|
className="w-[160px] justify-start text-left"
|
|
|
|
|
|
>
|
|
|
|
|
|
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
|
|
|
|
{endDate ? format(endDate, "dd MMM yyyy") : "Pilih"}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</PopoverTrigger>
|
|
|
|
|
|
<PopoverContent className="w-auto p-0">
|
|
|
|
|
|
<Calendar
|
|
|
|
|
|
mode="single"
|
|
|
|
|
|
selected={endDate}
|
|
|
|
|
|
onSelect={setEndDate}
|
|
|
|
|
|
initialFocus
|
|
|
|
|
|
/>
|
|
|
|
|
|
</PopoverContent>
|
|
|
|
|
|
</Popover>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-12-11 04:45:26 +00:00
|
|
|
|
{/* 🔹 Dynamic Category dari API */}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<div className="flex w-full gap-5 overflow-x-auto pb-2 border-b border-[#C6A455] mb-6">
|
2025-12-11 04:45:26 +00:00
|
|
|
|
<Button
|
|
|
|
|
|
key="SEMUA"
|
|
|
|
|
|
variant={selectedCategory === "SEMUA" ? "default" : "outline"}
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"rounded-sm whitespace-nowrap",
|
|
|
|
|
|
selectedCategory === "SEMUA" && "bg-[#C6A455] text-white"
|
|
|
|
|
|
)}
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setSelectedCategory("SEMUA");
|
|
|
|
|
|
setSelectedSlug(undefined); // reset filter
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
SEMUA
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
|
|
{clients.map((client) => (
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<Button
|
2025-12-11 04:45:26 +00:00
|
|
|
|
key={client.slug || client.name}
|
|
|
|
|
|
variant={
|
|
|
|
|
|
selectedCategory === client.name.toUpperCase()
|
|
|
|
|
|
? "default"
|
|
|
|
|
|
: "outline"
|
|
|
|
|
|
}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
className={cn(
|
2025-12-11 04:45:26 +00:00
|
|
|
|
"rounded-sm whitespace-nowrap flex items-center gap-2",
|
|
|
|
|
|
selectedCategory === client.name.toUpperCase() &&
|
|
|
|
|
|
"bg-[#C6A455] text-white"
|
2025-09-16 08:29:07 +00:00
|
|
|
|
)}
|
2025-12-11 04:45:26 +00:00
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setSelectedCategory(client.name.toUpperCase());
|
|
|
|
|
|
setSelectedSlug(client.slug); // 🔥 Set slug untuk filter API
|
|
|
|
|
|
}}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
>
|
2025-12-11 04:45:26 +00:00
|
|
|
|
{client.logoUrl && (
|
|
|
|
|
|
<img
|
|
|
|
|
|
src={client.logoUrl}
|
|
|
|
|
|
alt={client.name}
|
|
|
|
|
|
className="w-5 h-5 rounded"
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
{client.name}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
</Button>
|
|
|
|
|
|
))}
|
2025-12-11 04:45:26 +00:00
|
|
|
|
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<Button variant="ghost">
|
|
|
|
|
|
<ChevronRight className="w-5 h-5" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Schedule Table */}
|
|
|
|
|
|
<h2 className="text-md font-semibold text-muted-foreground mb-4">
|
|
|
|
|
|
Semua Jadwal
|
|
|
|
|
|
</h2>
|
2025-10-31 16:21:05 +00:00
|
|
|
|
|
|
|
|
|
|
{loading ? (
|
|
|
|
|
|
<div className="text-center text-muted-foreground py-10">
|
|
|
|
|
|
Memuat data jadwal...
|
|
|
|
|
|
</div>
|
2025-12-11 04:45:26 +00:00
|
|
|
|
) : scheduleData.length === 0 ? (
|
2025-10-31 16:21:05 +00:00
|
|
|
|
<div className="text-center text-muted-foreground py-10">
|
|
|
|
|
|
Tidak ada jadwal ditemukan.
|
|
|
|
|
|
</div>
|
|
|
|
|
|
) : (
|
2025-12-11 04:45:26 +00:00
|
|
|
|
<div className="flex flex-col gap-3 justify-between">
|
|
|
|
|
|
{scheduleData.map((item, index) => (
|
2025-10-31 16:21:05 +00:00
|
|
|
|
<div
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
className="flex justify-between items-start border-b pb-2"
|
|
|
|
|
|
>
|
2025-12-11 04:45:26 +00:00
|
|
|
|
<div className="w-2/5">
|
|
|
|
|
|
{item.startDate ? (
|
|
|
|
|
|
<>
|
|
|
|
|
|
{format(new Date(item.startDate), "dd MMM yyyy")}
|
|
|
|
|
|
{item.endDate &&
|
|
|
|
|
|
item.endDate !== item.startDate &&
|
|
|
|
|
|
` — ${format(new Date(item.endDate), "dd MMM yyyy")}`}
|
|
|
|
|
|
</>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
"-"
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="w-2/5 text-xs text-gray-400 mt-0.5">
|
|
|
|
|
|
{item.startTime && item.endTime ? (
|
|
|
|
|
|
<>
|
|
|
|
|
|
{item.startTime.slice(0, 5)} – {item.endTime.slice(0, 5)}
|
|
|
|
|
|
</>
|
|
|
|
|
|
) : item.startTime ? (
|
|
|
|
|
|
item.startTime.slice(0, 5)
|
|
|
|
|
|
) : (
|
|
|
|
|
|
""
|
|
|
|
|
|
)}
|
2025-10-31 16:21:05 +00:00
|
|
|
|
</div>
|
2025-12-11 04:45:26 +00:00
|
|
|
|
|
|
|
|
|
|
{/* Client */}
|
2025-10-31 16:21:05 +00:00
|
|
|
|
<div className="w-1/5">
|
2025-12-11 04:45:26 +00:00
|
|
|
|
<Badge className="bg-[#C6A455] text-white">
|
|
|
|
|
|
{item.clientName || "-"}
|
2025-10-31 16:21:05 +00:00
|
|
|
|
</Badge>
|
|
|
|
|
|
</div>
|
2025-12-11 04:45:26 +00:00
|
|
|
|
|
|
|
|
|
|
{/* Judul & Lokasi */}
|
|
|
|
|
|
<div className="w-2/5">{item.title}</div>
|
|
|
|
|
|
<div className="w-1/3 text-muted-foreground">{item.location}</div>
|
2025-09-16 08:29:07 +00:00
|
|
|
|
</div>
|
2025-10-31 16:21:05 +00:00
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<div className="flex justify-between mt-6 text-sm text-blue-600">
|
|
|
|
|
|
<button>Preview</button>
|
|
|
|
|
|
<button>Next</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2025-10-31 16:21:05 +00:00
|
|
|
|
|
|
|
|
|
|
// "use client";
|
|
|
|
|
|
|
|
|
|
|
|
// import { useState } from "react";
|
|
|
|
|
|
// import { format } from "date-fns";
|
|
|
|
|
|
// import { Calendar } from "@/components/ui/calendar";
|
|
|
|
|
|
// import {
|
|
|
|
|
|
// Popover,
|
|
|
|
|
|
// PopoverContent,
|
|
|
|
|
|
// PopoverTrigger,
|
|
|
|
|
|
// } from "@/components/ui/popover";
|
|
|
|
|
|
// import { Button } from "@/components/ui/button";
|
|
|
|
|
|
// import { Input } from "@/components/ui/input";
|
|
|
|
|
|
// import { CalendarIcon, ChevronRight } from "lucide-react";
|
|
|
|
|
|
// import { cn } from "@/lib/utils";
|
|
|
|
|
|
// import {
|
|
|
|
|
|
// Select,
|
|
|
|
|
|
// SelectTrigger,
|
|
|
|
|
|
// SelectValue,
|
|
|
|
|
|
// SelectContent,
|
|
|
|
|
|
// SelectItem,
|
|
|
|
|
|
// } from "@/components/ui/select";
|
|
|
|
|
|
// import { Badge } from "@/components/ui/badge";
|
|
|
|
|
|
|
|
|
|
|
|
// const scheduleData = [
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "POLRI",
|
|
|
|
|
|
// title: "HUT Bhayangkara RI - 79",
|
|
|
|
|
|
// location: "Mabes Polri, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "POLRI",
|
|
|
|
|
|
// title: "Hari Lahir Pancasila",
|
|
|
|
|
|
// location: "Mabes Polri, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "POLRI",
|
|
|
|
|
|
// title: "Pers Rilis Kasus",
|
|
|
|
|
|
// location: "Mabes Polri, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "POLRI",
|
|
|
|
|
|
// title: "Rapat Koordinasi HUT Bhayangkara RI - 79",
|
|
|
|
|
|
// location: "Mabes Polri, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "MPR",
|
|
|
|
|
|
// title: "Rapat PIMPINAN MPR RI",
|
|
|
|
|
|
// location: "Gedung MPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "DPR",
|
|
|
|
|
|
// title: "Rapat Anggota Komisi I",
|
|
|
|
|
|
// location: "Gedung DPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "MPR",
|
|
|
|
|
|
// title: "Sidang Paripurna",
|
|
|
|
|
|
// location: "Gedung MPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "KEJAKSAAN AGUNG",
|
|
|
|
|
|
// title: "Hari Lahir Pancasila",
|
|
|
|
|
|
// location: "Kejaksaan Agung, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "KPU",
|
|
|
|
|
|
// title: "Hari Lahir Pancasila",
|
|
|
|
|
|
// location: "Kantor KPU, Jakarta Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "DPR",
|
|
|
|
|
|
// title: "Rapat Anggota Komisi II",
|
|
|
|
|
|
// location: "Gedung DPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "MPR",
|
|
|
|
|
|
// title: "Rapat DPR dan Basarnas",
|
|
|
|
|
|
// location: "Gedung MPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "BUMN",
|
|
|
|
|
|
// title: "Hari Lahir Pancasila",
|
|
|
|
|
|
// location: "Kantor BUMN, Jakarta Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "BUMN",
|
|
|
|
|
|
// title: "Focus Group Discussion",
|
|
|
|
|
|
// location: "Kantor BUMN, Jakarta Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "MPR",
|
|
|
|
|
|
// title: "Rapat Anggota MPR RI",
|
|
|
|
|
|
// location: "Gedung MPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "BUMN",
|
|
|
|
|
|
// title: "Seremoni Sinergi BUMN",
|
|
|
|
|
|
// location: "Kantor BUMN, Jakarta Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "MPR",
|
|
|
|
|
|
// title: "Sumpah Janji Anggota MPR RI",
|
|
|
|
|
|
// location: "Gedung MPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "KPK",
|
|
|
|
|
|
// title: "Hari Lahir Pancasila",
|
|
|
|
|
|
// location: "Kantor KPK, Jakarta Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "BUMN",
|
|
|
|
|
|
// title: "Monitoring dan Evaluasi Keterbukaan Informasi Publik Tahun 2025",
|
|
|
|
|
|
// location: "Kantor BUMN, Jakarta Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 1 2025",
|
|
|
|
|
|
// type: "KEJAKSAAN AGUNG",
|
|
|
|
|
|
// title: "Hari Lahir Pancasila",
|
|
|
|
|
|
// location: "Kejaksaan Agung, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// date: "Jul 2 2025",
|
|
|
|
|
|
// type: "MPR",
|
|
|
|
|
|
// title: "Monitoring dan Evaluasi Informasi MPR Tahun 2025",
|
|
|
|
|
|
// location: "Gedung MPR, Jakarta, Indonesia",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// ];
|
|
|
|
|
|
|
|
|
|
|
|
// const categories = [
|
|
|
|
|
|
// "SEMUA",
|
|
|
|
|
|
// "POLRI",
|
|
|
|
|
|
// "MAHKAMAH AGUNG",
|
|
|
|
|
|
// "DPR",
|
|
|
|
|
|
// "MPR",
|
|
|
|
|
|
// "KEJAKSAAN AGUNG",
|
|
|
|
|
|
// "KPK",
|
|
|
|
|
|
// "PUPR",
|
|
|
|
|
|
// "BSKDN",
|
|
|
|
|
|
// "BUMN",
|
|
|
|
|
|
// "KPU",
|
|
|
|
|
|
// ];
|
|
|
|
|
|
|
|
|
|
|
|
// export default function Schedule() {
|
|
|
|
|
|
// const [search, setSearch] = useState("");
|
|
|
|
|
|
// const [startDate, setStartDate] = useState<Date | undefined>(
|
|
|
|
|
|
// new Date("2025-07-01")
|
|
|
|
|
|
// );
|
|
|
|
|
|
// const [endDate, setEndDate] = useState<Date | undefined>(
|
|
|
|
|
|
// new Date("2025-07-30")
|
|
|
|
|
|
// );
|
|
|
|
|
|
// const [selectedCategory, setSelectedCategory] = useState("SEMUA");
|
|
|
|
|
|
|
|
|
|
|
|
// const filteredData = scheduleData.filter((item) => {
|
|
|
|
|
|
// const matchesCategory =
|
|
|
|
|
|
// selectedCategory === "SEMUA" || item.type === selectedCategory;
|
|
|
|
|
|
// const matchesSearch = item.title
|
|
|
|
|
|
// .toLowerCase()
|
|
|
|
|
|
// .includes(search.toLowerCase());
|
|
|
|
|
|
// return matchesCategory && matchesSearch;
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// return (
|
|
|
|
|
|
// <div className="p-6 max-w-[1350px] mx-auto">
|
|
|
|
|
|
// {/* Filter Bar */}
|
|
|
|
|
|
// <div className="flex flex-wrap gap-4 items-center mb-6">
|
|
|
|
|
|
// <Input
|
|
|
|
|
|
// placeholder="Pencarian"
|
|
|
|
|
|
// className="w-70 mt-7"
|
|
|
|
|
|
// value={search}
|
|
|
|
|
|
// onChange={(e) => setSearch(e.target.value)}
|
|
|
|
|
|
// />
|
|
|
|
|
|
|
|
|
|
|
|
// {/* Tanggal Mulai */}
|
|
|
|
|
|
// <div className="flex flex-col gap-2">
|
|
|
|
|
|
// <label className="text-sm font-medium">Tanggal Mulai</label>
|
|
|
|
|
|
// <Popover>
|
|
|
|
|
|
// <PopoverTrigger asChild>
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// variant="outline"
|
|
|
|
|
|
// className="w-[160px] justify-start text-left"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <CalendarIcon className="mr-2 h-4 w-4" />
|
|
|
|
|
|
// {startDate ? format(startDate, "dd MMM yyyy") : "Pilih"}
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// </PopoverTrigger>
|
|
|
|
|
|
// <PopoverContent className="w-auto p-0">
|
|
|
|
|
|
// <Calendar
|
|
|
|
|
|
// mode="single"
|
|
|
|
|
|
// selected={startDate}
|
|
|
|
|
|
// onSelect={setStartDate}
|
|
|
|
|
|
// initialFocus
|
|
|
|
|
|
// />
|
|
|
|
|
|
// </PopoverContent>
|
|
|
|
|
|
// </Popover>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// {/* Tanggal Selesai */}
|
|
|
|
|
|
// <div className="flex flex-col gap-2">
|
|
|
|
|
|
// <label className="text-sm font-medium">Tanggal Selesai</label>
|
|
|
|
|
|
// <Popover>
|
|
|
|
|
|
// <PopoverTrigger asChild>
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// variant="outline"
|
|
|
|
|
|
// className="w-[160px] justify-start text-left"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <CalendarIcon className="mr-2 h-4 w-4" />
|
|
|
|
|
|
// {endDate ? format(endDate, "dd MMM yyyy") : "Pilih"}
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// </PopoverTrigger>
|
|
|
|
|
|
// <PopoverContent className="w-auto p-0">
|
|
|
|
|
|
// <Calendar
|
|
|
|
|
|
// mode="single"
|
|
|
|
|
|
// selected={endDate}
|
|
|
|
|
|
// onSelect={setEndDate}
|
|
|
|
|
|
// initialFocus
|
|
|
|
|
|
// />
|
|
|
|
|
|
// </PopoverContent>
|
|
|
|
|
|
// </Popover>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// {/* Publikasi */}
|
|
|
|
|
|
// <div className="flex flex-col gap-2">
|
|
|
|
|
|
// <label className="text-sm font-medium">Publikasi</label>
|
|
|
|
|
|
// <Select>
|
|
|
|
|
|
// <SelectTrigger className="w-[150px]">
|
|
|
|
|
|
// <SelectValue placeholder="Semua" />
|
|
|
|
|
|
// </SelectTrigger>
|
|
|
|
|
|
// <SelectContent>
|
|
|
|
|
|
// <SelectItem value="semua">K/L</SelectItem>
|
|
|
|
|
|
// <SelectItem value="dipublikasikan">BUMN</SelectItem>
|
|
|
|
|
|
// <SelectItem value="belum">PEMERINTAH DAERAH</SelectItem>
|
|
|
|
|
|
// </SelectContent>
|
|
|
|
|
|
// </Select>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// {/* Filter Chips */}
|
|
|
|
|
|
// <div className="flex w-full gap-5 overflow-x-auto pb-2 border-b border-[#C6A455] mb-6">
|
|
|
|
|
|
// {categories.map((cat) => (
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// key={cat}
|
|
|
|
|
|
// variant={selectedCategory === cat ? "default" : "outline"}
|
|
|
|
|
|
// className={cn(
|
|
|
|
|
|
// "rounded-sm whitespace-nowrap",
|
|
|
|
|
|
// selectedCategory === cat && "bg-[#C6A455] text-white"
|
|
|
|
|
|
// )}
|
|
|
|
|
|
// onClick={() => setSelectedCategory(cat)}
|
|
|
|
|
|
// >
|
|
|
|
|
|
// {cat}
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// ))}
|
|
|
|
|
|
// <Button variant="ghost">
|
|
|
|
|
|
// <ChevronRight className="w-5 h-5" />
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// {/* Schedule Table */}
|
|
|
|
|
|
// <h2 className="text-md font-semibold text-muted-foreground mb-4">
|
|
|
|
|
|
// Semua Jadwal
|
|
|
|
|
|
// </h2>
|
|
|
|
|
|
// <div className="flex flex-col gap-3">
|
|
|
|
|
|
// {filteredData.map((item, index) => (
|
|
|
|
|
|
// <div
|
|
|
|
|
|
// key={index}
|
|
|
|
|
|
// className="flex justify-between items-start border-b pb-2"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <div className="w-1/6 text-sm text-muted-foreground">
|
|
|
|
|
|
// {item.date}
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// <div className="w-1/5">
|
|
|
|
|
|
// <Badge
|
|
|
|
|
|
// className={cn("text-white", {
|
|
|
|
|
|
// "bg-red-600": item.type === "POLRI",
|
|
|
|
|
|
// "bg-yellow-500": item.type === "DPR",
|
|
|
|
|
|
// "bg-green-600": item.type === "KEJAKSAAN AGUNG",
|
|
|
|
|
|
// "bg-blue-700": item.type === "BUMN",
|
|
|
|
|
|
// "bg-amber-500": item.type === "MPR",
|
|
|
|
|
|
// "bg-pink-500": item.type === "KPU",
|
|
|
|
|
|
// "bg-red-700": item.type === "KPK",
|
|
|
|
|
|
// })}
|
|
|
|
|
|
// >
|
|
|
|
|
|
// {item.type}
|
|
|
|
|
|
// </Badge>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// <div className="w-2/5 text-sm">{item.title}</div>
|
|
|
|
|
|
// <div className="w-1/3 text-sm text-muted-foreground">
|
|
|
|
|
|
// {item.location}
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// ))}
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// <div className="flex justify-between mt-6 text-sm text-blue-600">
|
|
|
|
|
|
// <button>Preview</button>
|
|
|
|
|
|
// <button>Next</button>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// );
|
|
|
|
|
|
// }
|