jaecoo-kelapagading/components/dialog/galery-dialog.tsx

198 lines
5.9 KiB
TypeScript
Raw Normal View History

2025-11-18 06:56:39 +00:00
"use client";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
2025-11-20 06:57:16 +00:00
import { Upload, X } from "lucide-react";
import { useState, useRef, useEffect } from "react";
import { createGalery, uploadGaleryFile } from "@/service/galery";
2025-11-18 06:56:39 +00:00
export function GaleriDialog({ open, onClose, onSubmit }: any) {
const [title, setTitle] = useState("");
2025-11-20 06:57:16 +00:00
const [description, setDescription] = useState("");
const [files, setFiles] = useState<File[]>([]);
const [previews, setPreviews] = useState<string[]>([]);
2025-11-18 06:56:39 +00:00
const fileRef = useRef<HTMLInputElement>(null);
2025-11-20 06:57:16 +00:00
useEffect(() => {
if (!files || files.length === 0) {
setPreviews([]);
2025-11-18 06:56:39 +00:00
return;
}
2025-11-20 06:57:16 +00:00
const objectUrls = files.map((file) => URL.createObjectURL(file));
setPreviews(objectUrls);
2025-11-18 06:56:39 +00:00
2025-11-20 06:57:16 +00:00
return () => {
objectUrls.forEach((url) => URL.revokeObjectURL(url));
};
}, [files]);
2025-11-18 06:56:39 +00:00
2025-11-20 06:57:16 +00:00
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files;
if (!files) return;
setFiles((prev: File[]) => [...prev, ...Array.from(files)]);
};
2025-11-18 06:56:39 +00:00
2025-11-20 06:57:16 +00:00
const removeFile = (index: number) => {
setFiles((prev) => prev.filter((_, i) => i !== index));
2025-11-18 06:56:39 +00:00
};
2025-11-20 06:57:16 +00:00
const handleSubmit = async () => {
try {
if (!title) return alert("Judul wajib diisi!");
const formData = new FormData();
formData.append("title", title);
formData.append("description", description);
const res = await createGalery(formData);
const galleryId = res?.data?.data?.id;
if (!galleryId) {
alert("Galeri gagal dibuat");
return;
}
console.log("Galeri Created:", galleryId);
for (const file of files) {
const fileForm = new FormData();
fileForm.append("gallery_id", galleryId);
fileForm.append("title", title);
fileForm.append("file", file);
const uploadRes = await uploadGaleryFile(galleryId, fileForm);
console.log("File Uploaded:", uploadRes?.data);
}
onSubmit();
setTitle("");
setDescription("");
setFiles([]);
} catch (error) {
console.error("Submit failed:", error);
alert("Gagal mengupload galeri");
}
2025-11-18 06:56:39 +00:00
};
return (
<Dialog open={open} onOpenChange={onClose}>
<DialogContent className="max-w-2xl rounded-2xl p-0 overflow-hidden">
2025-11-20 06:57:16 +00:00
{/* HEADER */}
2025-11-18 06:56:39 +00:00
<div className="bg-[#1F6779] text-white px-6 py-4 flex justify-between items-center">
<DialogTitle className="text-white">Tambah Galeri</DialogTitle>
</div>
2025-11-20 06:57:16 +00:00
{/* BODY */}
2025-11-18 06:56:39 +00:00
<div className="px-6 py-6 space-y-6">
{/* Judul */}
<div>
<label className="font-medium text-sm">
Judul Galeri <span className="text-red-500">*</span>
</label>
<Input
placeholder="Masukkan judul galeri"
className="mt-1 h-12"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</div>
{/* Deskripsi */}
<div>
<label className="font-medium text-sm">
Deskripsi Galeri <span className="text-red-500">*</span>
</label>
<Input
placeholder="Masukkan deskripsi galeri"
className="mt-1 h-12"
2025-11-20 06:57:16 +00:00
value={description}
onChange={(e) => setDescription(e.target.value)}
2025-11-18 06:56:39 +00:00
/>
</div>
2025-11-20 06:57:16 +00:00
{/* Upload File */}
2025-11-18 06:56:39 +00:00
<div>
<label className="font-medium text-sm">
2025-11-20 06:57:16 +00:00
Upload File (opsional)
2025-11-18 06:56:39 +00:00
</label>
<div
className="border-2 border-dashed rounded-xl flex flex-col items-center justify-center py-10 cursor-pointer"
onClick={() => fileRef.current?.click()}
>
<Upload className="w-10 h-10 text-[#1F6779]" />
<p className="text-sm text-gray-600 mt-2">
Klik untuk upload atau drag & drop
</p>
<p className="text-xs text-gray-400">PNG, JPG (max 2MB)</p>
<input
ref={fileRef}
type="file"
className="hidden"
onChange={handleFileChange}
accept="image/*"
2025-11-20 06:57:16 +00:00
multiple
2025-11-18 06:56:39 +00:00
/>
</div>
2025-11-20 06:57:16 +00:00
{/* Preview Gambar */}
{previews.length > 0 && (
<div className="mt-4 flex flex-wrap gap-4">
{previews.map((src, i) => (
<div
key={i}
className="relative w-24 h-24 rounded-lg overflow-hidden border border-gray-300"
>
<img
src={src}
alt={`preview-${i}`}
className="object-cover w-full h-full"
/>
<button
onClick={() => removeFile(i)}
className="absolute top-1 right-1 bg-red-600 rounded-full p-1 text-white hover:bg-red-700 transition"
title="Hapus gambar"
type="button"
>
<X size={16} />
</button>
</div>
))}
</div>
2025-11-18 06:56:39 +00:00
)}
</div>
</div>
2025-11-20 06:57:16 +00:00
{/* FOOTER */}
2025-11-18 06:56:39 +00:00
<DialogFooter className="flex justify-between px-6 pb-6 gap-4">
<Button
variant="ghost"
onClick={onClose}
className="bg-slate-200 text-slate-700 w-full h-12"
>
Batal
</Button>
<Button
onClick={handleSubmit}
className="bg-[#1F6779] hover:bg-[#165766] text-white w-full h-12"
>
Submit
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}