mediahub-fe/components/form/content/create-form.tsx

382 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, { ChangeEvent, useRef, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Card } from "@/components/ui/card";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { useRouter } from "next/navigation";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import JoditEditor from "jodit-react";
import { register } from "module";
import { Switch } from "@/components/ui/switch";
const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
naration: z.string().min(2, {
message: "Narasi Penugasan harus lebih dari 2 karakter.",
}),
creator: z.string().min(1, { message: "Judul diperlukan" }),
tags: z.string().min(1, { message: "Judul diperlukan" }),
});
export default function FormImage() {
const MySwal = withReactContent(Swal);
const router = useRouter();
const editor = useRef(null);
type TaskSchema = z.infer<typeof taskSchema>;
const [tags, setTags] = useState<string[]>([]);
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
// State for various form fields
const [output, setOutput] = useState({
all: false,
video: false,
audio: false,
image: false,
text: false,
});
const [assignmentType, setAssignmentType] = useState("mediahub");
const [assignmentCategory, setAssignmentCategory] = useState("publication");
const [selectedTarget, setSelectedTarget] = useState("all");
const [unitSelection, setUnitSelection] = useState({
allUnit: false,
mabes: false,
polda: false,
polres: false,
});
const {
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<TaskSchema>({
resolver: zodResolver(taskSchema),
});
const handleKeyDown = (e: any) => {
const newTag = e.target.value.trim(); // Ambil nilai input
if (e.key === "Enter" && newTag) {
e.preventDefault(); // Hentikan submit form
if (!tags.includes(newTag)) {
setTags((prevTags) => [...prevTags, newTag]); // Tambah tag baru
setValue("tags", ""); // Kosongkan input
}
}
};
const handleRemoveTag = (index: any) => {
setTags((prevTags) => prevTags.filter((_, i) => i !== index));
};
const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
const files = Array.from(event.target.files);
setSelectedFiles((prevImages: any) => [...prevImages, ...files]);
console.log("DATAFILE::", selectedFiles);
}
};
const handleRemoveImage = (index: number) => {
setSelectedFiles((prevImages) => prevImages.filter((_, i) => i !== index));
};
const save = async (data: TaskSchema) => {
const requestData = {
...data,
output,
assignmentType,
assignmentCategory,
target: selectedTarget,
unitSelection,
};
console.log("Form Data Submitted:", requestData);
MySwal.fire({
title: "Sukses",
text: "Data berhasil disimpan.",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then(() => {
router.push("/en/content/image");
});
};
const onSubmit = (data: TaskSchema) => {
MySwal.fire({
title: "Simpan Data",
text: "Apakah Anda yakin ingin menyimpan data ini?",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#d33",
confirmButtonColor: "#3085d6",
confirmButtonText: "Simpan",
}).then((result) => {
if (result.isConfirmed) {
save(data);
}
});
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="flex lg:flex-row gap-10">
<Card className="w-full lg:w-8/12">
<div className="px-6 py-6">
<p className="text-lg font-semibold mb-3">Form Konten Foto</p>
<div className="gap-5 mb-5">
{/* Input Title */}
<div className="space-y-2 py-3">
<Label>Judul</Label>
<Controller
control={control}
name="title"
render={({ field }) => (
<Input
size="md"
type="text"
value={field.value}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/>
{errors.title?.message && (
<p className="text-red-400 text-sm">{errors.title.message}</p>
)}
</div>
<div className="flex items-center">
<div className="py-3 w-full">
<Label>Kategory</Label>
<Select onValueChange={setSelectedTarget}>
<SelectTrigger size="md">
<SelectValue placeholder="Pilih" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">Mediapool</SelectItem>
<SelectItem value="contributor">
Liputan Kegiatan
</SelectItem>
<SelectItem value="approver">Press Tour</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="py-3">
<Label>Deskripsi</Label>
<Controller
control={control}
name="naration"
render={({ field: { onChange, value } }) => (
<JoditEditor
ref={editor}
value={value}
onChange={onChange}
className="dark:text-black"
/>
)}
/>
{errors.naration?.message && (
<p className="text-red-400 text-sm">
{errors.naration.message}
</p>
)}
</div>
<div className="py-3">
<Label>Attachment</Label>
<div className="flex items-center justify-center w-full pt-2">
<label
htmlFor="dropzone-file"
className="flex flex-col items-center justify-center w-full h-[155px] border-2 border-black border-dashed rounded-lg cursor-pointer dark:bg-black dark:hover:bg-bray-800 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600"
>
<div className="flex flex-col items-center justify-center pt-5 pb-6 ">
<svg
className="w-10 h-10 mb-3 text-gray-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
></path>
</svg>
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
{/* or{" "} */}
<span className="font-semibold underline text-amber-800">
Click to upload
</span>
</p>
</div>
<input
id="dropzone-file"
type="file"
className="hidden"
onChange={handleImageChange}
/>
</label>
</div>
<div className="flex flex-row items-center gap-3 py-3">
<Label>Gunakan Watermark</Label>
<div className="flex items-center gap-3">
<Switch defaultChecked color="primary" id="c2" />
</div>
</div>
{selectedFiles?.length > 0 ? (
<div className="pt-2">
<div className="flex gap-3">
{selectedFiles.map((image, index) => (
<div
key={index}
className="flex flex-row items-center justify-between gap-1"
>
<img
src={URL.createObjectURL(image)}
alt="Pratinjau Gambar"
style={{ maxWidth: "200px", maxHeight: "200px" }}
className="rounded-md"
/>
<button
className="text-blue-600 hover:text-blue-800 focus:outline-none"
onClick={() => handleRemoveImage(index)}
>
X
</button>
</div>
))}
</div>
</div>
) : (
""
)}
</div>
</div>
{/* Submit Button */}
</div>
</Card>
<div className="w-4/12">
<Card className=" h-[500px]">
<div className="px-3 py-3">
<div className="space-y-2">
<Label>Kreator</Label>
<Controller
control={control}
name="creator"
render={({ field }) => (
<Input
size="md"
type="text"
value={field.value}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/>
{errors.creator?.message && (
<p className="text-red-400 text-sm">
{errors.creator.message}
</p>
)}
</div>
</div>
<div className="px-3 py-3">
<Label>Tags</Label>
<Controller
control={control}
name="tags"
render={({ field }) => (
<Input
size="md"
type="text"
value={field.value}
onChange={field.onChange}
placeholder="Enter Title"
onKeyDown={handleKeyDown}
/>
)}
/>
<div className="text-sm text-red-500">
{tags.length === 0 && "Please add at least one tag."}
</div>
<div className="flex flex-wrap gap-2 border border-gray-300 mt-2 rounded-md p-2 items-center">
{tags.map((tag, index) => (
<div
key={index}
className="flex items-center gap-1 bg-blue-100 text-blue-800 rounded-full px-3 py-1 text-sm font-medium"
>
<span>{tag}</span>
<button
className="text-blue-600 hover:text-blue-800 focus:outline-none"
onClick={() => handleRemoveTag(index)}
>
×
</button>
</div>
))}
</div>
</div>
<div className="px-3 py-3">
<div className="flex flex-col gap-6">
<Label>Target Publish</Label>
<div className="flex gap-2 items-center">
<Checkbox id="all" />
<Label htmlFor="all">SEMUA</Label>
</div>
<div className="flex gap-2 items-center">
<Checkbox id="umum" />
<Label htmlFor="umum">UMUM</Label>
</div>
<div className="flex gap-2 items-center">
<Checkbox id="journalist" />
<Label htmlFor="journalist">JOURNALIS</Label>
</div>
<div className="flex gap-2 items-center">
<Checkbox id="polri" />
<Label htmlFor="polri">POLRI</Label>
</div>
<div className="flex gap-2 items-center">
<Checkbox id="ksp" />
<Label htmlFor="ksp">KSP</Label>
</div>
</div>
</div>
</Card>
<div className="flex flex-row justify-end gap-3">
<div className="mt-4">
<Button type="submit" color="primary">
Submit
</Button>
</div>
<div className="mt-4">
<Button type="submit" color="primary" variant="outline">
Cancel
</Button>
</div>
</div>
</div>
</div>
</form>
);
}