From 84cb382670df908ed9e3ec2ca6ddeaf9904624e8 Mon Sep 17 00:00:00 2001 From: nico Date: Sat, 5 Oct 2024 17:47:15 +0800 Subject: [PATCH] Api Create Yang Lain Belum --- src/module/banner/lib/api_banner.ts | 3 +- src/module/banner/lib/type_banner.ts | 13 ++ src/module/banner/ui/create_banner.tsx | 177 +++++++++++++++++++------ src/module/banner/ui/edit_banner.tsx | 4 - src/module/banner/ui/list_banner.tsx | 142 ++++++++++++++++++-- 5 files changed, 284 insertions(+), 55 deletions(-) diff --git a/src/module/banner/lib/api_banner.ts b/src/module/banner/lib/api_banner.ts index c4b6a0c..54dd40a 100644 --- a/src/module/banner/lib/api_banner.ts +++ b/src/module/banner/lib/api_banner.ts @@ -21,7 +21,7 @@ export const funCreateBanner = async (data: FormData) => { return await response.json().catch(() => null); } -export const funGetOneBanner = async (path: string, p0: string) => { +export const funGetOneBanner = async (path: string) => { const response = await fetch(`/api/banner/${path}`) return await response.json().catch(() => null); } @@ -33,4 +33,3 @@ export const funEditBanner = async (path: string, data: FormData) => { }); return await response.json().catch(() => null); } - diff --git a/src/module/banner/lib/type_banner.ts b/src/module/banner/lib/type_banner.ts index 9d5a3ab..82b03e2 100644 --- a/src/module/banner/lib/type_banner.ts +++ b/src/module/banner/lib/type_banner.ts @@ -4,3 +4,16 @@ export interface IDataBanner { extension: string image: string }[] + +export interface IEditDataBanner { + id: string + title: string + extension: string + image: string +} +export interface ICreateDataBanner { + id: string + title: string + extension: string + image: string +} diff --git a/src/module/banner/ui/create_banner.tsx b/src/module/banner/ui/create_banner.tsx index c9edc10..86499e1 100644 --- a/src/module/banner/ui/create_banner.tsx +++ b/src/module/banner/ui/create_banner.tsx @@ -1,55 +1,134 @@ 'use client' import { LayoutNavbarNew, TEMA } from '@/module/_global'; +import LayoutModal from '@/module/_global/layout/layout_modal'; import { useHookstate } from '@hookstate/core'; -import { Box, Button, Group, Paper, rem, Text, TextInput } from '@mantine/core'; -import { Dropzone, DropzoneProps, IMAGE_MIME_TYPE } from '@mantine/dropzone'; +import { Box, Button, Group, Image, Paper, rem, Text, TextInput } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; import { IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; +import _ from 'lodash'; +import { useRouter } from 'next/navigation'; +import { useRef, useState } from 'react'; +import toast from 'react-hot-toast'; +import { funCreateBanner } from '../lib/api_banner'; -function CreateBanner(props: Partial) { +function CreateBanner() { + const router = useRouter(); + const [isModal, setModal] = useState(false); const tema = useHookstate(TEMA) - + const [loadingKonfirmasi, setLoadingKonfirmasi] = useState(false) + const [listData, setListData] = useState({ + title: "", + + }); + const [imgForm, setImgForm] = useState() + const openRef = useRef<() => void>(null) + const [img, setIMG] = useState() + // const [body, setBody] = useState({ + // id: "", + // title: "", + // }); + + + // function onCheck() { + // const cek = checkAll() + // if (!cek) + // return false + // setModal(true) + // } + + + + async function onSubmit(val: boolean) { + try { + console.log(listData) + setLoadingKonfirmasi(true) + const fd = new FormData() + fd.append("file", imgForm) + fd.append("data", JSON.stringify( + { + title: listData.title + } + )) + const res = await funCreateBanner(fd); + if (res.success) { + toast.success(res.message); + router.push('/banner') + } else { + toast.error(res.message); + } + setModal(false); + } catch (error) { + toast.error("Error"); + } finally { + setLoadingKonfirmasi(false) + setModal(false); + } + } + + // async function loadData() { + // const + // } + return ( - } /> + console.log('accepted files', files)} - onReject={(files) => console.log('rejected files', files)} - maxSize={5 * 1024 ** 2} - accept={IMAGE_MIME_TYPE} - {...props} + openRef={openRef} + onDrop={async (files) => { + if (!files || _.isEmpty(files)) + return toast.error('Tidak ada gambar yang dipilih') + setImgForm(files[0]) + // const buffer = URL.createObjectURL(files[0]); + const buffer = URL.createObjectURL(new Blob([new Uint8Array(await files[0].arrayBuffer())])) + setIMG(buffer) + }} + activateOnClick={false} + maxSize={1 * 1024 ** 2} + accept={['image/png', 'imagfe/jpeg', 'image/heic']} + onReject={(files) => { + return toast.error('File yang diizinkan: .png, .jpg, dan .heic dengan ukuran maksimal 1 MB') + }} + onClick={() => openRef.current?.()} > - - - - - - - - - - - - - Upload File - - - File Tidak Boleh Melebihi 500mb - - - + { + img ? + + : + + + + + + + + + + + +
+ + Klik Untuk Upload Image + + + Ukuran Foto Tidak Boleh Lebih Dari 500MB + +
+
+ } +
@@ -63,20 +142,38 @@ function CreateBanner(props: Partial) { borderRadius: 10, }, }} + onChange={(val) => { setListData({ title: val.target.value })}} /> + }}> + bg={tema.get().utama} radius={30} fullWidth + onClick={ () => { setModal(true)}} + + >Simpan
+ setModal(false)} + description="Apakah anda yakin ingin menambahkan banner ini?" + onYes={(val) => { + if (val) { + onSubmit(val); + } else { + setModal(false); + } + }} + + />
); } diff --git a/src/module/banner/ui/edit_banner.tsx b/src/module/banner/ui/edit_banner.tsx index 9f803be..d40ac60 100644 --- a/src/module/banner/ui/edit_banner.tsx +++ b/src/module/banner/ui/edit_banner.tsx @@ -10,13 +10,9 @@ import { useState } from 'react'; function EditBanner(props: Partial ) { - const router = useRouter() const tema = useHookstate(TEMA) - const param = useParams<{ id: string, detail: string }>() const [title, setTitle] = useState("") const [openModal, setOpenModal] = useState(false) - const [loading, setLoading] = useState(true) - const [imgForm, setImgForm] = useState() const [touched, setTouched] = useState({ title: false, }); diff --git a/src/module/banner/ui/list_banner.tsx b/src/module/banner/ui/list_banner.tsx index 8a6cd3b..7251a54 100644 --- a/src/module/banner/ui/list_banner.tsx +++ b/src/module/banner/ui/list_banner.tsx @@ -1,18 +1,20 @@ 'use client' -import { LayoutDrawer, LayoutModalViewFile, TEMA, WARNA } from '@/module/_global'; +import { currentScroll, LayoutDrawer, LayoutModalViewFile, TEMA, WARNA } from '@/module/_global'; import LayoutModal from '@/module/_global/layout/layout_modal'; import { useHookstate } from '@hookstate/core'; -import { ActionIcon, Anchor, Box, Flex, Group, Image, Paper, SimpleGrid, Stack, Text } from '@mantine/core'; +import { ActionIcon, Anchor, Box, Flex, Group, Image, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core'; import { useParams, useRouter } from 'next/navigation'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { FaFile, FaPencil, FaTrash } from 'react-icons/fa6'; +import { IDataBanner } from '../lib/type_banner'; +import toast from 'react-hot-toast'; +import { useShallowEffect } from '@mantine/hooks'; +import { funDeleteBanner, funGetAllBanner, funGetOneBanner } from '../lib/api_banner'; +import { HiMagnifyingGlass } from 'react-icons/hi2'; function ListBanner() { + const [isList, setIsList] = useState (false) const tema = useHookstate(TEMA) - const [searchQuery, setSearchQuery] = useState('') - const [loading, setLoading] = useState(true); - const [isData, setData] = useState([]); - const [valChoose, setValChoose] = useState(""); const router = useRouter(); const param = useParams<{ id: string }>() const [isOpenModalView, setOpenModalView] = useState(false) @@ -20,14 +22,99 @@ function ListBanner() { const [openDrawer, setOpenDrawer] = useState(false); const [idDataStorage, setIdDataStorage] = useState('') const [isExtension, setExtension] = useState('') + const [loading, setLoading] = useState(true) + const [isData, setData] = useState([]) + const [idData, setIdData] = useState('') + const [isPage, setPage] = useState(1) + const [searchQuerry, setSearchQuerry] = useState('') + // const { value: containerRef } = useHookstate(currentScroll); + const handleList = () => { + setIsList(!isList) + } + + const fetchData = async (loading: boolean) => { + console.log('jallan') + try { + if (loading) + setLoading(true) + const response = await funGetAllBanner('?search=' + searchQuerry) + if (response.success) { + setData(response.data) + } else { + toast.error(response.message) + } + setLoading(false) + } catch (error) { + console.error(error) + toast.error("Gagal mendapatkan banner, coba lagi nanti"); + } finally { + setLoading(false) + } + } + + function searchBanner(search: string) { + setSearchQuerry(search) + setPage(1) + } + + + useShallowEffect(() => { + fetchData(true) + }, [searchQuerry]) + + useShallowEffect(() => { + fetchData(false) + }, [isPage]) + + + async function onDelete() { + try { + const res = await funDeleteBanner(idData); + if (res.success) { + toast.success(res.message) + getOneData() + setIdData("") + setIdDataStorage("") + setOpenDrawer(false) + } else { + toast.error(res.message); + } + } catch (error) { + console.error(error); + toast.error("Gagal menghapus banner, coba lagi nanti"); + } + + } + + + return ( + + } + placeholder='pencarian' + value={searchQuerry} + onChange={(val) => { searchBanner(val.target.value)}} + /> + + + - {[...Array(5)].map((_, index) => ( + {isData.map((_, index) => ( { setOpenDrawer(true) } } style={{ @@ -96,7 +183,12 @@ function ListBanner() { setOpenModal(false)} description='Apakah Anda yakin ingin menghapus banner?' - onYes={(val) => { setOpenModal(false) }} /> + onYes={(val) => { + if (val) { + onDelete() + } + setOpenModal(false) + }} /> setOpenModalView(false)} file={idDataStorage} extension={isExtension} fitur='task' /> @@ -104,3 +196,35 @@ function ListBanner() { } export default ListBanner; + function funGetBanner(arg0: string) { + throw new Error('Function not implemented.'); + } + + function getOneData() { + throw new Error('Function not implemented.'); + } + + + + + // useEffect(() => { + // const handleScroll = async () => { + // if (containerRef && containerRef.current) { + // const scrollTop = containerRef.current.scrollTop; + // const containerHeight = containerRef.current.clientHeight; + // const scrollHeight = containerRef.current.scrollHeight; + + // if (scrollTop + containerHeight + 1 >= scrollHeight) { + // setPage(isPage + 1) + // } + // } + // }; + + // const container = containerRef?.current; + // container?.addEventListener("scroll", handleScroll); + + // return () => { + // container?.removeEventListener("scroll", handleScroll); + // }; + // }, [containerRef, isPage]); +