feat: master article

This commit is contained in:
amd123 2024-04-19 20:26:27 +07:00
parent 15e68f809d
commit a6c22e392a
44 changed files with 3835 additions and 114 deletions

View File

@ -0,0 +1,30 @@
"use client"
import { Image } from "@nextui-org/react";
export default function CustumPage() {
return (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 mx-[24px] h-[120px] my-5 rounded-md">
<div>
<div className="flex flex-row justify-between items-center">
<div>
<p className="text-2xl font-semibold ml-5 ">Custum Form</p>
<p className="text-gray-300 ml-5">custom designed elemnt</p>
</div>
<div className="pr-5">
<Image
width={110}
alt="NextUI hero Image"
src="https://modernize-nextjs-dark.vercel.app/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FChatBc.3d875e2e.png&w=256&q=75"
/>
</div>
</div>
</div>
</div >
{/* <CreateCustomForm /> */}
</div>
</div>
);
}

View File

@ -0,0 +1,38 @@
"use client"
import CreateCustomForm from "@/components/form/form-costum/custom-form";
import CreateHorizontalForm from "@/components/form/form-horizontal/custom-form";
import CreateWizardForm from "@/components/form/form-wizard/wizard-form";
import AuthtorsTable from "@/components/table/authors-table";
import CustomerTable from "@/components/table/customers-table";
import InvoiceTable from "@/components/table/invoice-table";
import UserTable from "@/components/table/article-table";
import UsersTable from "@/components/table/users-table";
import { Card, Divider, Image } from "@nextui-org/react";
export default function HorizontalPage() {
return (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 h-[120px] my-5 rounded-md mx-[24px]">
<div>
<div className="flex flex-row justify-between items-center">
<div>
<p className="text-2xl font-semibold ml-5 ">Horizontal Form</p>
<p className="text-gray-500 ml-5">Home<span className="text-black">{" > "}</span> <span className=" text-white">Horizontal Form</span></p>
</div>
<div className="pr-5">
<Image
width={110}
alt="NextUI hero Image"
src="https://modernize-nextjs-dark.vercel.app/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FChatBc.3d875e2e.png&w=256&q=75"
/>
</div>
</div>
</div>
</div >
<CreateHorizontalForm />
</div>
</div>
);
}

View File

@ -0,0 +1,40 @@
"use client"
import CreateLayoutForm from "@/components/form/form-layout/layout-form";
import CreateValidationForm from "@/components/form/form-validation/validation-form";
import CreateWizardForm from "@/components/form/form-wizard/wizard-form";
import AuthtorsTable from "@/components/table/authors-table";
import CustomerTable from "@/components/table/customers-table";
import InvoiceTable from "@/components/table/invoice-table";
import UserTable from "@/components/table/article-table";
import UsersTable from "@/components/table/users-table";
import { Card, Divider, Image } from "@nextui-org/react";
import { useEffect, useState } from "react";
export default function FormLayoutPage() {
return (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 mx-[24px] h-[120px] my-5 rounded-md">
<div>
<div className="flex flex-row justify-between items-center">
<div>
<p className="text-2xl font-semibold ml-5 text-white">Form Layout</p>
<p className="text-white ml-5">Home<span className="text-white">{" > "}</span> <span className=" text-white">Form Layout</span></p>
</div>
<div className="pr-5">
<Image
width={110}
alt="NextUI hero Image"
src="https://modernize-nextjs-dark.vercel.app/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FChatBc.3d875e2e.png&w=256&q=75"
/>
</div>
</div>
</div>
</div >
<CreateLayoutForm />
</div>
</div>
);
}

View File

@ -0,0 +1,37 @@
"use client"
import CreateValidationForm from "@/components/form/form-validation/validation-form";
import CreateWizardForm from "@/components/form/form-wizard/wizard-form";
import AuthtorsTable from "@/components/table/authors-table";
import CustomerTable from "@/components/table/customers-table";
import InvoiceTable from "@/components/table/invoice-table";
import UserTable from "@/components/table/article-table";
import UsersTable from "@/components/table/users-table";
import { Card, Divider, Image } from "@nextui-org/react";
export default function ValidationPage() {
return (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 mx-[24px] h-[120px] my-5 rounded-md">
<div>
<div className="flex flex-row justify-between items-center">
<div>
<p className="text-2xl font-semibold ml-5 ">Form Validation</p>
<p className="text-gray-500 ml-5">Home<span className="text-black">{" > "}</span> <span className=" text-white">Form Validation</span></p>
</div>
<div className="pr-5">
<Image
width={110}
alt="NextUI hero Image"
src="https://modernize-nextjs-dark.vercel.app/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FChatBc.3d875e2e.png&w=256&q=75"
/>
</div>
</div>
</div>
</div >
<CreateValidationForm />
</div>
</div>
);
}

View File

@ -0,0 +1,32 @@
"use client"
import CreateValidationForm from "@/components/form/form-validation/validation-form";
import CreateVerticalForm from "@/components/form/form-vertical/vertical-form";
import { Card, Divider, Image } from "@nextui-org/react";
export default function VerticalPage() {
return (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 mx-[24px] h-[120px] my-5 rounded-md">
<div>
<div className="flex flex-row justify-between items-center">
<div>
<p className="text-2xl font-semibold ml-5 ">Vertical Form</p>
<p className="text-gray-500 ml-5">Home<span className="text-black">{" > "}</span> <span className=" text-white">Verical Form</span></p>
</div>
<div className="pr-5">
<Image
width={110}
alt="NextUI hero Image"
src="https://modernize-nextjs-dark.vercel.app/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FChatBc.3d875e2e.png&w=256&q=75"
/>
</div>
</div>
</div>
</div >
<CreateVerticalForm />
</div>
</div>
);
}

View File

@ -0,0 +1,44 @@
"use client"
import CreateWizardForm from "@/components/form/form-wizard/wizard-form";
import AuthtorsTable from "@/components/table/authors-table";
import CustomerTable from "@/components/table/customers-table";
import InvoiceTable from "@/components/table/invoice-table";
import UserTable from "@/components/table/article-table";
import UsersTable from "@/components/table/users-table";
import { Card, Divider, Image } from "@nextui-org/react";
export default function WizardPage() {
return (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 mx-[24px] h-[120px] my-5 rounded-md">
<div>
<div className="flex flex-row justify-between items-center">
<div>
<p className="text-2xl font-semibold ml-5 ">Form Wizard</p>
<p className="text-white ml-5">This is Form WizardPage</p>
</div>
<div className="pr-5">
<Image
width={110}
alt="NextUI hero Image"
src="https://modernize-nextjs-dark.vercel.app/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FChatBc.3d875e2e.png&w=256&q=75"
/>
</div>
</div>
</div>
</div >
<Card className="rounded-md mx-[24px]">
<p className="ml-5 mt-5 text-lg">Form Wizard</p>
<Divider className="w-full my-3" />
<div>
<CreateWizardForm />
</div>
</Card>
</div>
</div>
);
}

View File

@ -0,0 +1,10 @@
import FormArticle from '@/components/form/form-article'
import { Card } from '@nextui-org/react'
export default function CreateArticle() {
return (
<Card className="h-[96vh] rounded-md my- ml-3 border bg-transparent">
<FormArticle />
</Card>
)
}

View File

@ -0,0 +1,24 @@
"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>
</div>
);
}

View File

@ -0,0 +1,39 @@
"use client"
import { Card, Divider, Image } from "@nextui-org/react";
export default function BasicPage() {
return (
<div className=" h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 w-full h-[120px] my-5 rounded-md">
<div>
<div className="flex flex-row justify-between items-center">
<div>
<p className="text-2xl font-semibold ml-5 ">Basic Table</p>
<p className="text-gray-500 ml-5">Home<span className="text-black">{" > "}</span> <span className=" text-white">Basic Table</span></p>
</div>
<div className="pr-5">
<Image
width={110}
alt="NextUI hero Image"
src="https://modernize-nextjs-dark.vercel.app/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FChatBc.3d875e2e.png&w=256&q=75"
/>
</div>
</div>
</div>
</div>
<Card className="rounded-md my-5">
<p className="ml-5 mt-5 text-lg">Basic Table</p>
<Divider className="w-full my-3" />
<div>
{/* <UsersTable />
<UserTable />
<CustomerTable />
<InvoiceTable />
<AuthtorsTable /> */}
</div>
</Card>
</div>
</div>
);
}

View File

@ -0,0 +1,11 @@
import DashboardContainer from "@/components/main/dashboard/dashboard-container";
export default function AdminPage() {
return (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<DashboardContainer />
</div>
</div>
)
}

View File

@ -0,0 +1,15 @@
"use client";
import { AdminLayout } from "@/components/layout/admin-layout";
export default function AdminPageLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<AdminLayout>
{children}
</AdminLayout>
);
}

View File

@ -0,0 +1,8 @@
import { ThemeSwitch } from "@/components/theme-switch";
export default function Submenu1Page() {
return (
<div className="flex mt-10 mx-4 md:m-0">Submenu1
</div>
)
}

View File

@ -0,0 +1,8 @@
import { ThemeSwitch } from "@/components/theme-switch";
export default function Submenu2Page() {
return (
<div className="flex mt-10 mx-4 md:m-0">Submenu2
</div>
)
}

View File

@ -0,0 +1,11 @@
"use client"
export default function HomePage() {
return (
<div className=" h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="px-4">
<h3>Welcome</h3>
</div>
</div>
);
}

View File

@ -1,13 +0,0 @@
import HumasAdminLayout from "@/components/layout/HumasAdminLayout";
export default function HumasLayoutAdmin({
children,
}: {
children: React.ReactNode;
}) {
return (
<HumasAdminLayout >
{children}
</HumasAdminLayout>
);
}

View File

@ -1,46 +0,0 @@
import React from 'react'
export default function AdminHumasPage() {
return (
<div className=''>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
</div>
)
}

View File

@ -37,7 +37,7 @@ export default function RootLayout({
)} )}
> >
<Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}> <Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}>
<main className="bg-white"> <main className="">
{children} {children}
</main> </main>
</Providers> </Providers>

View File

@ -1,28 +1,55 @@
import { Button, Card, CardBody, CardFooter, Image, Tab, Tabs } from '@nextui-org/react'; import { Button, Card, CardBody, CardFooter, Image, Tab, Tabs } from '@nextui-org/react';
import React from 'react' import React from 'react'
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import { Navigation, Pagination } from 'swiper/modules';
export default function MedolUpdate() { export default function MedolUpdate() {
let tabs = [
const mediaHubUpdate = [
{ {
id: "photos", id: 1,
label: "Photos", image: '/temp/mediahub1.png',
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." title: 'Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan',
createdDate: '12 Januari 2024',
time: '13:00 WITA'
}, },
{ {
id: "music", id: 2,
label: "Music", image: '/temp/mediahub2.png',
content: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." title: 'Kapolri Tinjau Langsung Kondisi Pelayanan Pemudik di Dermaga 1 Pelabuhan Merak',
createdDate: '14 Januari 2024',
time: '13:00 WIB'
}, },
{ {
id: "videos", id: 3,
label: "Videos", image: '/temp/mediahub2.png',
content: "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." title: 'Kapolri Tinjau Langsung Kondisi Pelayanan Pemudik di Dermaga 1 Pelabuhan Merak',
} createdDate: '14 Januari 2024',
]; time: '13:00 WIB'
},
{
id: 4,
image: '/temp/mediahub2.png',
title: 'Kapolri Tinjau Langsung Kondisi Pelayanan Pemudik di Dermaga 1 Pelabuhan Merak',
createdDate: '14 Januari 2024',
time: '13:00 WIB'
},
{
id: 5,
image: '/temp/mediahub2.png',
title: 'Kapolri Tinjau Langsung Kondisi Pelayanan Pemudik di Dermaga 1 Pelabuhan Merak',
createdDate: '14 Januari 2024',
time: '13:00 WIB'
},
]
return ( return (
<div className='border-2 rounded-lg py-2'> <div className='border-2 rounded-lg py-2'>
<div className='text-2xl font-semibold underline underline-offset-4 text-center decoration-red-600 '> <div className='text-2xl font-semibold underline underline-offset-4 text-center decoration-red-600 '>
Media Online Update Top 5 News Update
</div> </div>
<div className='bg-white text-black p-1 md:p-5 space-y-5'> <div className='bg-white text-black p-1 md:p-5 space-y-5'>
<Tabs <Tabs
@ -32,40 +59,33 @@ export default function MedolUpdate() {
}} }}
aria-label="Options" color='warning' className='flex justify-center'> aria-label="Options" color='warning' className='flex justify-center'>
<Tab key="mediahub" title="MediaHUB Update"> <Tab key="mediahub" title="MediaHUB Update">
<div className='flex gap-5 justify-center pt-3'> <Swiper
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'> navigation={true}
<CardBody className="overflow-visible p-0"> modules={[Navigation, Pagination]}
<Image spaceBetween={40}
shadow="sm" slidesPerView={2}
radius="lg" pagination={true}
width="300%" className="mySwiper">
alt="tes" {mediaHubUpdate.map((newsItem) => (
className="object-cover h-[270px]" <SwiperSlide>
src='/temp/mediahub1.png' <Card shadow="sm" className=' bg-white text-black border-2'>
/> <CardBody className="overflow-visible p-0">
</CardBody> <Image
<CardFooter className="flex flex-col items-start text-left"> radius="lg"
<p className='text-xs'>02-04-2024 09:31 WITA</p> width="300%"
<b className=''>Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan</b> alt="tes"
</CardFooter> className="object-cover h-[270px]"
</Card> src={newsItem.image}
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'> />
<CardBody className="overflow-visible p-0"> </CardBody>
<Image <CardFooter className="flex flex-col items-start text-left">
shadow="sm" <p className='text-xs'>02-04-2024 09:31 WITA</p>
radius="lg" <b className=''>Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan</b>
width="100%" </CardFooter>
alt="tes" </Card>
className="w-full object-cover h-[270px]" </SwiperSlide>
src='/temp/mediahub2.png' ))}
/> </Swiper>
</CardBody>
<CardFooter className="flex flex-col items-start text-left">
<p className='text-xs'>02-04-2024 09:16 WIB</p>
<b>Kapolri Tinjau Langsung Kondisi Pelayanan Pemudik di Dermaga 1 Pelabuhan Merak</b>
</CardFooter>
</Card>
</div>
<div className='text-center pt-6'> <div className='text-center pt-6'>
<Button <Button
className='bg-white text-[#DD8306] font-bold w-56' className='bg-white text-[#DD8306] font-bold w-56'

View File

@ -0,0 +1,264 @@
'use client'
import { Button, Card, Chip, Input, Select, SelectItem, Selection } from '@nextui-org/react'
import JoditEditor from 'jodit-react';
import React, { useRef, useState } from 'react'
import * as z from "zod";
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { createArticle } from '@/service/article';
import { error } from '@/config/swal';
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(1, { message: "Required" }).optional(),
});
export default function FormArticle() {
const [id, setId] = useState<any>();
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 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 CategoryArticle = [
{
key: 1,
label: "Article"
},
{
key: 2,
label: "Magazine"
},
]
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 = {
id: id,
title,
jenisArtikel: article,
slug,
tags,
description: content,
};
console.log("Form Data:", formData);
if (id != undefined) {
formData.id = id;
}
const response = await createArticle(formData);
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}
</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"
/>
<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" />
</label>
</div>
</div>
<Button
type="submit"
variant="solid"
className="bg-gradient-to-t from-[#8E5C18] to-[#DBC17B] rounded-md text-white lg:mr-14"
>
Save Data
</Button>
</Card>
</form>
</div>
)
}

View File

@ -771,3 +771,709 @@ export const Checklist = ({
</defs> </defs>
</svg> </svg>
); );
export const ChevronLeftIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}
>
<path fill="currentColor" d="m14 18l-6-6l6-6l1.4 1.4l-4.6 4.6l4.6 4.6z" />
</svg>
);
export const DotsYIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24">
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
d="M12 5.92A.96.96 0 1 0 12 4a.96.96 0 0 0 0 1.92m0 7.04a.96.96 0 1 0 0-1.92a.96.96 0 0 0 0 1.92M12 20a.96.96 0 1 0 0-1.92a.96.96 0 0 0 0 1.92">
</path>
</svg>
);
export const DotsXIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24">
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0">
</path>
</svg>
);
export const EyeIconMdi = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
fill={fill}
{...props}
>
<path
fill="currentColor"
d="M12 9a3 3 0 0 0-3 3a3 3 0 0 0 3 3a3 3 0 0 0 3-3a3 3 0 0 0-3-3m0 8a5 5 0 0 1-5-5a5 5 0 0 1 5-5a5 5 0 0 1 5 5a5 5 0 0 1-5 5m0-12.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5Z"
/>
</svg>
);
export const OnlineIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 256 256">
<path
fill="currentColor"
d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24m0 192a88 88 0 1 1 88-88a88.1 88.1 0 0 1-88 88">
</path>
</svg>
);
export const OfflineIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 32 32">
<path
fill="currentColor"
d="M16 30a14 14 0 1 1 14-14a14 14 0 0 1-14 14m0-26a12 12 0 1 0 12 12A12 12 0 0 0 16 4">
</path>
<path
fill="currentColor"
d="M20.59 22L15 16.41V7h2v8.58l5 5.01z">
</path>
</svg>
);
export const CreateIconIon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 512 512"
{...props}
>
<path
fill="currentColor"
d="M459.94 53.25a16.06 16.06 0 0 0-23.22-.56L424.35 65a8 8 0 0 0 0 11.31l11.34 11.32a8 8 0 0 0 11.34 0l12.06-12c6.1-6.09 6.67-16.01.85-22.38ZM399.34 90L218.82 270.2a9 9 0 0 0-2.31 3.93L208.16 299a3.91 3.91 0 0 0 4.86 4.86l24.85-8.35a9 9 0 0 0 3.93-2.31L422 112.66a9 9 0 0 0 0-12.66l-9.95-10a9 9 0 0 0-12.71 0Z"
/>
<path
fill="currentColor"
d="M386.34 193.66L264.45 315.79A41.08 41.08 0 0 1 247.58 326l-25.9 8.67a35.92 35.92 0 0 1-44.33-44.33l8.67-25.9a41.08 41.08 0 0 1 10.19-16.87l122.13-121.91a8 8 0 0 0-5.65-13.66H104a56 56 0 0 0-56 56v240a56 56 0 0 0 56 56h240a56 56 0 0 0 56-56V199.31a8 8 0 0 0-13.66-5.65Z"
/>
</svg>
);
export const DeleteIcon = ({
size,
height = 12,
width = 10,
fill = "none",
...props
}: IconSvgProps) => (
<svg
height={size || height}
width={size || width}
viewBox="0 0 10 12"
fill={fill}
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M9.66683 0.666667H7.3335L6.66683 0H3.3335L2.66683 0.666667H0.333496V2H9.66683M1.00016 10.6667C1.00016 11.0203 1.14064 11.3594 1.39069 11.6095C1.64074 11.8595 1.97987 12 2.3335 12H7.66683C8.02045 12 8.35959 11.8595 8.60964 11.6095C8.85969 11.3594 9.00016 11.0203 9.00016 10.6667V2.66667H1.00016V10.6667Z"
fill="currentColor"
/>
</svg>
);
export const AccIcon = ({
size,
height = 12,
width = 10,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 2048 2048">
<path
fill="currentColor"
d="M640 1755L19 1133l90-90l531 530L1939 275l90 90z">
</path>
</svg>
);
export const CloseIcon = ({
size,
height = 12,
width = 10,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 512 512">
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={32}
d="M368 368L144 144m224 0L144 368">
</path>
</svg>
);
export const RefundIcon = ({
size,
height = 12,
width = 10,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24">
<path
fill="currentColor"
d="m4 8l-.707.707L2.586 8l.707-.707zm5 12a1 1 0 1 1 0-2zm-.707-6.293l-5-5l1.414-1.414l5 5zm-5-6.414l5-5l1.414 1.414l-5 5zM4 7h10.5v2H4zm10.5 13H9v-2h5.5zm6.5-6.5a6.5 6.5 0 0 1-6.5 6.5v-2a4.5 4.5 0 0 0 4.5-4.5zM14.5 7a6.5 6.5 0 0 1 6.5 6.5h-2A4.5 4.5 0 0 0 14.5 9z">
</path>
</svg>
);
export const AddIcon = ({
size,
height = 12,
width = 12,
fill = "none",
...props
}: IconSvgProps) => (
<svg
height={size || height}
width={size || width}
viewBox="0 0 12 12"
fill={fill}
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M5.1665 6.83341H0.166504V5.16675H5.1665V0.166748H6.83317V5.16675H11.8332V6.83341H6.83317V11.8334H5.1665V6.83341Z"
fill="currentColor"
/>
</svg>
);
export const CompanyIcon = ({
size,
height = 12,
width = 12,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}
>
<path
fill="currentColor"
d="M10 2v2.26l2 1.33V4h10v15h-5v2h7V2zM7.5 5L0 10v11h15V10zM14 6v.93L15.61 8H16V6zm4 0v2h2V6zM7.5 7.5L13 11v8h-3v-6H5v6H2v-8zM18 10v2h2v-2zm0 4v2h2v-2z">
</path>
</svg>
);
export const EmailIcon = ({
size,
height = 12,
width = 12,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}
>
<path
fill="currentColor"
d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2zm-2 0l-8 5l-8-5zm0 12H4V8l8 5l8-5z">
</path>
</svg>
);
export const PhoneIcon = ({
size,
height = 12,
width = 12,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 256 256"
{...props}
>
<path
fill="currentColor"
d="m222.37 158.46l-47.11-21.11l-.13-.06a16 16 0 0 0-15.17 1.4a8.12 8.12 0 0 0-.75.56L134.87 160c-15.42-7.49-31.34-23.29-38.83-38.51l20.78-24.71c.2-.25.39-.5.57-.77a16 16 0 0 0 1.32-15.06v-.12L97.54 33.64a16 16 0 0 0-16.62-9.52A56.26 56.26 0 0 0 32 80c0 79.4 64.6 144 144 144a56.26 56.26 0 0 0 55.88-48.92a16 16 0 0 0-9.51-16.62M176 208A128.14 128.14 0 0 1 48 80a40.2 40.2 0 0 1 34.87-40a.61.61 0 0 0 0 .12l21 47l-20.67 24.74a6.13 6.13 0 0 0-.57.77a16 16 0 0 0-1 15.7c9.06 18.53 27.73 37.06 46.46 46.11a16 16 0 0 0 15.75-1.14a8.44 8.44 0 0 0 .74-.56L168.89 152l47 21.05h.11A40.21 40.21 0 0 1 176 208">
</path>
</svg>
);
export const MessageIcon = ({
size,
height = 12,
width = 12,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}
>
<path
fill="currentColor"
d="M2 6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2h-4.586l-2.707 2.707a1 1 0 0 1-1.414 0L8.586 19H4a2 2 0 0 1-2-2zm18 0H4v11h5a1 1 0 0 1 .707.293L12 19.586l2.293-2.293A1 1 0 0 1 15 17h5zM6 9.5a1 1 0 0 1 1-1h10a1 1 0 1 1 0 2H7a1 1 0 0 1-1-1m0 4a1 1 0 0 1 1-1h6a1 1 0 1 1 0 2H7a1 1 0 0 1-1-1">
</path>
</svg>
);
export const UserIcon = ({
size,
height = 12,
width = 12,
fill = "none",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 32 32"
{...props}
>
<path
fill="currentColor"
d="M16 4a5 5 0 1 1-5 5a5 5 0 0 1 5-5m0-2a7 7 0 1 0 7 7a7 7 0 0 0-7-7m10 28h-2v-5a5 5 0 0 0-5-5h-6a5 5 0 0 0-5 5v5H6v-5a7 7 0 0 1 7-7h6a7 7 0 0 1 7 7z">
</path>
</svg>
);
export const EyeOffIconMdi = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
fill={fill}
{...props}
>
<path
fill="currentColor"
d="M11.83 9L15 12.16V12a3 3 0 0 0-3-3h-.17m-4.3.8l1.55 1.55c-.05.21-.08.42-.08.65a3 3 0 0 0 3 3c.22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53a5 5 0 0 1-5-5c0-.79.2-1.53.53-2.2M2 4.27l2.28 2.28l.45.45C3.08 8.3 1.78 10 1 12c1.73 4.39 6 7.5 11 7.5c1.55 0 3.03-.3 4.38-.84l.43.42L19.73 22L21 20.73L3.27 3M12 7a5 5 0 0 1 5 5c0 .64-.13 1.26-.36 1.82l2.93 2.93c1.5-1.25 2.7-2.89 3.43-4.75c-1.73-4.39-6-7.5-11-7.5c-1.4 0-2.74.25-4 .7l2.17 2.15C10.74 7.13 11.35 7 12 7Z"
/>
</svg>
);
export const DateIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 16 16"
{...props}
>
<path
fill="currentColor"
d="M14.5 16h-13C.67 16 0 15.33 0 14.5v-12C0 1.67.67 1 1.5 1h13c.83 0 1.5.67 1.5 1.5v12c0 .83-.67 1.5-1.5 1.5M1.5 2c-.28 0-.5.22-.5.5v12c0 .28.22.5.5.5h13c.28 0 .5-.22.5-.5v-12c0-.28-.22-.5-.5-.5z">
</path>
<path
fill="currentColor"
d="M4.5 4c-.28 0-.5-.22-.5-.5v-3c0-.28.22-.5.5-.5s.5.22.5.5v3c0 .28-.22.5-.5.5m7 0c-.28 0-.5-.22-.5-.5v-3c0-.28.22-.5.5-.5s.5.22.5.5v3c0 .28-.22.5-.5.5m4 2H.5C.22 6 0 5.78 0 5.5S.22 5 .5 5h15c.28 0 .5.22.5.5s-.22.5-.5.5">
</path>
</svg>
);
export const WarningIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}
>
<path
fill="currentColor"
d="M12 20a8 8 0 1 0 0-16a8 8 0 0 0 0 16m0 2C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m-1-6h2v2h-2zm0-10h2v8h-2z">
</path>
</svg>
);
export const PasswordIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}
>
<path
fill="currentColor"
d="M12 17a2 2 0 0 1-2-2c0-1.11.89-2 2-2a2 2 0 0 1 2 2a2 2 0 0 1-2 2m6 3V10H6v10zm0-12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V10c0-1.11.89-2 2-2h1V6a5 5 0 0 1 5-5a5 5 0 0 1 5 5v2zm-6-5a3 3 0 0 0-3 3v2h6V6a3 3 0 0 0-3-3">
</path>
</svg>
);
export const TimeIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 32 32"
{...props}
>
<path
fill="currentColor"
d="M16 30a14 14 0 1 1 14-14a14 14 0 0 1-14 14m0-26a12 12 0 1 0 12 12A12 12 0 0 0 16 4">
</path>
<path
fill="currentColor"
d="M20.59 22L15 16.41V7h2v8.58l5 5.01z">
</path>
</svg>
);
export const VolumeLowIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}
>
<path
fill="none"
stroke="currentColor"
strokeWidth={2}
d="M1 8v8h5.099L12 21V3L6 8zm14 8a4 4 0 1 0 0-8">
</path></svg>
);
export const VolumeHighIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 16 16"
{...props}
>
<path
fill="currentColor"
d="M15 8.5c0 2.3-.8 4.5-2 6.2l.7.8c1.5-1.9 2.4-4.4 2.4-7c0-3.1-1.2-5.9-3.2-8l-.5 1C14 3.3 15 5.8 15 8.5">
</path>
<path
fill="currentColor"
d="m11.8 2.4l-.5 1C12.4 4.8 13 6.6 13 8.5c0 1.7-.5 3.2-1.3 4.6l.7.8c1.1-1.5 1.7-3.4 1.7-5.4c-.1-2.3-.9-4.4-2.3-6.1">
</path>
<path
fill="currentColor"
d="m10.8 4.4l-.5 1.1c.5.9.8 1.9.8 3c0 1-.3 2-.7 2.9l.7.9c.6-1.1 1-2.4 1-3.7c-.1-1.6-.5-3-1.3-4.2M4 5H0v6h4l5 4V1z">
</path></svg>
);
export const FormVerticalIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}>
<path fill="currentColor" d="M8 13q-.425 0-.712-.288T7 12q0-.425.288-.712T8 11q.425 0 .713.288T9 12q0 .425-.288.713T8 13m8 0q-.425 0-.712-.288T15 12q0-.425.288-.712T16 11q.425 0 .713.288T17 12q0 .425-.288.713T16 13M4 5q-.425 0-.712-.288T3 4q0-.425.288-.712T4 3q.425 0 .713.288T5 4q0 .425-.288.713T4 5m4 0q-.425 0-.712-.288T7 4q0-.425.288-.712T8 3q.425 0 .713.288T9 4q0 .425-.288.713T8 5m8 0q-.425 0-.712-.288T15 4q0-.425.288-.712T16 3q.425 0 .713.288T17 4q0 .425-.288.713T16 5m4 0q-.425 0-.712-.288T19 4q0-.425.288-.712T20 3q.425 0 .713.288T21 4q0 .425-.288.713T20 5M4 9q-.425 0-.712-.288T3 8q0-.425.288-.712T4 7q.425 0 .713.288T5 8q0 .425-.288.713T4 9m16 0q-.425 0-.712-.288T19 8q0-.425.288-.712T20 7q.425 0 .713.288T21 8q0 .425-.288.713T20 9M4 13q-.425 0-.712-.288T3 12q0-.425.288-.712T4 11q.425 0 .713.288T5 12q0 .425-.288.713T4 13m16 0q-.425 0-.712-.288T19 12q0-.425.288-.712T20 11q.425 0 .713.288T21 12q0 .425-.288.713T20 13M4 17q-.425 0-.712-.288T3 16q0-.425.288-.712T4 15q.425 0 .713.288T5 16q0 .425-.288.713T4 17m16 0q-.425 0-.712-.288T19 16q0-.425.288-.712T20 15q.425 0 .713.288T21 16q0 .425-.288.713T20 17M4 21q-.425 0-.712-.288T3 20q0-.425.288-.712T4 19q.425 0 .713.288T5 20q0 .425-.288.713T4 21m4 0q-.425 0-.712-.288T7 20q0-.425.288-.712T8 19q.425 0 .713.288T9 20q0 .425-.288.713T8 21m8 0q-.425 0-.712-.288T15 20q0-.425.288-.712T16 19q.425 0 .713.288T17 20q0 .425-.288.713T16 21m4 0q-.425 0-.712-.288T19 20q0-.425.288-.712T20 19q.425 0 .713.288T21 20q0 .425-.288.713T20 21m-9-1V4q0-.425.288-.712T12 3q.425 0 .713.288T13 4v16q0 .425-.288.713T12 21q-.425 0-.712-.288T11 20" />
</svg>
);
export const FormHorizontalIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}>
<path fill="currentColor" d="M12 9q-.425 0-.712-.288T11 8q0-.425.288-.712T12 7q.425 0 .713.288T13 8q0 .425-.288.713T12 9m0 8q-.425 0-.712-.288T11 16q0-.425.288-.712T12 15q.425 0 .713.288T13 16q0 .425-.288.713T12 17M4 5q-.425 0-.712-.288T3 4q0-.425.288-.712T4 3q.425 0 .713.288T5 4q0 .425-.288.713T4 5m4 0q-.425 0-.712-.288T7 4q0-.425.288-.712T8 3q.425 0 .713.288T9 4q0 .425-.288.713T8 5m4 0q-.425 0-.712-.288T11 4q0-.425.288-.712T12 3q.425 0 .713.288T13 4q0 .425-.288.713T12 5m4 0q-.425 0-.712-.288T15 4q0-.425.288-.712T16 3q.425 0 .713.288T17 4q0 .425-.288.713T16 5m4 0q-.425 0-.712-.288T19 4q0-.425.288-.712T20 3q.425 0 .713.288T21 4q0 .425-.288.713T20 5M4 9q-.425 0-.712-.288T3 8q0-.425.288-.712T4 7q.425 0 .713.288T5 8q0 .425-.288.713T4 9m16 0q-.425 0-.712-.288T19 8q0-.425.288-.712T20 7q.425 0 .713.288T21 8q0 .425-.288.713T20 9M4 17q-.425 0-.712-.288T3 16q0-.425.288-.712T4 15q.425 0 .713.288T5 16q0 .425-.288.713T4 17m16 0q-.425 0-.712-.288T19 16q0-.425.288-.712T20 15q.425 0 .713.288T21 16q0 .425-.288.713T20 17M4 21q-.425 0-.712-.288T3 20q0-.425.288-.712T4 19q.425 0 .713.288T5 20q0 .425-.288.713T4 21m4 0q-.425 0-.712-.288T7 20q0-.425.288-.712T8 19q.425 0 .713.288T9 20q0 .425-.288.713T8 21m4 0q-.425 0-.712-.288T11 20q0-.425.288-.712T12 19q.425 0 .713.288T13 20q0 .425-.288.713T12 21m4 0q-.425 0-.712-.288T15 20q0-.425.288-.712T16 19q.425 0 .713.288T17 20q0 .425-.288.713T16 21m4 0q-.425 0-.712-.288T19 20q0-.425.288-.712T20 19q.425 0 .713.288T21 20q0 .425-.288.713T20 21M4 13q-.425 0-.712-.288T3 12q0-.425.288-.712T4 11h16q.425 0 .713.288T21 12q0 .425-.288.713T20 13z" />
</svg>
);
export const FormCustomIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}>
<path fill="currentColor" d="M18 20H6v-2H4v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2h-2zM14 2H6a2 2 0 0 0-2 2v8h2V4h8v4h4v4h2V8zm-3 14H8v-2h3zm5 0h-3v-2h3zM3 14h3v2H3zm18 2h-3v-2h3z" />
</svg>
);
export const FormLayoutIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}>
<path fill="currentColor" d="M18 3H6a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V6a3 3 0 0 0-3-3M6 5h12a1 1 0 0 1 1 1v2H5V6a1 1 0 0 1 1-1M5 18v-8h6v9H6a1 1 0 0 1-1-1m13 1h-5v-9h6v8a1 1 0 0 1-1 1" />
</svg>
);
export const FormValidationIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}>
<path fill="currentColor" d="M3.5 3.75a.25.25 0 0 1 .25-.25h13.5a.25.25 0 0 1 .25.25v10a.75.75 0 0 0 1.5 0v-10A1.75 1.75 0 0 0 17.25 2H3.75A1.75 1.75 0 0 0 2 3.75v16.5c0 .966.784 1.75 1.75 1.75h7a.75.75 0 0 0 0-1.5h-7a.25.25 0 0 1-.25-.25z" /><path fill="currentColor" d="M6.25 7a.75.75 0 0 0 0 1.5h8.5a.75.75 0 0 0 0-1.5zm-.75 4.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75m16.28 4.53a.75.75 0 1 0-1.06-1.06l-4.97 4.97l-1.97-1.97a.75.75 0 1 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0z" />
</svg>
);
export const FormWizardIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size || height}
width={size || width}
viewBox="0 0 24 24"
{...props}>
<path fill="currentColor" d="M3.5 3.75a.25.25 0 0 1 .25-.25h13.5a.25.25 0 0 1 .25.25v10a.75.75 0 0 0 1.5 0v-10A1.75 1.75 0 0 0 17.25 2H3.75A1.75 1.75 0 0 0 2 3.75v16.5c0 .966.784 1.75 1.75 1.75h7a.75.75 0 0 0 0-1.5h-7a.25.25 0 0 1-.25-.25z" /><path fill="currentColor" d="M6.25 7a.75.75 0 0 0 0 1.5h8.5a.75.75 0 0 0 0-1.5zm-.75 4.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75m16.28 4.53a.75.75 0 1 0-1.06-1.06l-4.97 4.97l-1.97-1.97a.75.75 0 1 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0z" />
</svg>
);
export const FacebookIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 256 256">
<path
fill="#1877f2"
d="M256 128C256 57.308 198.692 0 128 0C57.308 0 0 57.308 0 128c0 63.888 46.808 116.843 108 126.445V165H75.5v-37H108V99.8c0-32.08 19.11-49.8 48.348-49.8C170.352 50 185 52.5 185 52.5V84h-16.14C152.959 84 148 93.867 148 103.99V128h35.5l-5.675 37H148v89.445c61.192-9.602 108-62.556 108-126.445">
</path>
<path
fill="#fff"
d="m177.825 165l5.675-37H148v-24.01C148 93.866 152.959 84 168.86 84H185V52.5S170.352 50 156.347 50C127.11 50 108 67.72 108 99.8V128H75.5v37H108v89.445A128.959 128.959 0 0 0 128 256a128.9 128.9 0 0 0 20-1.555V165z">
</path>
</svg>
);
export const GoogleIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 128 128">
<path
fill="#fff"
d="M44.59 4.21a63.28 63.28 0 0 0 4.33 120.9a67.6 67.6 0 0 0 32.36.35a57.13 57.13 0 0 0 25.9-13.46a57.44 57.44 0 0 0 16-26.26a74.33 74.33 0 0 0 1.61-33.58H65.27v24.69h34.47a29.72 29.72 0 0 1-12.66 19.52a36.16 36.16 0 0 1-13.93 5.5a41.29 41.29 0 0 1-15.1 0A37.16 37.16 0 0 1 44 95.74a39.3 39.3 0 0 1-14.5-19.42a38.31 38.31 0 0 1 0-24.63a39.25 39.25 0 0 1 9.18-14.91A37.17 37.17 0 0 1 76.13 27a34.28 34.28 0 0 1 13.64 8q5.83-5.8 11.64-11.63c2-2.09 4.18-4.08 6.15-6.22A61.22 61.22 0 0 0 87.2 4.59a64 64 0 0 0-42.61-.38">
</path>
<path
fill="#e33629"
d="M44.59 4.21a64 64 0 0 1 42.61.37a61.22 61.22 0 0 1 20.35 12.62c-2 2.14-4.11 4.14-6.15 6.22Q95.58 29.23 89.77 35a34.28 34.28 0 0 0-13.64-8a37.17 37.17 0 0 0-37.46 9.74a39.25 39.25 0 0 0-9.18 14.91L8.76 35.6A63.53 63.53 0 0 1 44.59 4.21">
</path>
<path
fill="#f8bd00"
d="M3.26 51.5a62.93 62.93 0 0 1 5.5-15.9l20.73 16.09a38.31 38.31 0 0 0 0 24.63q-10.36 8-20.73 16.08a63.33 63.33 0 0 1-5.5-40.9">
</path>
<path
fill="#587dbd"
d="M65.27 52.15h59.52a74.33 74.33 0 0 1-1.61 33.58a57.44 57.44 0 0 1-16 26.26c-6.69-5.22-13.41-10.4-20.1-15.62a29.72 29.72 0 0 0 12.66-19.54H65.27c-.01-8.22 0-16.45 0-24.68">
</path>
<path
fill="#319f43"
d="M8.75 92.4q10.37-8 20.73-16.08A39.3 39.3 0 0 0 44 95.74a37.16 37.16 0 0 0 14.08 6.08a41.29 41.29 0 0 0 15.1 0a36.16 36.16 0 0 0 13.93-5.5c6.69 5.22 13.41 10.4 20.1 15.62a57.13 57.13 0 0 1-25.9 13.47a67.6 67.6 0 0 1-32.36-.35a63 63 0 0 1-23-11.59A63.73 63.73 0 0 1 8.75 92.4">
</path>
</svg>
);

View File

@ -0,0 +1,172 @@
import * as React from "react";
import { IconSvgProps } from "@/types/globals";
export const DashboardUserIcon = ({
size,
height = 48,
width = 48,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 48 48"
width={size || width}
{...props}
>
<path fill="#ddbaff" d="M24,44L24,44c-8.216,0-15.137-6.14-16.116-14.297l-0.797-4.639C5.871,14.924,13.788,6,24,6h0 c10.212,0,18.129,8.924,16.912,19.063l-0.797,4.639C39.137,37.86,32.216,44,24,44z" /><path fill="#6c19ff" d="M37.701,10.916c-0.825-1.117-1.787-2.133-2.858-3.017C31.912,5.474,28.145,4.003,24,4.003 c-4.145,0-7.912,1.471-10.844,3.895c-0.554,0.458-1.084,0.951-1.58,1.485c-3.115,3.323-4.903,7.879-4.573,12.777 c3.362-1.449,5.88-4.482,6.615-8.158h20.764c0.735,3.677,3.253,6.709,6.615,8.158C41.278,17.982,40.019,14.053,37.701,10.916z" /><path fill="#ddbaff" d="M40,31H8c-1.657,0-3-1.343-3-3s1.343-3,3-3h32c1.657,0,3,1.343,3,3S41.657,31,40,31z" /><path fill="#2100c4" d="M37.701,13.913c-0.825-1.117-1.787-2.133-2.858-3.017C31.912,8.471,28.145,7,24,7 c-4.145,0-7.912,1.471-10.844,3.895c-0.554,0.458-1.084,0.951-1.58,1.485c-3.115,3.323-4.903,7.879-4.573,12.777 c3.362-1.449,5.88-4.482,6.615-8.158h20.764c0.735,3.677,3.253,6.709,6.615,8.158C41.278,20.979,40.019,17.05,37.701,13.913z" />
</svg>
);
export const DashboardBriefcaseIcon = ({
size,
height = 48,
width = 48,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 48 48"
width={size || width}
{...props}
>
<path fill="#f5bc00" d="M44,41H4V10h40V41z" />
<polygon fill="#eb7900" points="44,26 24,26 4,26 4,10 44,10" />
<path fill="#eb7900" d="M17,26h-6v3h6V26z" /><path fill="#eb7900" d="M37,26h-6v3h6V26z" />
<rect width="14" height="3" x="17" y="7" fill="#f5bc00" /><path fill="#eb0000" d="M17,23h-6v3h6V23z" />
<path fill="#eb0000" d="M37,23h-6v3h6V23z" />
</svg>
);
export const DashboardMailboxIcon = ({
size,
height = 48,
width = 48,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 48 48"
width={size || width}
{...props}
>
<path fill="#3dd9eb" d="M43,36H13V11h22c4.418,0,8,3.582,8,8V36z" />
<path fill="#7debf5" d="M21,36H5V19c0-4.418,3.582-8,8-8l0,0c4.418,0,8,3.582,8,8V36z" />
<path fill="#6c19ff" d="M21,36h5v8h-5V36z" />
<polygon fill="#eb0000" points="27,16 27,20 35,20 35,24 39,24 39,16" />
<rect width="8" height="3" x="9" y="20" fill="#3dd9eb" />
</svg>
);
export const DashboardBookmarkIcon = ({
size,
height = 48,
width = 48,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 48 48"
width={size || width}
{...props}
>
<polygon fill="#f55376" points="37,6 11,6 11,30 24,36 37,42" />
<polygon fill="#f55376" points="11,6 37,6 37,30 24,36 11,42" />
<polygon fill="#eb0000" points="11,6 11,30 24,36 31.5,32.538 37,25 37,6" />
<g>
<polygon fill="#fadb00" points="37,29.768 48,21 26,21" />
<polygon fill="#fadb00" points="37,29.732 43.957,34 44,34 37,14 30,34 30.044,34" />
<polygon fill="#f5bc00" points="39.45,21 34.55,21 32.685,26.329 36.974,29.748 37,29.732 37.026,29.748 41.315,26.329" />
</g>
</svg>
);
export const DashboardSpeecIcon = ({
size,
height = 48,
width = 48,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 48 48"
width={size || width}
{...props}
>
<circle cx="20" cy="28" r="16" fill="#3ddab4" />
<circle cx="31.584" cy="17.478" r="13.449" fill="#f5bc00" />
<polygon fill="#3ddab4" points="4.07,44 19.909,44 10.922,35.549" />
<path fill="#00b569" d="M20,12c-0.239,0-0.471,0.025-0.708,0.036c-0.739,1.665-1.157,3.504-1.157,5.443 c0,7.428,6.021,13.449,13.449,13.449c1.484,0,2.907-0.25,4.242-0.693C35.929,29.502,36,28.76,36,28C36,19.163,28.837,12,20,12z" />
<polygon fill="#f5bc00" points="44.975,4.029 31.661,4.029 39.215,11.133" />
</svg>
);
export const DashboardConnectIcon = ({
size,
height = 48,
width = 48,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 48 48"
width={size || width}
{...props}
>
<path fill="#3dd9eb" d="M11,18c-3.313,0-6,2.686-6,6c0,3.313,2.687,6,6,6c3.314,0,6-2.687,6-6C17,20.687,14.314,18,11,18" />
<path fill="#3dd9eb" d="M37,5c-3.313,0-6,2.687-6,6c0,3.313,2.687,6,6,6c3.314,0,6-2.687,6-6C43,7.687,40.314,5,37,5" />
<path fill="#3dd9eb" d="M37,31c-3.313,0-6,2.686-6,6c0,3.313,2.687,6,6,6c3.314,0,6-2.687,6-6C43,33.687,40.314,31,37,31" />
<path fill="#6c19ff" d="M31.819,14.028L25.073,22h-8.415C16.88,22.626,17,23.299,17,24c0,0.701-0.12,1.374-0.341,2h8.414 l6.746,7.973c0.688-1.175,1.765-2.095,3.053-2.584L28.62,24l6.251-7.389C33.583,16.123,32.507,15.202,31.819,14.028" />
<path fill="#00b3d7" d="M16.658,22H11v4h5.659C16.88,25.375,17,24.701,17,24C17,23.299,16.88,22.626,16.658,22" />
<path fill="#00b3d7" d="M35.474,9.708l-3.655,4.32c0.688,1.175,1.764,2.095,3.053,2.584l3.655-4.319L35.474,9.708" />
<path fill="#00b3d7" d="M34.872,31.389c-1.288,0.489-2.365,1.409-3.053,2.584l3.655,4.319l3.053-2.584L34.872,31.389" />
</svg>
);
export const DashboardTopLeftPointIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 24 24"
width={size || width}
{...props}
>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M18 18L6 6m0 0h9M6 6v9" />
</svg>
);
export const DashboardRightDownPointIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 24 24"
width={size || width}
{...props}
>
<path fill="currentColor" fill-rule="evenodd" d="M5.47 5.47a.75.75 0 0 1 1.06 0l10.72 10.72V9a.75.75 0 0 1 1.5 0v9a.75.75 0 0 1-.75.75H9a.75.75 0 0 1 0-1.5h7.19L5.47 6.53a.75.75 0 0 1 0-1.06" clip-rule="evenodd" />
</svg>
);

View File

@ -0,0 +1,167 @@
import * as React from "react";
import { IconSvgProps } from "@/types/globals";
export const MenuBurgerIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 24 24"
width={size || width}
{...props}
>
<path fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M3 6h18M3 12h18M3 18h18" />
</svg>
);
export const DashboardIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 24 24"
width={size || width}
{...props}
>
<path fill="currentColor" d="M13 9V3h8v6zM3 13V3h8v10zm10 8V11h8v10zM3 21v-6h8v6z" />
</svg>
);
export const HomeIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 24 24"
width={size || width}
{...props}
>
<g fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M2 12.204c0-2.289 0-3.433.52-4.381c.518-.949 1.467-1.537 3.364-2.715l2-1.241C9.889 2.622 10.892 2 12 2c1.108 0 2.11.622 4.116 1.867l2 1.241c1.897 1.178 2.846 1.766 3.365 2.715c.519.948.519 2.092.519 4.38v1.522c0 3.9 0 5.851-1.172 7.063C19.657 22 17.771 22 14 22h-4c-3.771 0-5.657 0-6.828-1.212C2 19.576 2 17.626 2 13.725z" />
<path strokeLinecap="round" d="M12 15v3" />
</g>
</svg>
);
export const Submenu1Icon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 48 48"
width={size || width}
{...props}
>
<defs>
<mask id="ipTData0">
<g fill="none" stroke="#fff" strokeLinecap="round" strokeLinejoin="round" strokeWidth="4">
<path d="M44 11v27c0 3.314-8.954 6-20 6S4 41.314 4 38V11" /><path d="M44 29c0 3.314-8.954 6-20 6S4 32.314 4 29m40-9c0 3.314-8.954 6-20 6S4 23.314 4 20" />
<ellipse cx="24" cy="10" fill="#555" rx="20" ry="6" />
</g>
</mask>
</defs>
<path fill="currentColor" d="M0 0h48v48H0z" mask="url(#ipTData0)" />
</svg>
);
export const Submenu2Icon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 256 256"
width={size || width}
{...props}
>
<path fill="currentColor" d="M230.93 220a8 8 0 0 1-6.93 4H32a8 8 0 0 1-6.92-12c15.23-26.33 38.7-45.21 66.09-54.16a72 72 0 1 1 73.66 0c27.39 8.95 50.86 27.83 66.09 54.16a8 8 0 0 1 .01 8" />
</svg>
);
export const InfoCircleIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 1024 1024"
width={size || width}
{...props}
>
<path fill="currentColor" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448s448-200.6 448-448S759.4 64 512 64m0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372s372 166.6 372 372s-166.6 372-372 372" />
<path fill="currentColor" d="M464 336a48 48 0 1 0 96 0a48 48 0 1 0-96 0m72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8" />
</svg>
);
export const MinusCircleIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 16 16"
width={size || width}
{...props}
>
<g fill="currentColor">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
<path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8" />
</g>
</svg>
);
export const TableIcon = ({
size,
height = 24,
width = 22,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 24 22"
width={size || width}
stroke-width="1.5"
stroke="currentColor"
{...props}
>
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5" />
</svg>
);

View File

@ -0,0 +1,39 @@
"use client";
import { useEffect, useState } from "react";
import Sidebar from "../sidebar/sidebar";
import { SidebarProvider } from "../sidebar/sidebar-context";
import { Breadcrumb } from "../ui/breadcrumb";
interface Props {
children: React.ReactNode;
}
export const AdminLayout = ({ children }: Props) => {
const [isOpen, setIsOpen] = useState(true);
const updateSidebarData = (newData: boolean) => {
setIsOpen(newData);
};
const [hasMounted, setHasMounted] = useState(false);
// Hooks
useEffect(() => {
setHasMounted(true);
}, []);
// Render
if (!hasMounted) return null;
return (
<SidebarProvider>
<div className="flex items-center justify-between h-screen p-4">
<Sidebar sidebarData={isOpen} updateSidebarData={updateSidebarData} />
<div className={`h-full w-full flex flex-col gap-4`}>
<Breadcrumb />
{children}
</div>
</div>
</SidebarProvider>
);
};

View File

@ -0,0 +1,81 @@
import React, { Component } from 'react';
import ReactApexChart from 'react-apexcharts';
interface State {
series: { name: string; data: number[] }[];
options: {
chart: { type: string; height: number };
plotOptions: { bar: { colors: { ranges: { from: number; to: number; color: string }[] }; columnWidth: string } };
dataLabels: { enabled: boolean };
yaxis: { title: { text: string }; labels: { formatter: (y: number) => string } };
xaxis: { type: string; categories: string[]; labels: { rotate: number } };
};
}
class ApexChartColumn extends Component<{}, State> {
render() {
return (
<div>
<div id="chart">
<ReactApexChart
options={
{
chart: { type: 'bar', height: 350, zoom: { enabled: false } },
plotOptions: {
bar: {
colors: {
ranges: [
{
from: -100,
to: 0,
color: '#57c0fd'
},
{
from: 0,
to: 100,
color: '#6484fd',
},
],
},
columnWidth: '20%',
},
},
dataLabels: {
enabled: false,
},
yaxis: {
labels: {
formatter: (y: any) => {
return y.toFixed(0);
},
},
},
xaxis: {
type: 'datetime',
categories: [
'2020-05-01', '2020-05-02', '2020-05-03', '2020-05-04', '2020-05-05',
],
labels: {
rotate: -90,
},
},
}}
series={[
{
name: 'Earning This Month ',
data: [
1.45, 5.9, -0.42, -12.6, -18.1
],
},
]} type="bar" height={350} />
</div>
<div id="html-dist"></div>
</div>
);
}
}
export default ApexChartColumn;

View File

@ -0,0 +1,51 @@
import React, { Component } from 'react';
import ReactApexChart from 'react-apexcharts';
interface State {
series: { name: string; data: number[] }[];
options: {
chart: { type: string; height: number };
dataLabels: { enabled: boolean };
};
}
class ApexChartDonut extends Component<{}, State> {
render() {
return (
<div>
<div id="chart">
<ReactApexChart
options={
{
chart: {
type: 'donut',
},
dataLabels: {
enabled: false,
},
responsive: [{
breakpoint: 480,
options: {
chart: {
width: 300
},
}
}],
labels: ["2020", "2019", "2018"],
colors: ['#5c6ac4', '#d4d4d8', '#e5e7eb'],
legend: {
show: false
}
}
}
series={[38, 40, 25]}
type="donut"
/>
</div>
<div id="html-dist"></div>
</div>
);
}
}
export default ApexChartDonut;

View File

@ -0,0 +1,74 @@
import React, { Component } from 'react';
import ReactApexChart from 'react-apexcharts';
interface State {
series: { name: string; data: number[] }[];
options: {
chart: { type: string; height: number };
plotOptions: { bar: { colors: { ranges: { from: number; to: number; color: string }[] }; columnWidth: string } };
dataLabels: { enabled: boolean };
yaxis: { title: { text: string }; labels: { formatter: (y: number) => string } };
xaxis: { type: string; categories: string[]; labels: { rotate: number } };
};
}
class ApexChartLineArea extends Component<{}, State> {
render() {
return (
<div id="chart" className='w-[377px] translate-y-6 -translate-x-6'>
<ReactApexChart
options={
{
chart: {
height: 50,
type: 'area',
zoom: {
enabled: false
},
toolbar: {
show: false, // Menampilkan toolbar
}
},
stroke: {
curve: 'smooth'
},
dataLabels: {
enabled: false
},
fill: {
type: 'light',
opacity: [0.35, 0],
},
markers: {
size: 0
},
xaxis: {
labels: {
show: false
}
},
yaxis: {
labels: {
show: false
}
},
legend: {
show: false
},
grid: {
show: false
}
}}
series={[{
name: 'Monthly Earning',
data: [25, 55, 20, 40, 12, 60, 20]
}]}
type="area" height={90}
/>
</div>
);
}
}
export default ApexChartLineArea;

View File

@ -0,0 +1,176 @@
'use client'
import { DashboardBookmarkIcon, DashboardBriefcaseIcon, DashboardConnectIcon, DashboardMailboxIcon, DashboardRightDownPointIcon, DashboardSpeecIcon, DashboardTopLeftPointIcon, DashboardUserIcon } from "@/components/icons/dashboard-icon";
import { Submenu1Icon } from "@/components/icons/sidebar-icon";
import { Button, Select, SelectItem, SelectSection } from "@nextui-org/react";
import ApexChartColumn from "./chart/column-chart";
import ApexChartDonut from "./chart/donut-chart";
import ApexChartLineArea from "./chart/line-area-chart";
export default function DashboardContainer() {
return (
<div className="p-8 flex justify-center">
<div className="w-full flex flex-col gap-6">
<div className="w-full flex flex-col md:flex-row gap-6 justify-center">
<div className="w-full md:w-[160px] h-[160px] bg-[#ecf2ff] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center"><DashboardUserIcon className="w-[50px]" /></div>
<div className="text-[#6484fd] font-semibold">Employees</div>
<div className="text-[#6484fd] font-semibold text-lg">96</div>
</div>
<div className="w-full md:w-[160px] h-[160px] bg-[#fef5e5] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center"><DashboardBriefcaseIcon className="w-[50px]" /></div>
<div className="text-[#feaf2d] font-semibold">Clients</div>
<div className="text-[#feaf2d] font-semibold text-lg">3650</div>
</div>
<div className="w-full md:w-[160px] h-[160px] bg-[#e8f7ff] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center"><DashboardMailboxIcon className="w-[50px]" /></div>
<div className="text-[#57c0fd] font-semibold">Projects</div>
<div className="text-[#57c0fd] font-semibold text-lg">356</div>
</div>
<div className="w-full md:w-[160px] h-[160px] bg-[#fdede8] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center"><DashboardBookmarkIcon className="w-[50px]" /></div>
<div className="text-[#f98e75] font-semibold">Events</div>
<div className="text-[#f98e75] font-semibold text-lg">696</div>
</div>
<div className="w-full md:w-[160px] h-[160px] bg-[#e6fffa] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center"><DashboardSpeecIcon className="w-[50px]" /></div>
<div className="text-[#29e2be] font-semibold">Payroll</div>
<div className="text-[#29e2be] font-semibold text-lg">$96k</div>
</div>
<div className="w-full md:w-[160px] h-[160px] bg-[#ebf3fe] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center"><DashboardConnectIcon className="w-[50px]" /></div>
<div className="text-[#5797fd] font-semibold">Reports</div>
<div className="text-[#5797fd] font-semibold text-lg">56</div>
</div>
</div>
<div className="w-full flex flex-row gap-6 justify-center">
<div className="border-1 shadow-sm w-full rounded-lg md:w-[712px] p-6 flex flex-col">
<div className="flex justify-between mb-3">
<div className="font-semibold flex flex-col">Revenue Update
<span className="font-normal text-xs text-gray-600">Overview of Profit</span>
</div>
<div className="w-auto md:w-[140px]">
<Select
label=""
labelPlacement="outside"
placeholder=""
className="w-full"
variant="bordered"
classNames={{
mainWrapper: "rounded",
listboxWrapper:
"bg-white w-full !text-indigo-500 text-center font-bold",
popoverContent: "bg-white !text-indigo-500",
trigger:
"border-1 border-gray-200 hover:!bg-gray-100 !text-black",
}}
listboxProps={{
itemClasses: {
base: [
"!text-left",
"!bg-white",
"text-indigo-500 ",
"data-[selectable=true]:!text-indigo-500",
"data-[pressed=true]:text-indigo-500",
"data-[hover=true]:!text-indigo-300",
],
wrapper: ["!bg-white border-none"],
},
}}
defaultSelectedKeys={["march"]}
// onChange={onChangeFilterStatus}
renderValue={(items) => {
return items.map((item) => (
<span key={item.props?.value} className="text-black text-xs">
{item.textValue}
</span>
));
}}
>
<SelectSection>
<SelectItem key="march">March 2023</SelectItem>
<SelectItem key="april">April 2023</SelectItem>
<SelectItem key="may">May 2023</SelectItem>
</SelectSection>
</Select>
</div>
</div>
<div className="flex flex-row w-full">
<div className="w-3/4">
<ApexChartColumn />
</div>
<div className="w-1/4 flex flex-col px-2 justify-between">
<div className="flex flex-row items-center gap-2">
<div className="bg-[#e8f7ff] p-2 rounded-md">
<Submenu1Icon className="h-full text-[#6484fd]" />
</div>
<div className="flex flex-col">
<p className="font-semibold text-xl">$63,489.50</p>
<p className="text-xs">Total Earnings</p>
</div>
</div>
<div className="flex flex-row gap-3 items-center">
<div className="w-2 h-2 bg-[#6484fd] rounded-full" />
<div className="flex flex-col">
<p className="text-xs">Earning this month</p>
<p className="font-semibold text-md">$48,820</p>
</div>
</div>
<div className="flex flex-row gap-3 items-center">
<div className="w-2 h-2 bg-[#57c0fd] rounded-full" />
<div className="flex flex-col">
<p className="text-xs">Expense this month</p>
<p className="font-semibold text-md">$26,498</p>
</div>
</div>
<Button className="w-full h-[35px] rounded-md" color="primary" variant="solid">View Full Report</Button>
</div>
</div>
</div>
<div className="flex flex-col w-[344px] gap-6">
<div className="h-1/2 border-1 shadow-sm w-full rounded-lg p-6 flex flex-row gap-2">
<div className="w-1/2 flex flex-col justify-between">
<p className="font-semibold">Yearly Breakup</p>
<div className="lflex flex-col">
<p className="font-semibold text-xl ">$36,358</p>
<div className="flex flex-row text-xs item-center">
<div className="rounded-full w-6 h-6 bg-[#e6fffa] p-[2px] flex items-center justify-center"><DashboardTopLeftPointIcon className="text-[#29e2be]" /></div>
<p className="pt-[3px]"> +9% last year</p></div>
</div>
<p className="font-semibold flex flex-row gap-3">
<div className="flex flex-row text-tiny items-center gap-2">
<div className="w-2 h-2 rounded-full bg-[#5c6ac4]" />
2020
</div>
<div className="flex flex-row text-tiny items-center gap-2">
<div className="w-2 h-2 rounded-full bg-[#d4d4d8]" />
2020
</div>
</p>
</div>
<div className="w-1/2 h-full flex items-center"><ApexChartDonut /></div>
</div>
<div className="h-1/2 border-1 shadow-sm w-full rounded-lg flex flex-col justify-between">
<div className="p-6 flex flex-col">
<div className="flex justify-between items-center font-semibold">
Monthly Earning
<a className="cursor-pointer w-10 h-10 bg-blue-300 flex justify-center items-center rounded-full text-white text-xl">$</a>
</div>
<div className="lflex flex-col">
<p className="font-semibold text-xl ">$6,820</p>
<div className="flex flex-row text-xs item-center">
<div className="rounded-full w-6 h-6 bg-[#fdede8] p-[2px] flex items-center justify-center">
<DashboardRightDownPointIcon className="text-[#f98e75]" />
</div>
<p className="pt-[3px]"> -6% last year</p></div>
</div>
</div>
<div className="w-auto object-cover"><ApexChartLineArea /></div>
</div>
</div>
</div>
<div>bawah</div>
</div>
</div>
)
}

View File

@ -0,0 +1,36 @@
import Link from "next/link";
import { DashboardIcon, HomeIcon, TableIcon } from "../icons/sidebar-icon";
import { useSidebar } from "./sidebar-context";
import { Tooltip } from "@nextui-org/react";
export default function ClosedSidebarIcon(props: { icon: string, isActive: boolean, childMenu: any, path: string, title: string }) {
const { isOpen, toggleSidebar } = useSidebar();
const { icon, isActive, childMenu, path, title } = props;
const renderIcon = () => {
switch (icon) {
case 'dashboard':
return <DashboardIcon />;
case 'menu1':
return <HomeIcon />;
case 'table':
return <TableIcon />;
default:
return null; // Tidak ada ikon yang sesuai
}
};
return (
<Tooltip content={title} placement="right" delay={0} closeDelay={0}>
{childMenu.length < 1 ?
< Link href={path} className={`w-fit rounded-lg p-1 flex items-center ${isActive ? "bg-[#11181c] dark:bg-white text-[#fafafa] dark:text-black" : "text-zinc-600 dark:text-zinc-400 hover:text-zinc-800 hover:dark:text-zinc-300"}`}>
{renderIcon()}
</Link >
:
<a onClick={toggleSidebar} className={`cursor-pointer w-fit rounded-lg p-1 flex items-center ${isActive ? "bg-[#11181c] dark:bg-white text-[#fafafa] dark:text-black" : "text-zinc-600 dark:text-zinc-400 hover:text-zinc-800 hover:dark:text-zinc-300"}`}>
{renderIcon()}
</a >
}
</Tooltip>
)
}

View File

@ -0,0 +1,73 @@
import React, { useEffect, useState } from "react";
import clsx from "clsx";
import { Accordion, AccordionItem, Tooltip } from "@nextui-org/react";
import { ChevronUpIcon } from "../icons";
import { DashboardIcon, HomeIcon, TableIcon } from "../icons/sidebar-icon";
import { useSidebar } from "./sidebar-context";
interface Props {
icon?: string;
title: string;
items?: React.ReactNode[];
isActive: boolean;
}
export const SidebarCollapseItems = ({
title,
items,
icon,
isActive,
}: Props) => {
const { isOpen, toggleSidebar } = useSidebar();
// useEffect(() => {
// console.log("Sidebar Collapse Item :: ", title, isActive);
// }, []);
const renderIcon = () => {
switch (icon) {
case 'dashboard':
return <DashboardIcon />;
case 'menu1':
return <HomeIcon />;
case 'table':
return <TableIcon />;
default:
return null; // Tidak ada ikon yang sesuai
}
};
return (
<div
className={`flex gap-4 h-full items-center cursor-pointer rounded-lg ${isActive ? `bg-zinc-600 dark:bg-zinc-300 ${isOpen ? "max-w-[253px]" : "max-w-[48px]"} ` : ""
} `}
>
<Accordion className={`${isOpen ? "pr-4 pl-0" : "pl-0 pr-4"} `} defaultExpandedKeys={isActive ? [title] : ""}>
<AccordionItem
key={title}
indicator={<ChevronUpIcon />}
classNames={{
// indicator: "data-[open=true]:-rotate-180",
indicator: `${isOpen ? "data-[open=true]:-rotate-180" : "hidden"}`,
trigger: `${isOpen ? "pl-[7px]" : "pl-[11px] "} py-2 rounded-lg active:scale-[0.98] transition-transform text-center ${isActive ? "bg-zinc-600 dark:bg-zinc-300 text-zinc-300 dark:text-zinc-500 font-bold font-bold hover:font-bold" : " hover:bg-zinc-400 hover:font-semibold"}`,
title: `${isOpen ? "pl-2 gap-2" : "px-0"} flex text-base h-full items-center cursor-pointer`,
}}
aria-label="Accordion 1"
title={
<div className={`w-full ${isActive ? "text-zinc-300 dark:text-zinc-600" : " !text-zinc-600 dark:!text-zinc-400"} flex flex-row ${isOpen && 'gap-2'} `}>
{icon && <span className={isOpen ? "pl-[1px]" : "self-center pl-0"}>{icon}</span>}
{/* {isOpen && <span>{title}</span>} */}
{isOpen && <span>{title}</span>}
</div>
}
>
<div className={`border-zinc-500 dark:border-zinc-600 ${isOpen ? "ml-6 border-l-1" : "border-none"}`}>
<ul className=" overflow-hidden">{items}</ul>
</div>
</AccordionItem>
</Accordion>
</div>
);
};

View File

@ -0,0 +1,95 @@
import React, { useEffect, useState } from "react";
import { Accordion, AccordionItem, Tooltip } from "@nextui-org/react";
import clsx from "clsx";
import Link from "next/link";
import { ChevronUpIcon } from "../icons";
import { Submenu1Icon, Submenu2Icon } from "../icons/sidebar-icon";
import { useSidebar } from "./sidebar-context";
interface SubSubItems {
title: string;
path: string;
isSubActive: boolean;
}
interface SubItems {
title: string;
path: string;
isActive: boolean;
isSubActive: boolean;
subItems?: SubSubItems[];
}
interface Props {
title: string;
icon?: any;
path: string;
isActive: boolean;
isParentActive: boolean;
}
export const SidebarCollapseSubItems = ({
title,
icon,
path,
isActive,
isParentActive,
}: Props) => {
const [open, setOpen] = useState(false);
let no = 0;
// useEffect(() => {
// console.log("Sidebar Collapse Sub Item :: ", title, path, isParentActive, isActive, icon);
// }, []);
const { isOpen, toggleSidebar } = useSidebar();
const renderIcon = () => {
switch (icon) {
case 'submenu1':
return <Submenu1Icon size={16} />;
case 'submenu2':
return <Submenu2Icon size={16} />;
default:
return null; // Tidak ada ikon yang sesuai
}
};
return (
<li key={`${title}-${(no += 1)}`}>
{isOpen ?
<Link
href={path}
>
<div
className={`flex items-center min-h-[36px] rounded-md py-1 text-sm
${isOpen ? "px-3.5" : "px-0"}
${isParentActive ? "text-zinc-300 dark:text-zinc-500 hover:text-zinc-200 dark:hover:text-zinc-600" : "text-zinc-600 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300"}
${isActive ? "font-bold hover:font-bold !text-zinc-100 dark:!text-zinc-600" : "hover:font-semibold"
}`}
>
<span className={`${isOpen ? "pl-3" : "pl-0"} pr-0 flex flex-row gap-2`}>{icon} {isOpen && title}</span>
</div>
</Link>
:
<Tooltip content={title} delay={0} closeDelay={0} placement="right">
<Link
href={path}
>
<div
className={`flex justify-center min-h-[36px] rounded-md py-1 text-sm
${isOpen ? "px-3.5" : "px-0"}
${isParentActive ? "text-zinc-300 dark:text-zinc-500 hover:text-zinc-200 dark:hover:text-zinc-600" : "text-zinc-600 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300"}
${isActive ? "font-bold hover:font-bold !text-zinc-100 dark:!text-zinc-600" : "hover:font-semibold"
}`}
>
<span className={`${isOpen ? "pl-3" : `${isParentActive ? "pl-3" : "pl-0"}`} pr-0 flex flex-row`}>{icon} {isOpen && title}</span>
</div>
</Link>
</Tooltip>
}
</li>
);
};

View File

@ -0,0 +1,58 @@
'use client'
import React, { createContext, useContext, useEffect, useState } from 'react';
interface SidebarContextType {
isOpen: boolean;
toggleSidebar: () => void;
}
const SidebarContext = createContext<SidebarContextType | undefined>(undefined);
export const SidebarProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [isOpen, setIsOpen] = useState(() => {
if (typeof window !== 'undefined') {
const storedValue = localStorage.getItem('sidebarOpen');
return storedValue ? JSON.parse(storedValue) : false;
}
});
const toggleSidebar = () => {
setIsOpen(!isOpen);
};
useEffect(() => {
localStorage.setItem('sidebarOpen', JSON.stringify(isOpen));
}, [isOpen]);
useEffect(() => {
const handleResize = () => {
setIsOpen(window.innerWidth > 768); // Ganti 768 dengan lebar yang sesuai dengan breakpoint Anda
};
handleResize(); // Pastikan untuk memanggil fungsi handleResize saat komponen dimuat
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<SidebarContext.Provider value={{ isOpen, toggleSidebar }}>
{children}
</SidebarContext.Provider>
);
};
export const useSidebar = () => {
const context = useContext(SidebarContext);
if (!context) {
throw new Error('useSidebar must be used within a SidebarProvider');
}
return context;
};
export const useSidebarContext = () => {
return useContext(SidebarContext);
};

View File

@ -0,0 +1,15 @@
import React from "react";
interface Props {
title?: string;
children?: React.ReactNode;
}
export const SidebarMenu = ({ title, children }: Props) => {
return (
<div className="flex gap-2 flex-col custom-scrollbar sidebar-scrollbar data-[top-scroll=true]:[mask-image:linear-gradient(0deg,#000_calc(100%_-_var(--scroll-shadow-size)),transparent)] data-[bottom-scroll=true]:[mask-image:linear-gradient(180deg,#000_calc(100%_-_var(--scroll-shadow-size)),transparent)] data-[top-bottom-scroll=true]:[mask-image:linear-gradient(#000,#000,transparent_0,#000_var(--scroll-shadow-size),#000_calc(100%_-_var(--scroll-shadow-size)),transparent)] overflow-auto max-h-[70vh] mr-[-1rem] pb-5" data-top-scroll="false" data-bottom-scroll="true">
<span className="text-xs font-normal ">{title}</span>
{children}
</div>
);
};

View File

@ -0,0 +1,474 @@
import { SidebarMenuTask } from "@/types/globals";
import { Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Tooltip, User } from '@nextui-org/react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import React, { useEffect, useState } from 'react';
import { ChevronLeftIcon, ChevronRightIcon, FormCustomIcon, FormHorizontalIcon, FormLayoutIcon, FormValidationIcon, FormVerticalIcon } from '../icons';
import { DashboardIcon, HomeIcon, InfoCircleIcon, MinusCircleIcon, TableIcon } from '../icons/sidebar-icon';
import { ThemeSwitch } from '../theme-switch';
import { SidebarCollapseItems } from "./sidebar-collapse-items";
import { SidebarCollapseSubItems } from "./sidebar-collapse-sub-items";
import { useSidebar } from './sidebar-context';
import { SidebarMenu } from "./sidebar-menu";
interface SubMenuItems {
id: number;
name: string;
modulePathUrl: string;
isSubActive: boolean;
}
interface MenuItems {
id: number;
name: string;
modulePathUrl: string;
isSubActive: boolean;
childMenu?: SubMenuItems[];
icon?: string
}
interface SidebarProps {
sidebarData: boolean;
updateSidebarData: (newData: boolean) => void;
}
const sideBarDummyData = [
{
id: 1,
name: "Dashboard",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/dashboard",
isGroup: true,
parentId: -1,
icon: "dashboard",
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 2,
name: "Dashboard",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/dashboard",
parentId: -1,
icon: <DashboardIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 3,
name: "Apps",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/basic",
isGroup: true,
parentId: -1,
icon: "table",
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 4,
name: "Artikel",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/article",
parentId: -1,
icon: <TableIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 4,
name: "E-Magazine",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/pagination-basic",
parentId: -1,
icon: <TableIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 5,
name: "Master",
moduleId: 652,
moduleName: "Dashboard",
isGroup: true,
modulePathUrl: "/admin/basic",
parentId: -1,
icon: "table",
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 6,
name: "Master Menu",
moduleId: 652,
moduleName: "Form Custom",
modulePathUrl: "/admin/form-costum",
parentId: -1,
icon: <FormCustomIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 7,
name: "Master Module",
moduleId: 653,
moduleName: "Form Horizontal",
modulePathUrl: "/admin/form-horizontal",
parentId: -1,
icon: <FormHorizontalIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 8,
name: "Master User",
moduleId: 654,
moduleName: "Form Vertical",
modulePathUrl: "/admin/form-vertical",
parentId: -1,
icon: <FormVerticalIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 9,
name: "Master User Levels",
moduleId: 655,
moduleName: "Form Layout",
modulePathUrl: "/admin/form-layout",
parentId: -1,
icon: <FormLayoutIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 10,
name: "Master User Role",
moduleId: 656,
moduleName: "Form Validation",
modulePathUrl: "/admin/form-validation",
parentId: -1,
icon: <FormValidationIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
// {
// id: 11,
// name: "Form Wizard",
// moduleId: 657,
// moduleName: "Form Wizard",
// modulePathUrl: "/admin/form-wizard",
// parentId: -1,
// icon: <FormWizardIcon />,
// position: 1,
// statusId: 1,
// childMenu: [],
// statusName: "Active",
// childModule: null,
// },
// {
// id: 13,
// name: "Others",
// moduleId: 658,
// moduleName: "Others",
// modulePathUrl: "/admin/basic",
// isGroup: true,
// parentId: -1,
// icon: "table",
// position: 1,
// statusId: 1,
// childMenu: [],
// statusName: "Active",
// childModule: null,
// },
// {
// id: 13,
// name: "Menu 1",
// moduleId: 652,
// moduleName: "Menu 1",
// modulePathUrl: "/admin/menu1",
// parentId: -1,
// icon: <HomeIcon />,
// position: 1,
// statusId: 1,
// statusName: "Active",
// childMenu: [
// {
// id: 3,
// name: "SubMenu 1",
// moduleId: 653,
// moduleName: "SubMenu 1",
// modulePathUrl: "/admin/menu1/submenu1",
// parentId: 702,
// icon: <Submenu1Icon size={16} />,
// position: 2,
// statusId: 1,
// statusName: "Active",
// childMenu: [],
// childModule: null,
// },
// {
// id: 4,
// name: "SubMenu 2",
// moduleId: 653,
// moduleName: "SubMenu 2",
// modulePathUrl: "/admin/menu1/submenu2",
// parentId: 702,
// icon: <Submenu2Icon size={16} />,
// position: 2,
// statusId: 1,
// statusName: "Active",
// childMenu: [],
// childModule: null,
// }
// ],
// childModule: null,
// },
]
const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
const pathname = usePathname();
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
const { isOpen, toggleSidebar } = useSidebar();
const closeSidebar = () => {
if (isOpen) {
toggleSidebar();
}
};
useEffect(() => {
updateSidebarData(isOpen)
}, [isOpen])
const renderIcon = (icon: string) => {
switch (icon) {
case 'dashboard':
return <DashboardIcon />;
case 'menu1':
return <HomeIcon />;
case 'table':
return <TableIcon />;
default:
return null;
}
};
return (
<div className={`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]'
}`}
>
{!isOpen &&
<div className='w-full flex justify-center items-center'>
<button
className="w-5 h-5 mb-3 text-zinc-400 dark:text-zinc-400 z-50 border-1 border-zinc-400 rounded-full flex justify-center items-center"
onClick={toggleSidebar}
>
<ChevronRightIcon />
</button>
</div>
}
<div className={`flex ${isOpen ? "justify-between" : "justify-center"} w-full items-center px-2`}>
<div className='flex flex-row items-center gap-3 font-bold'>
<img src="/favicon.ico" className='w-10' />
{isOpen && <span>ACME</span>}
</div>
{isOpen &&
<button
className="w-5 h-5 text-zinc-400 dark:text-zinc-400 z-50 border-1 border-zinc-400 rounded-full flex justify-center items-center"
onClick={toggleSidebar}
>
<ChevronLeftIcon />
</button>
}
</div>
<div className={`flex ${isOpen ? "justify-between" : "justify-center"} w-full items-center px-2 mt-4 mb-4`}>
<div className='flex flex-row items-center gap-3 font-bold'>
<Dropdown placement="bottom-start">
<DropdownTrigger>
<User
as="button"
avatarProps={{
isBordered: true,
src: "https://i.pravatar.cc/150?u=a042581f4e29026024d",
}}
classNames={{
base: `transition-transform gap-0`,
wrapper: `${isOpen && "pl-3"}`
}}
description={isOpen && "@tonyreichert"}
name={isOpen && "Tony Reichert"}
/>
</DropdownTrigger>
<DropdownMenu aria-label="User Actions" variant="flat">
<DropdownItem key="profile" className="h-14 gap-2">
<p className="font-bold">Signed in as</p>
<p className="font-bold">@tonyreichert</p>
</DropdownItem>
<DropdownItem key="team_settings">Profile Settings</DropdownItem>
<DropdownItem key="analytics">
Analytics
</DropdownItem>
<DropdownItem key="help_and_feedback">
Help & Feedback
</DropdownItem>
<DropdownItem key="logout" color="danger">
Log Out
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
</div>
<SidebarMenu>
{sideBarDummyData
? sideBarDummyData?.map((list: any, index: number) => (
list.isGroup ?
<p className={`font-bold mr-4 ${!isOpen ? 'text-center' : ''}`}>{isOpen ? list.name : "..."}</p>
:
list.childMenu?.length < 1 ?
<>
{isOpen ?
<Link key={list.id} href={list.modulePathUrl}>
<div className={`px-3.5 py-2 mr-4 rounded-lg hover:bg-zinc-400 dark:hover:text-zinc-600 flex flex-row gap-2 ${pathname.includes(list.modulePathUrl) ? "bg-zinc-600 dark:bg-zinc-300 text-zinc-300 dark:text-zinc-500 font-bold" : "text-zinc-600 dark:text-zinc-400"}`}>
{list.icon} {isOpen && list.name}
</div>
</Link> :
<Tooltip content={list.name} placement="right" delay={0} closeDelay={0}>
<Link key={list.id} href={list.modulePathUrl}>
<div className={`py-2 mr-4 rounded-lg hover:bg-zinc-400 dark:hover:text-zinc-600 flex flex-row justify-center gap-1 ${pathname.includes(list.modulePathUrl) ? "bg-zinc-600 dark:bg-zinc-300 text-zinc-300 dark:text-zinc-500 font-bold" : "text-zinc-600 dark:text-zinc-400"}`}>
{list.icon} {isOpen && list.name}
</div>
</Link>
</Tooltip>
}
</>
:
<SidebarCollapseItems
key={list.id}
title={list.name}
isActive={pathname.includes(list.modulePathUrl)}
icon={list.icon}
items={[
list?.childMenu?.map((item: any) => (
<SidebarCollapseSubItems
key={item.id}
title={item?.name}
isActive={pathname.includes(item.modulePathUrl)}
isParentActive={pathname.includes(list.modulePathUrl)}
path={item.modulePathUrl}
icon={item.icon}
/>
)),
]}
/>
))
: ""}
</SidebarMenu>
<div className={`mt-12 p-2 flex ${isOpen ? "justify-start ml-2" : "justify-center"} mt-auto flex flex-col items-between`}>
<div className='flex flex-col gap-4'>
<div className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
<ThemeSwitch />
{isOpen && "Theme"}
</div>
{isOpen ?
<a className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
<InfoCircleIcon size={24} />
{isOpen && "Support"}
</a>
:
<Tooltip content="Support" delay={0} closeDelay={0} placement='right'>
<a className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
<InfoCircleIcon size={24} />
{isOpen && "Support"}
</a>
</Tooltip>
}
{isOpen ?
<a className={`ml-[1px] cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
<MinusCircleIcon size={21} />
{isOpen && "Log Out"}
</a>
:
<Tooltip content="Log Out" delay={0} closeDelay={0} placement='right'>
<a className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
<MinusCircleIcon size={21} />
{isOpen && "Log Out"}
</a>
</Tooltip>
}
</div>
</div>
</div>
{/* <div className="hidden md:block w-20 bg-gray-100 dark:bg-stone-950 h-full text-black dark:text-white">
<div className={`mt-4 flex justify-center w-full ${isOpen ? "hidden" : ""}`}>
<button
className="w-6 h-6 z-40"
onClick={toggleSidebar}
>
<MenuBurgerIcon />
</button>
</div>
{sideBarDummyData.map((list) => (
<div key={list.id} className='w-full flex justify-center my-2'>
<ClosedSidebarIcon icon={list.icon} isActive={pathname.includes(list.modulePathUrl)} childMenu={list.childMenu} path={list.modulePathUrl} title={list.name} />
</div>
))}
</div>
{isOpen && (
<div
className="block md:hidden fixed top-0 left-0 h-full w-full bg-black opacity-50 z-30"
onClick={toggleSidebar}
></div>
)} */}
</div>
);
};
export default Sidebar;

View File

@ -0,0 +1,253 @@
"use client";
import {
AddIcon,
CreateIconIon,
DeleteIcon,
DotsYIcon,
EyeFilledIcon,
EyeIcon,
EyeIconMdi
} from "@/components/icons";
import { getListArticle } from "@/service/article";
import { Article } from "@/types/globals";
import { Button } from "@nextui-org/button";
import {
Chip,
ChipProps,
Dropdown,
DropdownItem,
DropdownMenu,
DropdownTrigger,
Spinner,
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
User
} from "@nextui-org/react";
import Link from "next/link";
import { Key, useCallback, useEffect, useState } from "react";
type UserObject = {
id: number;
user: string;
status: string;
projectName: string;
avatar: string;
};
const statusColorMap = {
active: "success",
paused: "danger",
vacation: "warning",
};
export default function ArticleTable() {
const [article, setArticle] = useState<Article[]>([]);
useEffect(() => {
async function initState() {
const res = await getListArticle();
setArticle(res.data?.data);
console.log("Data Aritcle", res.data.data);
}
initState();
}, []);
type TableRow = (typeof usersTable)[0];
const columns = [
{ name: "No", uid: "no" },
{ name: "Judul", uid: "title" },
{ name: "Kategori", uid: "articleCategory" },
{ name: "Tanggal Unggah", uid: "createdDate" },
{ name: "Kreator", uid: "creator" },
{ name: "Sumber", uid: "source" },
// { name: "Users", uid: "users" },
{ name: "Status", uid: "status" },
{ name: "Aksi", uid: "actions" },
];
// const statusOptions = [
// { name: "Active", uid: "active" },
// { name: "Paused", uid: "paused" },
// { name: "Vacation", uid: "vacation" },
// ];
const usersTable = [
{
id: 1,
user: "Olivia Rhya",
status: "active",
projectName: "Xtreme admin",
avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
},
{
id: 2,
user: "Barbara Steele",
status: "cancel",
projectName: "Adminpro admin",
avatar: "https://cdn.icon-icons.com/icons2/2859/PNG/512/avatar_face_man_boy_male_profile_smiley_happy_people_icon_181661.png",
},
{
id: 3,
user: "Leonardo Gordon",
status: "pending",
projectName: "Monster admin",
avatar: "https://cdn.icon-icons.com/icons2/2859/PNG/512/avatar_face_man_boy_male_profile_smiley_happy_people_icon_181657.png",
},
{
id: 4,
user: "Evelyn Pope",
status: "cancel",
projectName: "Materialpro admin",
avatar: "https://cdn.icon-icons.com/icons2/3708/PNG/512/man_person_people_avatar_icon_230017.png",
},
{
id: 5,
user: "Tommy Garza",
status: "cancel",
projectName: "Elegant admin",
avatar: "https://cdn.icon-icons.com/icons2/1736/PNG/512/4043275-avatar-man-person-punk_113271.png",
},
];
const renderCell = useCallback(
(article: Article, columnKey: Key) => {
const cellValue = article[columnKey as keyof Article];
const statusColorMap: Record<string, ChipProps["color"]> = {
active: "primary",
cancel: "danger",
pending: "success",
};
switch (columnKey) {
case "no":
return (
<div>{article.id}</div>
)
case "status":
return (
<Chip
className="capitalize "
color={statusColorMap[article.status]}
size="lg"
variant="flat"
>
<div className="flex flex-row items-center gap-2 justify-center">
{cellValue}
</div>
</Chip>
);
case "actions":
return (
<div className="relative flex justify-star items-center gap-2">
<Dropdown className="lg:min-w-[150px] bg-black text-white shadow border ">
<DropdownTrigger>
<Button isIconOnly size="lg" variant="light">
<DotsYIcon className="text-default-300" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem
>
<Link
href={`#`}
>
<EyeIconMdi className="inline mr-2 mb-1" />
Detail
</Link>
</DropdownItem>
<DropdownItem
>
<Link
href={`#`}
>
<CreateIconIon className="inline mr-2 mb-1" />
Edit
</Link>
</DropdownItem>
<DropdownItem
>
<Link
href={`#`}
>
<DeleteIcon
color="red"
width={20}
height={16}
className="inline mr-2 mb-1"
/>
Delete
</Link>
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
);
default:
return cellValue;
}
}, []);
return (
<>
<div className="mx-5 my-5">
<div className="flex flex-col items-center rounded-2xl">
<Table
// selectionMode="multiple"
aria-label="micro issue table"
className="rounded-3xl"
classNames={{
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
base: "bg-white dark:bg-black border",
wrapper: "min-h-[50px] bg-transpararent text-black dark:text-white ",
}}
>
<TableHeader columns={columns}>
{(column) => (
<TableColumn key={column.uid}>{column.name}</TableColumn>
)}
</TableHeader>
<TableBody
items={article}
emptyContent={"No data to display."}
loadingContent={<Spinner label="Loading..." />}
>
{(item) => (
<TableRow key={item.id}>
{(columnKey) => (
<TableCell>{renderCell(item, columnKey)}</TableCell>
)}
</TableRow>
)}
</TableBody>
</Table>
</div>
</div>
</>
);
}

View File

@ -0,0 +1,207 @@
"use client";
import {
TableCell,
TableRow,
Table,
TableHeader,
TableColumn,
TableBody,
Pagination,
Dropdown,
DropdownTrigger,
DropdownMenu,
DropdownItem,
Input,
User,
Card,
Divider,
Chip,
ChipProps,
} from "@nextui-org/react";
import { Button } from "@nextui-org/button";
import React, { Key, useCallback, useMemo, useState } from "react";
import {
AccIcon,
CloseIcon,
CreateIconIon,
DeleteIcon,
DotsXIcon,
DotsYIcon,
EyeIconMdi,
OfflineIcon,
OnlineIcon,
RefundIcon,
SearchIcon,
} from "@/components/icons";
import Link from "next/link";
type UserObject = {
id: number;
user: string;
status: string;
projectName: string;
avatar: string;
};
export default function UsersTable() {
type TableRow = (typeof usersTable)[0];
const columns = [
{ name: "Users", uid: "user" },
{ name: "ProjectName", uid: "projectName" },
{ name: "Team", uid: "team" },
{ name: "Status", uid: "status" },
{ name: "Budget", uid: "budget" },
];
const usersTable = [
{
id: 1,
user: "Sunil Joshi",
description: "Web Designer",
team: "S",
status: "Active",
projectName: "Elite admin",
budget: "$3.9k",
avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
},
{
id: 2,
user: "AndrewMcDownland",
description: "Project Manager",
team: "T",
status: "Pending",
projectName: "Real Homes WP Theme",
budget: "$24.5k",
avatar: "https://cdn.icon-icons.com/icons2/2859/PNG/512/avatar_face_man_boy_male_profile_smiley_happy_people_icon_181661.png",
},
{
id: 3,
user: "Cristopher jamil",
description: "Project Manager",
team: "X",
status: "Completed",
projectName: "MediacalPro WP Theme",
budget: "$12.8k",
avatar: "https://cdn.icon-icons.com/icons2/2859/PNG/512/avatar_face_man_boy_male_profile_smiley_happy_people_icon_181657.png",
},
{
id: 4,
user: "Nirav Joshi",
description: "Frontend Engineer",
team: "A",
status: "Active",
projectName: "Hosting Press HTML",
budget: "$2.4k",
avatar: "https://cdn.icon-icons.com/icons2/3708/PNG/512/man_person_people_avatar_icon_230017.png",
},
{
id: 5,
user: "MichealDoe",
description: "Content Writer",
team: "S",
status: "Cancel",
projectName: "Helping Hands WP Theme",
budget: "$9.3k",
avatar: "https://cdn.icon-icons.com/icons2/1736/PNG/512/4043275-avatar-man-person-punk_113271.png",
},
];
const renderCell = useCallback((basic: TableRow, columnKey: Key) => {
const cellValue = basic[columnKey as keyof UserObject];
const statusColorMap: Record<string, ChipProps["color"]> = {
Active: "success",
Cancel: "danger",
Pending: "warning",
Completed: "primary"
};
switch (columnKey) {
case "no":
return (
<div>{basic.id}</div>
)
case "user":
return (
<User
avatarProps={{ radius: "lg", src: basic.avatar }}
description={basic.description}
name={cellValue}
>
{basic.description}
</User>
)
case "team":
return (
<div className="bg-blue-400 h-11 w-11 flex flex-row justify-center items-center text-lg rounded-full">{cellValue}</div>
)
case "status":
return (
<Chip
className="capitalize "
color={statusColorMap[basic.status]}
size="lg"
variant="flat"
>
<div className="flex flex-row items-center gap-2 justify-center">
{cellValue}
</div>
</Chip>
);
case "budget":
return (
<div className="relative flex justify-star items-center gap-2">
<p className="text-lg font-semibold font-serif">{cellValue}</p>
</div>
);
default:
return cellValue;
}
}, []);
return (
<>
<div className="mx-5 my-5">
<div className="flex flex-col items-center rounded-2xl">
<Table
// selectionMode="multiple"
aria-label="micro issue table"
className="rounded-3xl"
classNames={{
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
base: "bg-white dark:bg-black border",
wrapper: "min-h-[50px] bg-transpararent text-black dark:text-white ",
}}
>
<TableHeader columns={columns}>
{(column) => (
<TableColumn key={column.uid}>{column.name}</TableColumn>
)}
</TableHeader>
<TableBody items={usersTable} emptyContent={"No data to display."}>
{(item) => (
<TableRow key={item.id}>
{(columnKey) => (
<TableCell>{renderCell(item, columnKey)}</TableCell>
)}
</TableRow>
)}
</TableBody>
</Table>
</div>
</div>
</>
);
}

View File

@ -0,0 +1,55 @@
"use client";
import { useEffect, useState } from "react";
import { Button } from "@nextui-org/button";
import { BreadcrumbItem, Breadcrumbs } from "@nextui-org/react";
import { usePathname, useRouter } from "next/navigation";
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(' ');
});
console.log('pathname : ', pathnameTransformed);
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);
}
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 >
);
};

95
config/swal.ts Normal file
View File

@ -0,0 +1,95 @@
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { useRouter } from "next/navigation";
const MySwal = withReactContent(Swal);
const Toast = MySwal.mixin({
toast: true,
position: "top-end",
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener("mouseenter", Swal.stopTimer);
toast.addEventListener("mouseleave", Swal.resumeTimer);
},
});
export function loading(msg?: any) {
let timerInterval: any;
MySwal.fire({
title: msg || "Loading...",
allowOutsideClick: false,
timerProgressBar: true,
didOpen: () => {
MySwal.showLoading();
timerInterval = setInterval(() => { }, 100);
},
willClose: () => {
clearInterval(timerInterval);
},
});
}
export function error(msg?: any) {
MySwal.fire({
icon: "error",
title: "Failed...",
text: msg || "Unknown Error",
});
}
export function successRouter(redirect: string, router?: any) {
MySwal.fire({
title: "Success!",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "Ok",
allowOutsideClick: false,
}).then((result) => {
if (result.isConfirmed) {
router.push(redirect);
}
});
}
export function success(title: string) {
MySwal.fire({
title: title || "Success!",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then((result) => {
if (result.isConfirmed) {
return true;
}
});
}
export function close() {
MySwal.close();
}
export function warning(text: string, redirect: string, router?: any) {
MySwal.fire({
title: text,
icon: "warning",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then((result) => {
if (result.isConfirmed) {
router.push(redirect);
}
});
}
export function successToast(title: string, text: string) {
Toast.fire({
icon: "success",
title: title,
text: text,
});
}

271
package-lock.json generated
View File

@ -27,22 +27,29 @@
"@types/react": "18.2.21", "@types/react": "18.2.21",
"@types/react-datepicker": "^6.0.1", "@types/react-datepicker": "^6.0.1",
"@types/react-dom": "18.2.7", "@types/react-dom": "18.2.7",
"apexcharts": "^3.48.0",
"autoprefixer": "10.4.16", "autoprefixer": "10.4.16",
"axios": "^1.6.8",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"eslint": "8.48.0", "eslint": "8.48.0",
"eslint-config-next": "14.0.2", "eslint-config-next": "14.0.2",
"framer-motion": "^10.18.0", "framer-motion": "^10.18.0",
"intl-messageformat": "^10.5.0", "intl-messageformat": "^10.5.0",
"jodit-react": "^4.0.25",
"next": "14.0.2", "next": "14.0.2",
"next-themes": "^0.2.1", "next-themes": "^0.2.1",
"postcss": "8.4.31", "postcss": "8.4.31",
"react": "18.2.0", "react": "18.2.0",
"react-apexcharts": "^1.4.1",
"react-datepicker": "^6.1.0", "react-datepicker": "^6.1.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hook-form": "^7.50.1", "react-hook-form": "^7.50.1",
"react-icons": "^5.0.1", "react-icons": "^5.0.1",
"react-sweetalert2": "^0.6.0",
"react-tailwindcss-datepicker": "^1.6.6", "react-tailwindcss-datepicker": "^1.6.6",
"react-tweet": "^3.2.0", "react-tweet": "^3.2.0",
"sweetalert2": "^11.10.8",
"sweetalert2-react-content": "^5.0.7",
"swiper": "^11.0.6", "swiper": "^11.0.6",
"tailwind-variants": "^0.1.18", "tailwind-variants": "^0.1.18",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
@ -2954,6 +2961,11 @@
"url": "https://opencollective.com/typescript-eslint" "url": "https://opencollective.com/typescript-eslint"
} }
}, },
"node_modules/@yr/monotone-cubic-spline": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.11.2", "version": "8.11.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
@ -3027,6 +3039,20 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/apexcharts": {
"version": "3.48.0",
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.48.0.tgz",
"integrity": "sha512-Lhpj1Ij6lKlrUke8gf+P+SE6uGUn+Pe1TnCJ+zqrY0YMvbqM3LMb1lY+eybbTczUyk0RmMZomlTa2NgX2EUs4Q==",
"dependencies": {
"@yr/monotone-cubic-spline": "^1.0.3",
"svg.draggable.js": "^2.2.2",
"svg.easing.js": "^2.0.0",
"svg.filter.js": "^2.0.2",
"svg.pathmorphing.js": "^0.1.3",
"svg.resize.js": "^1.4.3",
"svg.select.js": "^3.0.1"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@ -3180,6 +3206,20 @@
"has-symbols": "^1.0.3" "has-symbols": "^1.0.3"
} }
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/autobind-decorator": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/autobind-decorator/-/autobind-decorator-2.4.0.tgz",
"integrity": "sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw==",
"engines": {
"node": ">=8.10",
"npm": ">=6.4.1"
}
},
"node_modules/autoprefixer": { "node_modules/autoprefixer": {
"version": "10.4.16", "version": "10.4.16",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz",
@ -3235,6 +3275,16 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/axios": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axobject-query": { "node_modules/axobject-query": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@ -3478,6 +3528,17 @@
"resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz", "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz",
"integrity": "sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==" "integrity": "sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w=="
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": { "node_modules/commander": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@ -3609,6 +3670,14 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dequal": { "node_modules/dequal": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@ -4302,6 +4371,25 @@
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ=="
}, },
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-each": { "node_modules/for-each": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@ -4310,6 +4398,19 @@
"is-callable": "^1.1.3" "is-callable": "^1.1.3"
} }
}, },
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fraction.js": { "node_modules/fraction.js": {
"version": "4.3.7", "version": "4.3.7",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
@ -5033,6 +5134,26 @@
"jiti": "bin/jiti.js" "jiti": "bin/jiti.js"
} }
}, },
"node_modules/jodit": {
"version": "4.1.16",
"resolved": "https://registry.npmjs.org/jodit/-/jodit-4.1.16.tgz",
"integrity": "sha512-rqBGuYkmaU4cJrmid2vtdBFMA0eCFp6S7qhP2aNf92wBiLYmo+UnvyW08lH+CcZ2ZoWtVjEiqzGMvj8kZ0zsKA==",
"dependencies": {
"autobind-decorator": "^2.4.0"
}
},
"node_modules/jodit-react": {
"version": "4.0.25",
"resolved": "https://registry.npmjs.org/jodit-react/-/jodit-react-4.0.25.tgz",
"integrity": "sha512-HFbbpabQlE3UdD5mOVm/ZHCRVMtNHCy5oZi4mWquM1W6uNrQG5sO7GuIYTxmW84qfTpuKPWjyw2q1ov/YFW8ug==",
"dependencies": {
"jodit": "^4.1.16"
},
"peerDependencies": {
"react": "~0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "~0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -5233,6 +5354,25 @@
"node": ">=8.6" "node": ">=8.6"
} }
}, },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@ -5764,6 +5904,11 @@
"react-is": "^16.13.1" "react-is": "^16.13.1"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@ -5802,6 +5947,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-apexcharts": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
"integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
"apexcharts": "^3.41.0",
"react": ">=0.13"
}
},
"node_modules/react-datepicker": { "node_modules/react-datepicker": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.1.0.tgz", "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.1.0.tgz",
@ -5947,6 +6104,18 @@
} }
} }
}, },
"node_modules/react-sweetalert2": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/react-sweetalert2/-/react-sweetalert2-0.6.0.tgz",
"integrity": "sha512-4MEWGAJamSfoj56m7MUs7IfBnev9wJYs0RayvoHvxshSQeH62iK0N/EkDiHr3VuZ3vTy34kOpzL1Yg3b3VYF8w==",
"dependencies": {
"sweetalert2": "^11.7.5"
},
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
},
"node_modules/react-tailwindcss-datepicker": { "node_modules/react-tailwindcss-datepicker": {
"version": "1.6.6", "version": "1.6.6",
"resolved": "https://registry.npmjs.org/react-tailwindcss-datepicker/-/react-tailwindcss-datepicker-1.6.6.tgz", "resolved": "https://registry.npmjs.org/react-tailwindcss-datepicker/-/react-tailwindcss-datepicker-1.6.6.tgz",
@ -6449,6 +6618,108 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/svg.draggable.js": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
"integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
"dependencies": {
"svg.js": "^2.0.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/svg.easing.js": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
"integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==",
"dependencies": {
"svg.js": ">=2.3.x"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/svg.filter.js": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
"integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==",
"dependencies": {
"svg.js": "^2.2.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/svg.js": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
"integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
},
"node_modules/svg.pathmorphing.js": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
"integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
"dependencies": {
"svg.js": "^2.4.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/svg.resize.js": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
"integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
"dependencies": {
"svg.js": "^2.6.5",
"svg.select.js": "^2.1.2"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/svg.resize.js/node_modules/svg.select.js": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
"integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
"dependencies": {
"svg.js": "^2.2.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/svg.select.js": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
"integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
"dependencies": {
"svg.js": "^2.6.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/sweetalert2": {
"version": "11.10.8",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.8.tgz",
"integrity": "sha512-oAkYROBfXBY+4sVbQEIcN+ZxAx69lsmz5WEBwdEpyS4m59vOBNlRU5/fJpAI1MVfiDwFZiGwVzB/KBpOyfLNtg==",
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/limonte"
}
},
"node_modules/sweetalert2-react-content": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/sweetalert2-react-content/-/sweetalert2-react-content-5.0.7.tgz",
"integrity": "sha512-8Fk82Mpk45lFXpJWKIFF/lq8k/dJKDDQGFcuqVosaL/qRdViyAs5+u37LoTGfnOIvf+rfQB3PAXcp1XLLn+0ew==",
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0",
"sweetalert2": "^11.0.0"
}
},
"node_modules/swiper": { "node_modules/swiper": {
"version": "11.0.6", "version": "11.0.6",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.0.6.tgz", "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.0.6.tgz",

View File

@ -28,22 +28,29 @@
"@types/react": "18.2.21", "@types/react": "18.2.21",
"@types/react-datepicker": "^6.0.1", "@types/react-datepicker": "^6.0.1",
"@types/react-dom": "18.2.7", "@types/react-dom": "18.2.7",
"apexcharts": "^3.48.0",
"autoprefixer": "10.4.16", "autoprefixer": "10.4.16",
"axios": "^1.6.8",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"eslint": "8.48.0", "eslint": "8.48.0",
"eslint-config-next": "14.0.2", "eslint-config-next": "14.0.2",
"framer-motion": "^10.18.0", "framer-motion": "^10.18.0",
"intl-messageformat": "^10.5.0", "intl-messageformat": "^10.5.0",
"jodit-react": "^4.0.25",
"next": "14.0.2", "next": "14.0.2",
"next-themes": "^0.2.1", "next-themes": "^0.2.1",
"postcss": "8.4.31", "postcss": "8.4.31",
"react": "18.2.0", "react": "18.2.0",
"react-apexcharts": "^1.4.1",
"react-datepicker": "^6.1.0", "react-datepicker": "^6.1.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hook-form": "^7.50.1", "react-hook-form": "^7.50.1",
"react-icons": "^5.0.1", "react-icons": "^5.0.1",
"react-sweetalert2": "^0.6.0",
"react-tailwindcss-datepicker": "^1.6.6", "react-tailwindcss-datepicker": "^1.6.6",
"react-tweet": "^3.2.0", "react-tweet": "^3.2.0",
"sweetalert2": "^11.10.8",
"sweetalert2-react-content": "^5.0.7",
"swiper": "^11.0.6", "swiper": "^11.0.6",
"tailwind-variants": "^0.1.18", "tailwind-variants": "^0.1.18",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",

View File

@ -1,4 +1,4 @@
import { httpGet } from "./http-config/axios-base-service"; import { httpGet, httpPost } from "./http-config/axios-base-service";
export async function getListArticle() { export async function getListArticle() {
const headers = { const headers = {
@ -6,3 +6,8 @@ export async function getListArticle() {
}; };
return await httpGet(`/articles`, headers); return await httpGet(`/articles`, headers);
} }
export async function createArticle(data: any) {
const pathUrl = `/articles`;
return await httpPost(pathUrl, data);
}

View File

@ -3,7 +3,7 @@ import axiosBaseInstance from "./http-base-service";
export async function httpPost(pathUrl: any, headers: any, data?: any) { export async function httpPost(pathUrl: any, headers: any, data?: any) {
const response = await axiosBaseInstance const response = await axiosBaseInstance
.post(pathUrl, data, { headers }) .post(pathUrl, data, { headers })
.catch(function (error) { .catch(function (error: any) {
console.log(error); console.log(error);
return error.response; return error.response;
}); });
@ -26,7 +26,7 @@ export async function httpPost(pathUrl: any, headers: any, data?: any) {
export async function httpGet(pathUrl: any, headers: any) { export async function httpGet(pathUrl: any, headers: any) {
const response = await axiosBaseInstance const response = await axiosBaseInstance
.get(pathUrl, { headers }) .get(pathUrl, { headers })
.catch(function (error) { .catch(function (error: any) {
console.log(error); console.log(error);
return error.response; return error.response;
}); });

View File

@ -8,8 +8,9 @@
border:1px solid green; border:1px solid green;
} */ } */
.custom-scrollbar::-webkit-scrollbar { .custom-scrollbar::-webkit-scrollbar {
width: 12px; width: 1px;
} }
.custom-scrollbar::-webkit-scrollbar-track { .custom-scrollbar::-webkit-scrollbar-track {
@ -17,6 +18,18 @@
} }
.custom-scrollbar::-webkit-scrollbar-thumb { .custom-scrollbar::-webkit-scrollbar-thumb {
background: transparent; background: rgb(190, 189, 189);
border-radius: 5px; border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: transparent;
}
.hidden-tooltip {
display: none;
}
.sidebar-scrollbar {
--scroll-shadow-size: 40px;
} }

26
types/globals.tsx Normal file
View File

@ -0,0 +1,26 @@
import { SVGProps } from "react";
export type IconSvgProps = SVGProps<SVGSVGElement> & {
size?: number;
};
export type SidebarMenuTask = {
childMenu: any[];
name: string;
id: number;
parentId: number;
position: number;
statusId: number;
statusName: string;
};
export type Article = {
id: number;
title: string;
articleCategory: string;
updated_at: string;
creator: string;
source: string;
status: string;
actions: string;
};