feat:magazine edit
This commit is contained in:
parent
d64ce7fc14
commit
471539804c
|
|
@ -33,7 +33,7 @@ import {
|
|||
PptIcon,
|
||||
WordIcon,
|
||||
} from "@/components/icons/globals";
|
||||
import { createMagazine } from "@/service/magazine";
|
||||
import { createMagazine, uploadMagazineFile } from "@/service/magazine";
|
||||
|
||||
// const CustomEditor = dynamic(
|
||||
// () => {
|
||||
|
|
@ -85,11 +85,6 @@ export default function NewCreateMagazineForm() {
|
|||
const router = useRouter();
|
||||
const editor = useRef(null);
|
||||
const [files, setFiles] = useState<FileWithPreview[]>([]);
|
||||
const [useAi, setUseAI] = useState(false);
|
||||
const [listCategory, setListCategory] = useState<CategoryType[]>([]);
|
||||
const [tag, setTag] = useState("");
|
||||
const [thumbnailImg, setThumbnailImg] = useState<File[]>([]);
|
||||
const [selectedMainImage, setSelectedMainImage] = useState<number>();
|
||||
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
onDrop: (acceptedFiles) => {
|
||||
|
|
@ -160,28 +155,23 @@ export default function NewCreateMagazineForm() {
|
|||
// rows: values.rows,
|
||||
};
|
||||
console.log("formd", formData);
|
||||
// const response = await createMagazine(formData);
|
||||
const response = await createMagazine(formData);
|
||||
|
||||
// if (response?.error) {
|
||||
// error(response.message);
|
||||
// return false;
|
||||
// }
|
||||
// const magazineId = response?.data?.data?.id;
|
||||
// if (files?.length > 0) {
|
||||
// const formFiles = new FormData();
|
||||
if (response?.error) {
|
||||
error(response.message);
|
||||
return false;
|
||||
}
|
||||
const magazineId = response?.data?.data?.id;
|
||||
if (files?.length > 0) {
|
||||
const formFiles = new FormData();
|
||||
|
||||
// for (const element of files) {
|
||||
// formFiles.append("file", element);
|
||||
// const resFile = await uploadArticleFile(magazineId, formFiles);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (thumbnailImg?.length > 0) {
|
||||
// const formFiles = new FormData();
|
||||
|
||||
// formFiles.append("file", thumbnailImg[0]);
|
||||
// const resFile = await uploadArticleThumbnail(magazineId, formFiles);
|
||||
// }
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
formFiles.append("files", files[i]);
|
||||
formFiles.append("title", values.rows[i].title);
|
||||
formFiles.append("file", values.rows[i].description);
|
||||
const resFile = await uploadMagazineFile(magazineId, formFiles);
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
successSubmit("/admin/magazine");
|
||||
|
|
@ -310,6 +300,7 @@ export default function NewCreateMagazineForm() {
|
|||
<Button
|
||||
className=" border-none rounded-full"
|
||||
variant="bordered"
|
||||
color="danger"
|
||||
onClick={() => handleRemoveFile(file)}
|
||||
>
|
||||
<TimesIcon />
|
||||
|
|
|
|||
|
|
@ -29,12 +29,14 @@ import Link from "next/link";
|
|||
import {
|
||||
CsvIcon,
|
||||
ExcelIcon,
|
||||
FileIcon,
|
||||
PdfIcon,
|
||||
PptIcon,
|
||||
WordIcon,
|
||||
} from "@/components/icons/globals";
|
||||
import {
|
||||
createMagazine,
|
||||
deleteMagazineFiles,
|
||||
getMagazineById,
|
||||
updateMagazine,
|
||||
uploadMagazineFile,
|
||||
|
|
@ -93,6 +95,7 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
|
|||
const router = useRouter();
|
||||
const editor = useRef(null);
|
||||
const [files, setFiles] = useState<FileWithPreview[]>([]);
|
||||
const [detailfiles, setDetailFiles] = useState<any>([]);
|
||||
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
onDrop: (acceptedFiles) => {
|
||||
|
|
@ -144,6 +147,8 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
|
|||
const data = res?.data?.data;
|
||||
setValue("title", data?.title);
|
||||
setValue("description", data?.description);
|
||||
setDetailFiles(data?.files);
|
||||
|
||||
console.log("datasss", data);
|
||||
};
|
||||
|
||||
|
|
@ -222,31 +227,38 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
|
|||
setValue("slug", generateSlug(watchTitle));
|
||||
}, [watchTitle]);
|
||||
|
||||
const renderPreview = (file: File) => {
|
||||
if (file.type === "application/pdf") {
|
||||
const renderPreview = (file: File, fileName?: string) => {
|
||||
const fileType = fileName?.split(".")[fileName?.split(".").length - 1];
|
||||
if (file.type === "application/pdf" || fileType == "pdf") {
|
||||
return <PdfIcon size={60} />;
|
||||
} else if (file.type === "text/csv") {
|
||||
} else if (file.type === "text/csv" || fileType == "csv") {
|
||||
return <CsvIcon size={60} />;
|
||||
} else if (
|
||||
file.type ===
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" ||
|
||||
file.type === "application/msword"
|
||||
file.type === "application/msword" ||
|
||||
fileType == "doc" ||
|
||||
fileType == "docx"
|
||||
) {
|
||||
return <WordIcon size={60} />;
|
||||
} else if (
|
||||
file.type ===
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ||
|
||||
file.type === "application/vnd.ms-excel"
|
||||
file.type === "application/vnd.ms-excel" ||
|
||||
fileType == "xls" ||
|
||||
fileType == "xlsx"
|
||||
) {
|
||||
return <ExcelIcon size={60} />;
|
||||
} else if (
|
||||
file.type ===
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation" ||
|
||||
file.type === "application/vnd.ms-powerpoint"
|
||||
file.type === "application/vnd.ms-powerpoint" ||
|
||||
fileType == "ppt" ||
|
||||
fileType == "pptx"
|
||||
) {
|
||||
return <PptIcon size={60} />;
|
||||
} else {
|
||||
return "unknown";
|
||||
return <FileIcon size={60} />;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -319,6 +331,7 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
|
|||
<Button
|
||||
className=" border-none rounded-full"
|
||||
variant="bordered"
|
||||
color="danger"
|
||||
onClick={() => handleRemoveFile(file)}
|
||||
>
|
||||
<TimesIcon />
|
||||
|
|
@ -326,6 +339,43 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
|
|||
</div>
|
||||
));
|
||||
|
||||
const handleDeleteFile = (id: number) => {
|
||||
MySwal.fire({
|
||||
title: "Hapus File",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Hapus",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
deleteFile(id);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const deleteFile = async (id: number) => {
|
||||
loading();
|
||||
const res = await deleteMagazineFiles(id);
|
||||
|
||||
if (res?.error) {
|
||||
error(res.message);
|
||||
return false;
|
||||
}
|
||||
close();
|
||||
initFetch();
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
className="flex flex-row gap-8 text-black"
|
||||
|
|
@ -411,8 +461,8 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
|
|||
)}
|
||||
|
||||
<p className="text-sm mt-3">File Media</p>
|
||||
<Fragment>
|
||||
{!isDetail && (
|
||||
{!isDetail && (
|
||||
<Fragment>
|
||||
<div {...getRootProps({ className: "dropzone" })} className="mb-2">
|
||||
<input {...getInputProps()} />
|
||||
<div className=" w-full text-center border-dashed border border-default-200 dark:border-default-300 rounded-md py-[52px] flex items-center flex-col">
|
||||
|
|
@ -426,21 +476,190 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{files.length ? (
|
||||
<Fragment>
|
||||
{fileList}
|
||||
|
||||
{files.length ? (
|
||||
<Fragment>
|
||||
<div className="grid grid-cols-2 gap-2">{fileList}</div>
|
||||
{files.length > 1 && (
|
||||
<div className=" flex justify-between gap-2">
|
||||
<Button onPress={() => setFiles([])} size="sm">
|
||||
Hapus Semua
|
||||
{/* {files.length > 1 && (
|
||||
<div className=" flex justify-between gap-2">
|
||||
<Button onPress={() => setFiles([])} size="sm">
|
||||
Hapus Semua
|
||||
</Button>
|
||||
</div>
|
||||
)} */}
|
||||
</Fragment>
|
||||
) : null}
|
||||
{detailfiles?.map((file: any, index: number) => (
|
||||
<div
|
||||
key={file.fileName + index}
|
||||
className=" flex justify-between border p-3 rounded-md"
|
||||
>
|
||||
<div className="flex gap-3 grow">
|
||||
<div className="file-preview">
|
||||
{renderPreview(file, file.fileName)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-1 grow">
|
||||
<p className="text-sm font-semibold">Nama File</p>
|
||||
<div className="flex flex-row gap-2 items-center">
|
||||
<p className=" text-sm text-card-foreground">
|
||||
{file.fileName}
|
||||
</p>
|
||||
<p className=" text-xs font-light text-muted-foreground">
|
||||
{Math.round(file.size / 100) / 10 > 1000 ? (
|
||||
<>
|
||||
{(Math.round(file.size / 100) / 10000).toFixed(1)}
|
||||
</>
|
||||
) : (
|
||||
<>{(Math.round(file.size / 100) / 10).toFixed(1)}</>
|
||||
)}
|
||||
{" kb"}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm font-semibold">Judul</p>
|
||||
<Input
|
||||
type="text"
|
||||
id="title"
|
||||
placeholder=""
|
||||
label=""
|
||||
isReadOnly
|
||||
value={file.title}
|
||||
onValueChange={(e) =>
|
||||
setValue(`rows.${index}.title`, e)
|
||||
}
|
||||
labelPlacement="outside"
|
||||
className="w-full "
|
||||
classNames={{
|
||||
inputWrapper: [
|
||||
"border-1 rounded-lg",
|
||||
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||
],
|
||||
}}
|
||||
variant="bordered"
|
||||
/>
|
||||
<p className="text-sm font-semibold">Deskripsi</p>
|
||||
<Textarea
|
||||
type="text"
|
||||
id="title"
|
||||
placeholder=""
|
||||
label=""
|
||||
value={file.description}
|
||||
onValueChange={(e) =>
|
||||
setValue(`rows.${index}.description`, e)
|
||||
}
|
||||
isReadOnly
|
||||
labelPlacement="outside"
|
||||
className="w-full "
|
||||
classNames={{
|
||||
inputWrapper: [
|
||||
"border-1 rounded-lg",
|
||||
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||
],
|
||||
}}
|
||||
variant="bordered"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className=" border-none rounded-full"
|
||||
variant="bordered"
|
||||
color="danger"
|
||||
onClick={() => handleDeleteFile(file?.id)}
|
||||
>
|
||||
<TimesIcon />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</Fragment>
|
||||
) : null}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
</Fragment>
|
||||
)}
|
||||
{isDetail && (
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{detailfiles?.map((file: any, index: number) => (
|
||||
<div
|
||||
key={file.fileName + index}
|
||||
className=" flex justify-between border p-3 rounded-md"
|
||||
>
|
||||
<div className="flex gap-3 grow">
|
||||
<div className="file-preview">
|
||||
{renderPreview(file, file.fileName)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-1 grow">
|
||||
<p className="text-sm font-semibold">Nama File</p>
|
||||
<div className="flex flex-row gap-2 items-center">
|
||||
<p className=" text-sm text-card-foreground">
|
||||
{file.fileName}
|
||||
</p>
|
||||
<p className=" text-xs font-light text-muted-foreground">
|
||||
{Math.round(file.size / 100) / 10 > 1000 ? (
|
||||
<>
|
||||
{(Math.round(file.size / 100) / 10000).toFixed(1)}
|
||||
</>
|
||||
) : (
|
||||
<>{(Math.round(file.size / 100) / 10).toFixed(1)}</>
|
||||
)}
|
||||
{" kb"}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm font-semibold">Judul</p>
|
||||
<Input
|
||||
type="text"
|
||||
id="title"
|
||||
placeholder=""
|
||||
label=""
|
||||
isReadOnly
|
||||
value={file.title}
|
||||
onValueChange={(e) => setValue(`rows.${index}.title`, e)}
|
||||
labelPlacement="outside"
|
||||
className="w-full "
|
||||
classNames={{
|
||||
inputWrapper: [
|
||||
"border-1 rounded-lg",
|
||||
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||
],
|
||||
}}
|
||||
variant="bordered"
|
||||
/>
|
||||
<p className="text-sm font-semibold">Deskripsi</p>
|
||||
<Textarea
|
||||
type="text"
|
||||
id="title"
|
||||
placeholder=""
|
||||
label=""
|
||||
value={file.description}
|
||||
onValueChange={(e) =>
|
||||
setValue(`rows.${index}.description`, e)
|
||||
}
|
||||
isReadOnly
|
||||
labelPlacement="outside"
|
||||
className="w-full "
|
||||
classNames={{
|
||||
inputWrapper: [
|
||||
"border-1 rounded-lg",
|
||||
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||
],
|
||||
}}
|
||||
variant="bordered"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <Button
|
||||
className=" border-none rounded-full"
|
||||
variant="bordered"
|
||||
color="danger"
|
||||
onClick={() => handleRemoveFile(file)}
|
||||
>
|
||||
<TimesIcon />
|
||||
</Button> */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-row gap-3 mt-3">
|
||||
{!isDetail && (
|
||||
<Button color="primary" type="submit">
|
||||
|
|
|
|||
|
|
@ -128,3 +128,23 @@ export const PptIcon = ({
|
|||
/>
|
||||
</svg>
|
||||
);
|
||||
export const FileIcon = ({
|
||||
size,
|
||||
height = 24,
|
||||
width = 24,
|
||||
fill = "currentColor",
|
||||
...props
|
||||
}: IconSvgProps) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size || width}
|
||||
height={size || height}
|
||||
{...props}
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="m10.5.5l.354-.354L10.707 0H10.5zm3 3h.5v-.207l-.146-.147zm-1 10.5h-10v1h10zM2 13.5v-12H1v12zM2.5 1h8V0h-8zM13 3.5v10h1v-10zM10.146.854l3 3l.708-.708l-3-3zM2.5 14a.5.5 0 0 1-.5-.5H1A1.5 1.5 0 0 0 2.5 15zm10 1a1.5 1.5 0 0 0 1.5-1.5h-1a.5.5 0 0 1-.5.5zM2 1.5a.5.5 0 0 1 .5-.5V0A1.5 1.5 0 0 0 1 1.5z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -56,3 +56,7 @@ export async function uploadMagazineFile(id: string, data: any) {
|
|||
};
|
||||
return await httpPost(`/magazine-files/${id}`, headers, data);
|
||||
}
|
||||
|
||||
export async function deleteMagazineFiles(id: number) {
|
||||
return await httpDeleteInterceptor(`magazine-files/${id}`);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue