192 lines
5.9 KiB
TypeScript
192 lines
5.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogFooter,
|
|
DialogClose,
|
|
} from "@/components/ui/dialog";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import { UploadCloud, Check } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
import router from "next/router";
|
|
import { useRouter } from "next/navigation";
|
|
import withReactContent from "sweetalert2-react-content";
|
|
import Swal from "sweetalert2";
|
|
|
|
interface BannerDialogProps {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
onSubmit?: (data: any) => void;
|
|
onSuccess?: () => void;
|
|
}
|
|
|
|
export function BannerDialog({
|
|
open,
|
|
onOpenChange,
|
|
onSubmit,
|
|
onSuccess,
|
|
}: BannerDialogProps) {
|
|
const [selectedOrder, setSelectedOrder] = useState<number | null>(1);
|
|
const [file, setFile] = useState<File | null>(null);
|
|
const [title, setTitle] = useState("");
|
|
const router = useRouter();
|
|
const MySwal = withReactContent(Swal);
|
|
|
|
const handleFileChange = (e: any) => {
|
|
const selected = e.target.files[0];
|
|
if (selected) setFile(selected);
|
|
};
|
|
|
|
const successSubmit = () => {
|
|
MySwal.fire({
|
|
title: "Sukses",
|
|
icon: "success",
|
|
confirmButtonColor: "#3085d6",
|
|
confirmButtonText: "OK",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
router.refresh(); // ⬅️ refresh halaman
|
|
}
|
|
});
|
|
};
|
|
|
|
const handleSubmit = async () => {
|
|
if (!title || !file || !selectedOrder) return;
|
|
|
|
const formData = new FormData();
|
|
formData.append("title", title);
|
|
formData.append("position", selectedOrder.toString());
|
|
formData.append("description", "hardcode description dulu");
|
|
formData.append("status", "active");
|
|
formData.append("thumbnail_path", "path-hardcode.png");
|
|
formData.append("file", file);
|
|
|
|
if (onSubmit) {
|
|
await onSubmit(formData);
|
|
successSubmit(); // swal muncul disini
|
|
}
|
|
|
|
onOpenChange(false);
|
|
};
|
|
|
|
const orderOptions = [
|
|
{ id: 1, label: "Pertama" },
|
|
{ id: 2, label: "Kedua" },
|
|
{ id: 3, label: "Ketiga" },
|
|
{ id: 4, label: "Keempat" },
|
|
{ id: 5, label: "Kelima" },
|
|
];
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="max-w-lg p-0 overflow-hidden">
|
|
{/* Header */}
|
|
<DialogHeader className="bg-[#1F6779] px-6 py-4">
|
|
<DialogTitle className="text-white text-lg">
|
|
Tambah Banner
|
|
</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
{/* Body */}
|
|
<div className="p-6 space-y-4">
|
|
{/* Judul Banner */}
|
|
<div>
|
|
<Label className="text-gray-700">
|
|
Judul Banner <span className="text-red-500">*</span>
|
|
</Label>
|
|
<Input
|
|
placeholder="Masukkan judul banner"
|
|
className="mt-1"
|
|
value={title}
|
|
onChange={(e) => setTitle(e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
{/* Upload File */}
|
|
<div>
|
|
<Label className="text-gray-700">
|
|
Upload File <span className="text-red-500">*</span>
|
|
</Label>
|
|
<label
|
|
htmlFor="uploadFile"
|
|
className="mt-1 border-2 border-dashed border-gray-300 rounded-xl p-6 flex flex-col items-center justify-center text-gray-500 cursor-pointer hover:border-[#1F6779]/50 transition"
|
|
>
|
|
<UploadCloud className="w-10 h-10 text-[#1F6779] mb-2" />
|
|
<p className="text-sm font-medium">
|
|
Klik untuk upload atau drag & drop
|
|
</p>
|
|
<p className="text-xs text-gray-400 mt-1">PNG, JPG (max 2 MB)</p>
|
|
<input
|
|
id="uploadFile"
|
|
type="file"
|
|
accept="image/png, image/jpeg"
|
|
className="hidden"
|
|
onChange={handleFileChange}
|
|
/>
|
|
{file && (
|
|
<p className="mt-2 text-xs text-[#1F6779] font-medium">
|
|
{file.name}
|
|
</p>
|
|
)}
|
|
</label>
|
|
</div>
|
|
|
|
{/* Urutan Banner */}
|
|
<div>
|
|
<Label className="text-gray-700">
|
|
Urutan Banner <span className="text-red-500">*</span>
|
|
</Label>
|
|
<div className="grid grid-cols-5 gap-2 mt-2">
|
|
{orderOptions.map((opt) => (
|
|
<button
|
|
key={opt.id}
|
|
type="button"
|
|
onClick={() => setSelectedOrder(opt.id)}
|
|
className={cn(
|
|
"border rounded-lg py-2 flex flex-col items-center justify-center text-sm font-medium transition",
|
|
selectedOrder === opt.id
|
|
? "bg-[#1F6779]/20 border-[#1F6779] text-[#1F6779]"
|
|
: "bg-white border-gray-300 text-gray-600 hover:border-[#1F6779]/50"
|
|
)}
|
|
>
|
|
{selectedOrder === opt.id && (
|
|
<Check className="w-4 h-4 text-[#1F6779] mb-1" />
|
|
)}
|
|
<span>{opt.id}</span>
|
|
<span className="text-xs font-normal text-gray-500">
|
|
{opt.label}
|
|
</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<DialogFooter className="bg-gray-100 px-6 py-4 flex justify-end gap-3">
|
|
<DialogClose asChild>
|
|
<Button
|
|
variant="outline"
|
|
className="bg-[#A9C5CC]/40 text-[#1F6779] border-none"
|
|
>
|
|
Batal
|
|
</Button>
|
|
</DialogClose>
|
|
<Button
|
|
className="bg-[#1F6779] text-white hover:bg-[#155864]"
|
|
onClick={handleSubmit}
|
|
>
|
|
Submit
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|