web-campaignpool/components/dialog/media-sosial.tsx

237 lines
7.4 KiB
TypeScript
Raw Normal View History

2025-11-11 02:52:38 +00:00
import { useState, useMemo } from "react";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { ChevronDown, ChevronUp } from "lucide-react";
export default function DialogMediaSosial({
isOpen,
onClose,
}: {
isOpen: boolean;
onClose: () => void;
}) {
const mediaPlatforms = ["X", "Instagram", "Facebook", "Youtube", "TikTok"];
const mediaPerPlatform: Record<string, string[]> = {
X: ["X Mabes", "X Polda Jawa Timur", "X Polda Jawa Barat"],
Instagram: [
"Instagram Mabes",
"Instagram Polda Jawa Timur",
"Instagram Polda Jawa Barat",
],
Facebook: [
"Facebook Mabes",
"Facebook Polda Jawa Timur",
"Facebook Polda Jawa Barat",
],
Youtube: [
"Youtube Mabes",
"Youtube Polda Jawa Timur",
"Youtube Polda Jawa Barat",
],
TikTok: [
"TikTok Mabes",
"TikTok Polda Jawa Timur",
"TikTok Polda Jawa Barat",
],
};
const [selectedMediaSosial, setSelectedMediaSosial] = useState<string[]>([]);
const [searchTerm, setSearchTerm] = useState("");
const [expanded, setExpanded] = useState<Record<string, boolean>>({});
const [selectedPlatforms, setSelectedPlatforms] = useState<string[]>([
"X",
"Instagram",
"Facebook",
"Youtube",
"TikTok",
]);
// Filter berdasarkan pencarian
const filteredPlatforms = useMemo(() => {
return mediaPlatforms.filter((p) =>
p.toLowerCase().includes(searchTerm.toLowerCase())
);
}, [searchTerm]);
// Toggle platform (misalnya centang Instagram)
const togglePlatform = (platform: string) => {
if (selectedPlatforms.includes(platform)) {
setSelectedPlatforms(selectedPlatforms.filter((p) => p !== platform));
// hapus semua media sosial di dalam platform tsb
setSelectedMediaSosial((prev) =>
prev.filter((m) => !mediaPerPlatform[platform].includes(m))
);
} else {
setSelectedPlatforms([...selectedPlatforms, platform]);
setSelectedMediaSosial((prev) => [
...prev,
...mediaPerPlatform[platform],
]);
}
};
// Toggle semua platform
const toggleSelectAll = () => {
if (selectedPlatforms.length === mediaPlatforms.length) {
setSelectedPlatforms([]);
setSelectedMediaSosial([]);
} else {
setSelectedPlatforms([...mediaPlatforms]);
setSelectedMediaSosial(Object.values(mediaPerPlatform).flat());
}
};
// Expand/collapse per platform
const toggleExpand = (platform: string) => {
setExpanded((prev) => ({ ...prev, [platform]: !prev[platform] }));
};
// Toggle media per item
const toggleMedia = (media: string) => {
setSelectedMediaSosial((prev) =>
prev.includes(media) ? prev.filter((m) => m !== media) : [...prev, media]
);
};
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="w-full max-w-3xl sm:max-h-[90vh] overflow-hidden flex flex-col">
<DialogHeader>
<DialogTitle>Pilih Media Sosial</DialogTitle>
</DialogHeader>
{/* Input Pencarian */}
<div className="relative mb-4">
<input
type="text"
placeholder="Cari Media Sosial..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-10 pr-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<svg
xmlns="http://www.w3.org/2000/svg"
className="w-4 h-4 absolute left-3 top-3 text-gray-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-4.35-4.35m0 0A7.5 7.5 0 104.5 4.5a7.5 7.5 0 0012.15 12.15z"
/>
</svg>
</div>
{/* Checkbox utama */}
<div className="flex flex-wrap gap-3 mb-3">
<label className="flex items-center gap-2 font-medium cursor-pointer">
<input
type="checkbox"
checked={selectedPlatforms.length === mediaPlatforms.length}
onChange={toggleSelectAll}
className="accent-blue-600"
/>
Semua
</label>
{filteredPlatforms.map((platform) => (
<label
key={platform}
className="flex items-center gap-2 cursor-pointer"
>
<input
type="checkbox"
checked={selectedPlatforms.includes(platform)}
onChange={() => togglePlatform(platform)}
className="accent-blue-600"
/>
{platform}
</label>
))}
</div>
{/* Expand per platform */}
<div className="flex-1 overflow-y-auto border rounded-md p-2 space-y-1">
{filteredPlatforms.map((platform) => (
<div key={platform}>
<button
onClick={() => toggleExpand(platform)}
className="flex justify-between items-center w-full p-2 font-medium hover:bg-gray-50 rounded-md"
>
<span>Pilih {platform}</span>
{expanded[platform] ? (
<ChevronUp className="w-4 h-4" />
) : (
<ChevronDown className="w-4 h-4" />
)}
</button>
{expanded[platform] && (
<div className="pl-4 grid grid-cols-1 sm:grid-cols-2 gap-2 mt-1">
{mediaPerPlatform[platform].map((media) => (
<label
key={media}
className="flex items-center gap-2 p-2 rounded-md hover:bg-gray-50 cursor-pointer"
>
<input
type="checkbox"
checked={selectedMediaSosial.includes(media)}
onChange={() => toggleMedia(media)}
className="accent-blue-600"
/>
{media}
</label>
))}
</div>
)}
</div>
))}
</div>
{/* Tag media sosial dipilih */}
{selectedMediaSosial.length > 0 && (
<div className="mt-3">
<p className="text-sm font-medium mb-2">
{selectedMediaSosial.length} Media Sosial dipilih
</p>
<div className="flex flex-wrap gap-2 max-h-[100px] overflow-y-auto border rounded-md p-2 bg-gray-50">
{selectedMediaSosial.map((m) => (
<div
key={m}
className="flex items-center gap-2 px-3 py-1 bg-white rounded-full text-sm border"
>
{m}
<button
onClick={() => toggleMedia(m)}
className="text-gray-500 hover:text-gray-700"
>
</button>
</div>
))}
</div>
</div>
)}
{/* Tombol Footer */}
<DialogFooter className="mt-4">
<Button variant="outline" onClick={onClose}>
Batal
</Button>
<Button onClick={onClose}>Pilih</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}