feat:date picker article admin, category

This commit is contained in:
Rama Priyanto 2024-11-13 15:29:27 +07:00
parent d18bbfe568
commit 575dacc7e6
10 changed files with 897 additions and 391 deletions

View File

@ -1,24 +1,25 @@
"use client"
"use client";
import { AddIcon } from "@/components/icons";
import ArticleTable from "@/components/table/article-table";
import { Button, Card } from "@nextui-org/react";
import Link from "next/link";
export default function BasicPage() {
return (
<div className="h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-2 ml-4">
<div className="px-4">
<Card className="rounded-md my-5 pl-5 py-2">
<Link href="/admin/article/create">
<Button size="md" color="primary" className="w-min">
<AddIcon />New Article
</Button>
</Link>
</Card>
<Card className="rounded-md my-5">
<ArticleTable />
</Card>
</div>
return (
<div className="overflow-x-hidden overflow-y-scroll rounded-lg border-2">
<div className="px-2 md:px-4 w-full">
<div className="rounded-md my-5 px-5 py-2 bg-white dark:bg-[#18181b]">
<Link href="/admin/article/create">
<Button size="md" color="primary" className="w-min">
<AddIcon />
New Article
</Button>
</Link>
</div>
);
<div className="bg-white dark:bg-[#18181b] rounded-xl my-5 p-2">
<ArticleTable />
</div>
</div>
</div>
);
}

View File

@ -1,328 +1,394 @@
'use client'
import { error } from '@/config/swal';
import { createArticle } from '@/service/article';
import { zodResolver } from '@hookform/resolvers/zod';
import { Button, Card, Chip, Input, Select, SelectItem, Selection } from '@nextui-org/react';
import JoditEditor from 'jodit-react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import React, { ChangeEvent, useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content';
"use client";
import { error } from "@/config/swal";
import { createArticle } from "@/service/article";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Button,
Card,
Chip,
Input,
Select,
SelectItem,
Selection,
} from "@nextui-org/react";
import JoditEditor from "jodit-react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import * as z from "zod";
import ReactSelect from "react-select";
import makeAnimated from "react-select/animated";
const articleSchema = z.object({
title: z.string().min(1, { message: "Required" }),
article: z.string().min(1, { message: "Required" }),
slug: z.string().min(1, { message: "Required" }),
tags: z.string().min(0, { message: "Required" }).optional(),
description: z.string().min(0, { message: "Required" }).optional(),
title: z.string().min(1, { message: "Required" }),
article: z.string().min(1, { message: "Required" }),
slug: z.string().min(1, { message: "Required" }),
tags: z.string().min(0, { message: "Required" }).optional(),
description: z.string().min(0, { message: "Required" }).optional(),
});
const dummyCategory = [
{
id: 1,
label: "Category 1",
value: "category-1",
},
{
id: 2,
label: "Category 2",
value: "category-2",
},
{
id: 3,
label: "Category 3",
value: "category-3",
},
{
id: 4,
label: "Category 4",
value: "category-4",
},
{
id: 5,
label: "Category 5",
value: "category-5",
},
];
export default function FormArticle() {
const router = useRouter();
const [title, setTitle] = useState<string>("");
const [article, setArticle] = React.useState<Selection>(new Set([]));
const [slug, setSlug] = useState<string>("");
const [tags, setTags] = useState<string[]>([]);
const [newTags, setNewTags] = useState<string>("");
const editor = useRef(null);
const [content, setContent] = useState('');
const MySwal = withReactContent(Swal);
const [selectedImages, setSelectedImages] = useState<File[]>([]);
const animatedComponents = makeAnimated();
const formOptions = { resolver: zodResolver(articleSchema) };
type MicroIssueSchema = z.infer<typeof articleSchema>;
const {
register,
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<MicroIssueSchema>(formOptions);
const router = useRouter();
const [title, setTitle] = useState<string>("");
const [article, setArticle] = React.useState<Selection>(new Set([]));
const [slug, setSlug] = useState<string>("");
const [tags, setTags] = useState<string[]>([]);
const [newTags, setNewTags] = useState<string>("");
const editor = useRef(null);
const [content, setContent] = useState("");
const MySwal = withReactContent(Swal);
const [selectedImages, setSelectedImages] = useState<File[]>([]);
const [selectedCategory, setSelectedCategory] = useState<any>();
const TypeId = [
{
key: 1,
label: "Article"
},
{
key: 2,
label: "Magazine"
},
]
useEffect(() => {
console.log("selected", selectedCategory);
}, [selectedCategory]);
const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
const files = Array.from(event.target.files);
setSelectedImages((prevImages) => [...prevImages, ...files]);
}
const formOptions = { resolver: zodResolver(articleSchema) };
type MicroIssueSchema = z.infer<typeof articleSchema>;
const {
register,
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<MicroIssueSchema>(formOptions);
const TypeId = [
{
key: 1,
label: "Article",
},
{
key: 2,
label: "Magazine",
},
];
const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
const files = Array.from(event.target.files);
setSelectedImages((prevImages) => [...prevImages, ...files]);
}
};
const handleRemoveImage = (index: number) => {
setSelectedImages((prevImages) => prevImages.filter((_, i) => i !== index));
};
// const handleSubmitImage = (event: any) => {
// event.preventDefault();
// // Lakukan penanganan pengunggahan gambar di sini
// if (selectedImage) {
// console.log('Gambar yang dipilih:', selectedImage);
// // Anda dapat melakukan pengunggahan gambar ke server di sini
// } else {
// console.log('Pilih gambar terlebih dahulu.');
// }
// };
const handleClose = (tagsToRemove: string) => {
setTags(tags.filter((tag) => tag !== tagsToRemove));
if (tags.length === 1) {
setTags([]);
}
};
const handleAddTags = (e: any) => {
if (newTags.trim() !== "") {
setTags([...tags, newTags.trim()]);
setNewTags("");
e.preventDefault();
}
};
const handleKeyDown = (event: any) => {
if (event.key === "Enter") {
handleAddTags(event);
}
};
async function save(data: any) {
const formData = {
title: title,
typeId: parseInt(String(Array.from(article)[0])),
slug: slug,
tags: tags.join(","),
description: content,
htmlDescription: content,
};
const handleRemoveImage = (index: number) => {
setSelectedImages((prevImages) =>
prevImages.filter((_, i) => i !== index)
);
};
console.log("Form Data:", formData);
const response = await createArticle(formData);
// const handleSubmitImage = (event: any) => {
// event.preventDefault();
// // Lakukan penanganan pengunggahan gambar di sini
// if (selectedImage) {
// console.log('Gambar yang dipilih:', selectedImage);
// // Anda dapat melakukan pengunggahan gambar ke server di sini
// } else {
// console.log('Pilih gambar terlebih dahulu.');
// }
// };
const handleClose = (tagsToRemove: string) => {
setTags(tags.filter((tag) => tag !== tagsToRemove));
if (tags.length === 1) {
setTags([]);
}
};
const handleAddTags = (e: any) => {
if (newTags.trim() !== "") {
setTags([...tags, newTags.trim()]);
setNewTags("");
e.preventDefault();
}
};
const handleKeyDown = (event: any) => {
if (event.key === "Enter") {
handleAddTags(event);
}
};
async function save(data: any) {
const formData = {
title: title,
typeId: parseInt(String(Array.from(article)[0])),
slug: slug,
tags: tags.join(','),
description: content,
htmlDescription: content,
};
console.log("Form Data:", formData);
const response = await createArticle(formData);
if (response?.error) {
error(response.message);
return false;
}
successSubmit("/admin/article");
};
function successSubmit(redirect: any) {
MySwal.fire({
title: "Sukses",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then((result) => {
if (result.isConfirmed) {
router.push(redirect);
}
});
if (response?.error) {
error(response.message);
return false;
}
async function onSubmit(data: any) {
MySwal.fire({
title: "Simpan Data",
text: "",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#d33",
confirmButtonColor: "#3085d6",
confirmButtonText: "Simpan",
}).then((result) => {
if (result.isConfirmed) {
save(data);
}
});
}
return (
<div className='mx-5 my-5 overflow-y-auto'>
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
<Card className='rounded-md p-5 space-y-5'>
<div>
<Input
type="title"
{...register("title")}
value={title}
onChange={(e) => setTitle(e.target.value)}
label="Judul"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
/>
<div className="text-sm text-red-500">
{(title.length === 0 && errors.title) && errors.title.message}
successSubmit("/admin/article");
}
</div>
</div>
<div>
<Select
label="Jenis Artikel"
{...register("article")}
variant="bordered"
labelPlacement='outside'
placeholder="Select"
selectedKeys={article}
className="max-w-xs"
onSelectionChange={setArticle}
>
{TypeId.map((data) => (
<SelectItem key={data.key} value={data.key}>
{data.label}
</SelectItem>
))}
</Select>
<div className="text-sm text-red-500">
{errors.article?.message}
</div>
{/* <p>{article}</p> */}
</div>
<div>
<Input
type="text"
{...register("slug")}
value={slug}
onChange={(e) => setSlug(e.target.value)}
label="Slug"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
/>
<div className="text-sm text-red-500">
{(slug.length === 0 && errors.slug) && errors.slug.message}
</div>
</div>
<div>
<Input
label="Tags (Optional)"
{...register("tags")}
labelPlacement='outside'
type="text"
value={newTags}
onChange={(e) => setNewTags(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Tambahkan tag baru dan tekan Enter"
/>
<div className="text-sm text-red-500">
{(tags.length === 0 && errors.tags) && errors.tags.message}
</div>
<div className="flex gap-2 border border-inherit mt-2 rounded-md p-1 items-center h-11">
{tags.map((tag, index) => (
<Chip color='primary' key={index} onClose={() => handleClose(tag)}>
{tag}
</Chip>
))}
</div>
</div>
<div>
<p className='pb-2'>Description</p>
<JoditEditor
ref={editor}
value={content}
onChange={(newContent) => setContent(newContent)}
className="dark:text-black"
function successSubmit(redirect: any) {
MySwal.fire({
title: "Sukses",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then((result) => {
if (result.isConfirmed) {
router.push(redirect);
}
});
}
/>
<div className="text-sm text-red-500">
{(content.length === 0 && errors.description) && errors.description.message}
</div>
async function onSubmit(data: any) {
MySwal.fire({
title: "Simpan Data",
text: "",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#d33",
confirmButtonColor: "#3085d6",
confirmButtonText: "Simpan",
}).then((result) => {
if (result.isConfirmed) {
save(data);
}
});
}
return (
<div className="mx-5 my-5 overflow-y-auto">
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
<Card className="rounded-md p-5 space-y-5">
<div>
<Input
type="title"
{...register("title")}
value={title}
onChange={(e) => setTitle(e.target.value)}
label="Judul"
variant="bordered"
placeholder="Enter Text"
labelPlacement="outside"
/>
<div className="text-sm text-red-500">
{title.length === 0 && errors.title && errors.title.message}
</div>
</div>
<div>
<Select
label="Jenis Artikel"
{...register("article")}
variant="bordered"
labelPlacement="outside"
placeholder="Select"
selectedKeys={article}
className="max-w-xs"
onSelectionChange={setArticle}
>
{TypeId.map((data) => (
<SelectItem key={data.key} value={data.key}>
{data.label}
</SelectItem>
))}
</Select>
<div className="text-sm text-red-500">
{errors.article?.message}
</div>
{/* <p>{article}</p> */}
</div>
<div>
<p className="text-sm mb-1">Category</p>
<ReactSelect
className="basic-single text-black z-50"
classNames={{
control: (state: any) =>
"!rounded-xl bg-white !border-1 !border-gray-200",
}}
classNamePrefix="select"
onChange={setSelectedCategory}
closeMenuOnSelect={false}
components={animatedComponents}
isClearable={true}
isSearchable={true}
isMulti={true}
placeholder="Category ..."
name="sub-module"
options={dummyCategory}
/>
<div className="text-sm text-red-500">
{(!selectedCategory || selectedCategory?.length < 1) && (
<p>Required</p>
)}
</div>
</div>
<div>
<Input
type="text"
{...register("slug")}
value={slug}
onChange={(e) => setSlug(e.target.value)}
label="Slug"
variant="bordered"
placeholder="Enter Text"
labelPlacement="outside"
/>
<div className="text-sm text-red-500">
{slug.length === 0 && errors.slug && errors.slug.message}
</div>
</div>
<div>
<Input
label="Tags (Optional)"
{...register("tags")}
labelPlacement="outside"
type="text"
value={newTags}
onChange={(e) => setNewTags(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Tambahkan tag baru dan tekan Enter"
/>
<div className="text-sm text-red-500">
{tags.length === 0 && errors.tags && errors.tags.message}
</div>
<div className="flex gap-2 border border-inherit mt-2 rounded-md p-1 items-center h-11">
{tags.map((tag, index) => (
<Chip
color="primary"
key={index}
onClose={() => handleClose(tag)}
>
{tag}
</Chip>
))}
</div>
</div>
<div>
<p className="pb-2">Description</p>
<JoditEditor
ref={editor}
value={content}
onChange={(newContent) => setContent(newContent)}
className="dark:text-black"
/>
<div className="text-sm text-red-500">
{content.length === 0 &&
errors.description &&
errors.description.message}
</div>
</div>
<div>
<p>Attachment (Opsional)</p>
<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-36 border border-gray-100 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-200"
>
<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">
Drag and drop files here
</p>
<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"
onChange={handleImageChange}
/>
</label>
</div>
{selectedImages?.length > 0 ? (
<div>
<h4>Pratinjau:</h4>
<div className="flex gap-2 pt-2">
{selectedImages.map((image, index) => (
<div key={index} className="flex flex-col items-end">
<Chip
color="danger"
size="sm"
className="cursor-pointer"
onClick={() => handleRemoveImage(index)}
>
X
</Chip>
<img
src={URL.createObjectURL(image)}
alt="Pratinjau Gambar"
style={{ maxWidth: "200px", maxHeight: "200px" }}
/>
</div>
<div>
<p>Attachment (Opsional)</p>
<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-36 border border-gray-100 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-200"
>
<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">
Drag and drop files here
</p>
<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" onChange={handleImageChange} />
</label>
</div>
{
selectedImages?.length > 0 ?
<div>
<h4>Pratinjau:</h4>
<div className='flex gap-2 pt-2'>
{selectedImages.map((image, index) => (
<div key={index} className='flex flex-col items-end'>
<Chip
color='danger'
size='sm'
className='cursor-pointer'
onClick={() => handleRemoveImage(index)}
>
X
</Chip>
<img
src={URL.createObjectURL(image)}
alt="Pratinjau Gambar"
style={{ maxWidth: '200px', maxHeight: '200px' }}
/>
</div>
))}
</div>
</div>
: ""
}
</div>
<div className='flex justify-end gap-3'>
<Link href={`/admin/article`}>
<Button
color='danger'
variant="ghost"
>
Cancel
</Button>
</Link>
<Button
type="submit"
color='primary'
variant="solid"
>
Save
</Button>
</div>
</Card>
</form>
</div>
)
))}
</div>
</div>
) : (
""
)}
</div>
<div className="flex justify-end gap-3">
<Link href={`/admin/article`}>
<Button color="danger" variant="ghost">
Cancel
</Button>
</Link>
<Button type="submit" color="primary" variant="solid">
Save
</Button>
</div>
</Card>
</form>
</div>
);
}

View File

@ -27,7 +27,7 @@ export const AdminLayout = ({ children }: Props) => {
return (
<SidebarProvider>
<div className="flex items-center justify-between h-screen p-4">
<div className="flex items-center justify-between h-screen p-1 md:p-4">
<Sidebar sidebarData={isOpen} updateSidebarData={updateSidebarData} />
<div className={`h-full w-full flex flex-col gap-4`}>
<Breadcrumb />

View File

@ -220,7 +220,11 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
}, [isOpen]);
return (
<div className={`flex h-full ${isOpen ? "min-w-[290px]" : "min-w-[80px]"}`}>
<div
className={`hidden md:flex h-full ${
isOpen ? "min-w-[290px]" : "min-w-[80px]"
}`}
>
<div
className={`will-change relative flex h-full flex-col rounded-lg p-4 mb-0 bg-gray-100 dark:bg-stone-950 z-40 transition-width !ease-in-out ${
isOpen ? "w-[288px]" : "w-[80px]"

View File

@ -9,6 +9,7 @@ import {
import { error, success } from "@/config/swal";
import { deleteArticle, getListArticle } from "@/service/article";
import { Article } from "@/types/globals";
import { convertDateFormat } from "@/utils/global";
import { Button } from "@nextui-org/button";
import {
Chip,
@ -47,6 +48,7 @@ const columns = [
type ArticleData = Article & {
no: number;
createdAt: string;
};
export default function ArticleTable() {
@ -66,9 +68,14 @@ export default function ArticleTable() {
}, [page, showData, startDateValue]);
async function initState() {
const startDate: string = `${startDateValue.startDate}`;
const req = { limit: showData, page: page, search: search };
const req = {
limit: showData,
page: page,
search: search,
startDate:
startDateValue.startDate === null ? "" : startDateValue.startDate,
endDate: startDateValue.endDate === null ? "" : startDateValue.endDate,
};
const res = await getListArticle(req);
getTableNumber(parseInt(showData), res.data?.data);
console.log("res.data?.data", res.data);
@ -151,6 +158,8 @@ export default function ArticleTable() {
</div>
</Chip>
);
case "createdAt":
return <p>{convertDateFormat(article.createdAt)}</p>;
case "actions":
return (
@ -211,9 +220,9 @@ export default function ArticleTable() {
return (
<>
<div className="mx-5 my-5">
<div className="p-3">
<div className="flex flex-col items-start rounded-2xl gap-3">
<div className="flex flex-row gap-3 w-full">
<div className="flex flex-col md:flex-row gap-3 w-full">
<div className="flex flex-col gap-1 w-1/3">
<p className="font-semibold text-sm">Search</p>
<Input
@ -274,15 +283,13 @@ export default function ArticleTable() {
</SelectItem>
</Select>
</div>
<div className="flex flex-col gap-1 w-[170px]">
<div className="flex flex-col gap-1 w-full md:w-[340px]">
<p className="font-semibold text-sm">Date</p>
<Datepicker
useRange={false}
asSingle={true}
value={startDateValue}
displayFormat="DD/MM/YYYY"
onChange={(e: any) => setStartDateValue(e)}
inputClassName="z-50 w-full text-sm bg-transparent border-1 border-gray-200 px-2 py-[6px] rounded-xl h-[40px]"
inputClassName="z-50 w-full text-sm bg-transparent border-1 border-gray-200 px-2 py-[6px] rounded-xl h-[40px] text-gray-600 dark:text-gray-300"
/>
</div>
</div>

View File

@ -8,48 +8,58 @@ import { Image } from "@nextui-org/react";
import { FormLayoutIcon } from "../icons";
export const Breadcrumb = () => {
const [currentPage, setCurrentPage] = useState<React.Key>("");
const router = useRouter();
const pathname = usePathname();
const pathnameSplit = pathname.split("/");
pathnameSplit.shift();
let pathnameTransformed = pathnameSplit.map(item => {
let words = item.split('-');
let capitalizedWords = words.map(word => word.charAt(0).toUpperCase() + word.slice(1));
return capitalizedWords.join(' ');
});
const [currentPage, setCurrentPage] = useState<React.Key>("");
const router = useRouter();
const pathname = usePathname();
const pathnameSplit = pathname.split("/");
pathnameSplit.shift();
let pathnameTransformed = pathnameSplit.map((item) => {
let words = item.split("-");
let capitalizedWords = words.map(
(word) => word.charAt(0).toUpperCase() + word.slice(1)
);
return capitalizedWords.join(" ");
});
console.log('pathname : ', pathnameTransformed);
console.log("pathname : ", pathnameTransformed);
useEffect(() =>{
setCurrentPage(pathnameSplit[pathnameSplit.length - 1])
}, [pathnameSplit])
useEffect(() => {
setCurrentPage(pathnameSplit[pathnameSplit.length - 1]);
}, [pathnameSplit]);
const handleAction = (key: any) => {
const keyIndex = pathnameSplit.indexOf(key);
const combinedPath = pathnameSplit.slice(0, keyIndex + 1).join('/');
router.push("/" + combinedPath);
}
const handleAction = (key: any) => {
const keyIndex = pathnameSplit.indexOf(key);
const combinedPath = pathnameSplit.slice(0, keyIndex + 1).join("/");
router.push("/" + combinedPath);
};
return (
<div className="flex h-[100px] gap-0 grid rounded-lg border-small ml-4">
<div className="px-6">
<div className="flex flex-row justify-between items-center">
<div className="pt-1">
<p className="text-2xl font-semibold mb-2">{pathnameTransformed[pathnameTransformed.length - 1]}</p>
<Breadcrumbs underline="active" onAction={(key) => handleAction(key)}>
{pathnameTransformed?.map((item, index) => (
<BreadcrumbItem key={pathnameSplit[index]} isCurrent={pathnameSplit[index] === currentPage}>
{item}
</BreadcrumbItem>
))}
</Breadcrumbs>
</div>
<div className="pt-2">
<FormLayoutIcon width={50} height={50} />
</div>
</div>
</div>
</div >
);
return (
<div className="h-[100px] gap-0 grid rounded-lg border-small">
<div className="px-4 md:px-8">
<div className="flex flex-row justify-between items-center">
<div className="pt-1">
<p className="text-2xl font-semibold mb-2">
{pathnameTransformed[pathnameTransformed.length - 1]}
</p>
<Breadcrumbs
underline="active"
onAction={(key) => handleAction(key)}
>
{pathnameTransformed?.map((item, index) => (
<BreadcrumbItem
key={pathnameSplit[index]}
isCurrent={pathnameSplit[index] === currentPage}
>
{item}
</BreadcrumbItem>
))}
</Breadcrumbs>
</div>
<div className="pt-2">
<FormLayoutIcon width={50} height={50} />
</div>
</div>
</div>
</div>
);
};

439
package-lock.json generated
View File

@ -49,6 +49,7 @@
"react-dom": "18.2.0",
"react-hook-form": "^7.50.1",
"react-icons": "^5.0.1",
"react-select": "^5.8.3",
"react-sweetalert2": "^0.6.0",
"react-tailwindcss-datepicker": "^1.6.6",
"react-tweet": "^3.2.0",
@ -78,6 +79,76 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@babel/code-frame": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"dependencies": {
"@babel/helper-validator-identifier": "^7.25.9",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/generator": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz",
"integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
"dependencies": {
"@babel/parser": "^7.26.2",
"@babel/types": "^7.26.0",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
"integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
"dependencies": {
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
"integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
"dependencies": {
"@babel/types": "^7.26.0"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/runtime": {
"version": "7.23.2",
"license": "MIT",
@ -88,6 +159,101 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
"integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
"dependencies": {
"@babel/code-frame": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
"integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
"dependencies": {
"@babel/code-frame": "^7.25.9",
"@babel/generator": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/template": "^7.25.9",
"@babel/types": "^7.25.9",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse/node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/types": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
"integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@emotion/babel-plugin": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz",
"integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==",
"dependencies": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
"@emotion/hash": "^0.9.2",
"@emotion/memoize": "^0.9.0",
"@emotion/serialize": "^1.2.0",
"babel-plugin-macros": "^3.1.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^4.0.0",
"find-root": "^1.1.0",
"source-map": "^0.5.7",
"stylis": "4.2.0"
}
},
"node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
"integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
},
"node_modules/@emotion/cache": {
"version": "11.13.1",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz",
"integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==",
"dependencies": {
"@emotion/memoize": "^0.9.0",
"@emotion/sheet": "^1.4.0",
"@emotion/utils": "^1.4.0",
"@emotion/weak-memoize": "^0.4.0",
"stylis": "4.2.0"
}
},
"node_modules/@emotion/cache/node_modules/@emotion/memoize": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
"integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
},
"node_modules/@emotion/hash": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="
},
"node_modules/@emotion/is-prop-valid": {
"version": "0.8.8",
"license": "MIT",
@ -101,6 +267,74 @@
"license": "MIT",
"optional": true
},
"node_modules/@emotion/react": {
"version": "11.13.3",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz",
"integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==",
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.12.0",
"@emotion/cache": "^11.13.0",
"@emotion/serialize": "^1.3.1",
"@emotion/use-insertion-effect-with-fallbacks": "^1.1.0",
"@emotion/utils": "^1.4.0",
"@emotion/weak-memoize": "^0.4.0",
"hoist-non-react-statics": "^3.3.1"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@emotion/serialize": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz",
"integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==",
"dependencies": {
"@emotion/hash": "^0.9.2",
"@emotion/memoize": "^0.9.0",
"@emotion/unitless": "^0.10.0",
"@emotion/utils": "^1.4.1",
"csstype": "^3.0.2"
}
},
"node_modules/@emotion/serialize/node_modules/@emotion/memoize": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
"integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
},
"node_modules/@emotion/sheet": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
"integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="
},
"node_modules/@emotion/unitless": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
"integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg=="
},
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz",
"integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==",
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@emotion/utils": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz",
"integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA=="
},
"node_modules/@emotion/weak-memoize": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg=="
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"license": "MIT",
@ -301,38 +535,43 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
"license": "MIT",
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dependencies": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.9"
"@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.1",
"license": "MIT",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.1.2",
"license": "MIT",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"license": "MIT"
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.20",
"license": "MIT",
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@ -2653,6 +2892,11 @@
"version": "20.5.7",
"license": "MIT"
},
"node_modules/@types/parse-json": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
"integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="
},
"node_modules/@types/prop-types": {
"version": "15.7.10",
"license": "MIT"
@ -2683,6 +2927,14 @@
"@types/react": "*"
}
},
"node_modules/@types/react-transition-group": {
"version": "4.4.11",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz",
"integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": {
"version": "0.16.6",
"license": "MIT"
@ -3087,6 +3339,20 @@
"dequal": "^2.0.3"
}
},
"node_modules/babel-plugin-macros": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"cosmiconfig": "^7.0.0",
"resolve": "^1.19.0"
},
"engines": {
"node": ">=10",
"npm": ">=6"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"license": "MIT"
@ -3323,6 +3589,34 @@
"version": "0.0.1",
"license": "MIT"
},
"node_modules/convert-source-map": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
},
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
"dependencies": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
"parse-json": "^5.0.0",
"path-type": "^4.0.0",
"yaml": "^1.10.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/cosmiconfig/node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"engines": {
"node": ">= 6"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"license": "MIT",
@ -3467,6 +3761,15 @@
"node": ">=6.0.0"
}
},
"node_modules/dom-helpers": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
"dependencies": {
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
}
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
@ -3548,6 +3851,19 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dependencies": {
"is-arrayish": "^0.2.1"
}
},
"node_modules/error-ex/node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
},
"node_modules/es-abstract": {
"version": "1.22.3",
"license": "MIT",
@ -4094,6 +4410,11 @@
"node": ">=8"
}
},
"node_modules/find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
},
"node_modules/find-up": {
"version": "5.0.0",
"license": "MIT",
@ -4443,6 +4764,14 @@
"node": ">= 0.4"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/html-dom-parser": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-5.0.8.tgz",
@ -4910,10 +5239,26 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/jsesc": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
"integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
"node": ">=6"
}
},
"node_modules/json-buffer": {
"version": "3.0.1",
"license": "MIT"
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"license": "MIT"
@ -5053,6 +5398,11 @@
"node": ">=10"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
"node_modules/merge2": {
"version": "1.4.1",
"license": "MIT",
@ -5383,6 +5733,23 @@
"node": ">=6"
}
},
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
"json-parse-even-better-errors": "^2.3.0",
"lines-and-columns": "^1.1.6"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"license": "MIT",
@ -5743,6 +6110,26 @@
}
}
},
"node_modules/react-select": {
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.3.tgz",
"integrity": "sha512-lVswnIq8/iTj1db7XCG74M/3fbGB6ZaluCzvwPGT5ZOjCdL/k0CLWhEK0vCBLuU5bHTEf6Gj8jtSvi+3v+tO1w==",
"dependencies": {
"@babel/runtime": "^7.12.0",
"@emotion/cache": "^11.4.0",
"@emotion/react": "^11.8.1",
"@floating-ui/dom": "^1.0.1",
"@types/react-transition-group": "^4.4.0",
"memoize-one": "^6.0.0",
"prop-types": "^15.6.0",
"react-transition-group": "^4.3.0",
"use-isomorphic-layout-effect": "^1.1.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-style-singleton": {
"version": "2.2.1",
"license": "MIT",
@ -5800,6 +6187,21 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
},
"peerDependencies": {
"react": ">=16.6.0",
"react-dom": ">=16.6.0"
}
},
"node_modules/react-tweet": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-tweet/-/react-tweet-3.2.0.tgz",
@ -6078,6 +6480,14 @@
"node": ">=8"
}
},
"node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"license": "BSD-3-Clause",
@ -6212,6 +6622,11 @@
}
}
},
"node_modules/stylis": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
},
"node_modules/sucrase": {
"version": "3.34.0",
"license": "MIT",

View File

@ -50,6 +50,7 @@
"react-dom": "18.2.0",
"react-hook-form": "^7.50.1",
"react-icons": "^5.0.1",
"react-select": "^5.8.3",
"react-sweetalert2": "^0.6.0",
"react-tailwindcss-datepicker": "^1.6.6",
"react-tweet": "^3.2.0",

View File

@ -7,12 +7,12 @@ import {
} from "./http-config/axios-base-service";
export async function getListArticle(props: PaginationRequest) {
const { page, limit, search } = props;
const { page, limit, search, startDate, endDate } = props;
const headers = {
"content-type": "application/json",
};
return await httpGet(
`/articles?limit=${limit}&page=${page}&title=${search}`,
`/articles?limit=${limit}&page=${page}&title=${search}&startDate=${startDate}&endDate=${endDate}`,
headers
);
}

View File

@ -59,4 +59,6 @@ export type PaginationRequest = {
limit: string;
page: number;
search: string;
startDate?: string;
endDate?: string;
};