feat:add data table master-user-level and form master-user-level

This commit is contained in:
Anang Yusman 2024-04-23 12:23:30 +07:00
commit ea15b175c7
60 changed files with 3867 additions and 124 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

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

View File

@ -2,6 +2,7 @@
import CategorySatker from './CategorySatker'
import ENewsPolri from './ENewsPolri'
import MediaSocial from './MediaSocial'
import MedolUpdate from './MedolUpdate'
import RegionalNews from './RegionalNews'
import SidebarNav from './SidebarNav'
@ -10,6 +11,7 @@ export default function BodyLayout() {
<>
<div className='md:flex bg-white text-black pt-10 pb-8 px-2 md:px-4 lg:px-8 gap-9'>
<div className='w-auto md:w-[65%] lg:w-[75%] space-y-7'>
<MedolUpdate />
<CategorySatker />
<RegionalNews />
<MediaSocial />

View File

@ -5,11 +5,10 @@ import { MailIcon } from '../icons'
export default function Footer() {
return (
<div className='relative text-xs leading-4 md:leading-loose lg:leading-8 font-semibold '>
<div className='h-[620px] md:h-[720px] lg:h-auto bg-black'>
<img src="/temp/foot.png" alt="" className='w-full h-full object-cover object-left-top opacity-50' />
<div className='h-[650px] md:h-[720px] lg:h-auto bg-black'>
<img src="/assets/Footer.jpg" alt="" className='w-full h-full object-cover object-left-top opacity-80' />
</div>
<div className="absolute top-0 left-0 w-full grid grid-cols-3 md:grid-cols-5 lg:grid-cols-5 gap-2 md:gap-4 px-1 md:px-10 lg:px-20 pt-5 md:pt-16 pb-5 md:pb-20 text-white">
<div className="absolute top-0 left-0 w-full grid grid-cols-3 md:grid-cols-4 lg:grid-cols-7 gap-5 md:gap-4 px-1 md:px-10 lg:px-20 pt-5 md:pt-16 pb-5 md:pb-20 text-white">
<div className='pb-2 md:pb-0'>
<p>Berita Terkini</p>
<p>Info Komnas Anak</p>
@ -46,13 +45,13 @@ export default function Footer() {
<p>Pelayanan Polisiku</p>
<p>Pelayanan BINMAS</p>
</div>
<div className=''>
<div className='w-auto lg:w-max'>
<p className='text-xl font-bold'>Subscribe</p>
<p>Dapatkan info & event terupdate dari kami.</p>
<Input
label="Email"
placeholder="Email Anda"
className='w-min pt-2'
className='w-min pt-1'
startContent={
<MailIcon className="text-xl text-default-400 pointer-events-none flex-shrink-0" />
}
@ -62,10 +61,10 @@ export default function Footer() {
</div>
}
/>
<Button className='mt-3 bg-[#DD8306]'>Kontributor Wilayah</Button>
<Button className='mt-1 bg-[#DD8306]'>Kontributor Wilayah</Button>
</div>
</div>
<div className='dark:bg-black text-black dark:text-white text-center py-5 text-xs md:text-medium flex justify-center font-normal'>&copy; Copyright Humas<p className='text-red-700'>&nbsp; POLRI &reg;</p>&nbsp; All Rights Reserved</div>
<div className='dark:bg-black text-black dark:text-white text-center py-3 text-xs md:text-medium flex justify-center font-normal'>&copy; Copyright Humas<p className='text-red-700'>&nbsp; POLRI &reg;</p>&nbsp; All Rights Reserved</div>
</div>
)
}

View File

@ -8,8 +8,20 @@ import 'swiper/css/pagination';
import { Autoplay, Pagination, Navigation } from 'swiper/modules';
import Link from 'next/link';
import GPRKominfo from '../SocialMedia/GprKominfo';
import { useEffect, useState } from 'react';
import { getListArticle } from '@/service/article';
export default function HeaderNews() {
const [article, setArticle] = useState();
useEffect(() => {
async function getArticle() {
const response = await getListArticle();
console.log("res", response?.data?.data);
}
getArticle();
}, []);
const newsData = [
{
id: 1,

View File

@ -1,14 +1,8 @@
import { useEffect, useState } from 'react';
import { ChevronRightIcon, DotsIcon, FbIcon, IgIcon, TtIcon, TwitterIcon, YtIcon } from '../icons';
import { ScrollShadow } from '@nextui-org/react';
import { Tweet } from 'react-tweet';
import Link from 'next/link';
import YoutubePages from '../SocialMedia/Youtube';
import YoutubeWidget from '../SocialMedia/Youtube';
import InstagramWidget from '../SocialMedia/Instagram';
import TiktokWidget from '../SocialMedia/Tiktok';
import Facebookwidget from '../SocialMedia/Facebook';
import InstagramWidget from '../SocialMedia/Instagram';
import TwitterWidget from '../SocialMedia/Twitter';
import { ChevronRightIcon, FbIcon, IgIcon, TtIcon, TwitterIcon, YtIcon } from '../icons';
export default function MediaSocial() {
// const [limitedData, setLimitedData] = useState<any>([]);

View File

@ -0,0 +1,246 @@
import { Button, Card, CardBody, CardFooter, Image, Tab, Tabs } from '@nextui-org/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() {
const mediaHubUpdate = [
{
id: 1,
image: '/temp/mediahub1.png',
title: 'Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan',
createdDate: '12 Januari 2024',
time: '13:00 WITA'
},
{
id: 2,
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: 3,
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: 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 (
<div className='border-2 rounded-lg py-2'>
<div className='text-2xl font-semibold underline underline-offset-4 text-center decoration-red-600 '>
Top 5 News Update
</div>
<div className='bg-white text-black p-1 md:p-5 space-y-5'>
<Tabs
classNames={{
tabList: "bg-white shadow-lg border",
tabContent: 'group-data-[selected=true]:text-[white] text-warning'
}}
aria-label="Options" color='warning' className='flex justify-center'>
<Tab key="mediahub" title="MediaHUB Update">
<Swiper
navigation={true}
modules={[Navigation, Pagination]}
spaceBetween={40}
slidesPerView={2}
pagination={true}
className="mySwiper">
{mediaHubUpdate.map((newsItem) => (
<SwiperSlide>
<Card shadow="sm" className=' bg-white text-black border-2'>
<CardBody className="overflow-visible p-0">
<Image
radius="lg"
width="300%"
alt="tes"
className="object-cover h-[270px]"
src={newsItem.image}
/>
</CardBody>
<CardFooter className="flex flex-col items-start text-left">
<p className='text-xs'>02-04-2024 09:31 WITA</p>
<b className=''>Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan</b>
</CardFooter>
</Card>
</SwiperSlide>
))}
</Swiper>
<div className='text-center pt-6'>
<Button
className='bg-white text-[#DD8306] font-bold w-56'
size='sm'
color='warning'
variant='bordered'
>
Lihat Lebih Banyak
</Button>
</div>
</Tab>
<Tab key="tbnews" title="Tribrata News Update">
<div className='flex gap-5 justify-center pt-3'>
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'>
<CardBody className="overflow-visible p-0">
<Image
shadow="sm"
radius="lg"
width="300%"
alt="tes"
className="object-cover h-[270px]"
src='/temp/mediahub1.png'
/>
</CardBody>
<CardFooter className="flex flex-col items-start text-left">
<p className='text-xs'>02-04-2024 09:31 WITA</p>
<b className=''>Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan</b>
</CardFooter>
</Card>
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'>
<CardBody className="overflow-visible p-0">
<Image
shadow="sm"
radius="lg"
width="100%"
alt="tes"
className="w-full object-cover h-[270px]"
src='/temp/mediahub2.png'
/>
</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'>
<Button
className='bg-white text-[#DD8306] font-bold w-56'
size='sm'
color='warning'
variant='bordered'
>
Lihat Lebih Banyak
</Button>
</div>
</Tab>
<Tab key="inp" title="Indonesia Nasional Police Update">
<div className='flex gap-5 justify-center pt-3'>
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'>
<CardBody className="overflow-visible p-0">
<Image
shadow="sm"
radius="lg"
width="300%"
alt="tes"
className="object-cover h-[270px]"
src='/temp/mediahub1.png'
/>
</CardBody>
<CardFooter className="flex flex-col items-start text-left">
<p className='text-xs'>02-04-2024 09:31 WITA</p>
<b className=''>Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan</b>
</CardFooter>
</Card>
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'>
<CardBody className="overflow-visible p-0">
<Image
shadow="sm"
radius="lg"
width="100%"
alt="tes"
className="w-full object-cover h-[270px]"
src='/temp/mediahub2.png'
/>
</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'>
<Button
className='bg-white text-[#DD8306] font-bold w-56'
size='sm'
color='warning'
variant='bordered'
>
Lihat Lebih Banyak
</Button>
</div>
</Tab>
<Tab key="polritv" title="Polri TV Update">
<div className='flex gap-5 justify-center pt-3'>
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'>
<CardBody className="overflow-visible p-0">
<Image
shadow="sm"
radius="lg"
width="300%"
alt="tes"
className="object-cover h-[270px]"
src='/temp/mediahub1.png'
/>
</CardBody>
<CardFooter className="flex flex-col items-start text-left">
<p className='text-xs'>02-04-2024 09:31 WITA</p>
<b className=''>Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan</b>
</CardFooter>
</Card>
<Card shadow="sm" isPressable onPress={() => console.log("item pressed")} className='w-[45%] bg-white text-black'>
<CardBody className="overflow-visible p-0">
<Image
shadow="sm"
radius="lg"
width="100%"
alt="tes"
className="w-full object-cover h-[270px]"
src='/temp/mediahub2.png'
/>
</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'>
<Button
className='bg-white text-[#DD8306] font-bold w-56'
size='sm'
color='warning'
variant='bordered'
>
Lihat Lebih Banyak
</Button>
</div>
</Tab>
</Tabs>
</div>
</div>
)
}

View File

@ -47,13 +47,13 @@ export default function RegionalNews() {
const listPoldaAll = [
{
id: 1,
img: "/assets/polda/polda-metro.svg",
img: "/assets/polda/polda-metro-jaya.svg",
title: "Polda Metro Jaya",
path: '/news/polda-metro-jaya'
},
{
id: 2,
img: "/assets/polda/polda-jabar.svg",
img: "/assets/polda/polda-jawa-barat.svg",
title: "Polda Jawa Barat",
path: '/news/polda-jawa-barat'
},
@ -209,7 +209,7 @@ export default function RegionalNews() {
},
{
id: 28,
img: "/assets/polda/polda-sulut.svg",
img: "/assets/polda/polda-sulawesi-utara.svg",
title: "Polda Sulawesi Utara",
path: '/news/polda-sulawesi-utara'
},

View File

@ -1,4 +1,4 @@
import { LinkIcon, ScrollShadow } from '@nextui-org/react'
import { Button, LinkIcon, ScrollShadow } from '@nextui-org/react'
import React from 'react'
import { EyeIcon } from '../icons'
import Image from 'next/image'
@ -8,11 +8,22 @@ export default function SidebarNav() {
return (
<>
<div className='space-y-4'>
<div className='text-xl font-semibold underline underline-offset-4 decoration-red-600 '>
SERTIFIKAT ISO 9001:2015
</div>
<div className='h-[370px] text-white rounded-md'>
<Image height={200} width={380} src="/sertifikat.png" alt="publikasi" />
</div>
<div className='text-xl font-semibold underline underline-offset-4 decoration-red-600 '>
Media Update
</div>
<div className='h-[360px] p-2 bg-[#020101] text-white rounded-md border-2 border-white'>
<ScrollShadow hideScrollBar className=" h-[343px]">
<div className='h-[410px] p-2 bg-[#020101] text-white rounded-md border-2 border-white'>
<ScrollShadow hideScrollBar className=" h-[345px]">
<div className='text-xs text-left m-2 p-2 bg-[#1E1616] rounded-md'>
<p>Pelihara Kondusifitas Kamtibmas, Personel Polsek Sayan Sambangi Warganya yang Masih Beraktifitas Pada Malam Hari</p>
<p className='py-[2px]'>21-07-2023 13:50</p>
<p className='flex items-center gap-1'><EyeIcon />82</p>
</div>
<div className='text-xs text-left m-2 p-2 bg-[#1E1616] rounded-md'>
<p>Pelihara Kondusifitas Kamtibmas, Personel Polsek Sayan Sambangi Warganya yang Masih Beraktifitas Pada Malam Hari</p>
<p className='py-[2px]'>21-07-2023 13:50</p>
@ -34,8 +45,15 @@ export default function SidebarNav() {
<p className='flex items-center gap-1'><EyeIcon />82</p>
</div>
</ScrollShadow>
<Button
className='w-full bg-[#DD8306] font-bold rounded-bl-md rounded-br-md focus:outline-none'
radius='none'
>
Lihat Semua
</Button>
</div>
<div className='text-xl font-semibold underline underline-offset-4 decoration-red-600'>Publikasi
<div className='text-xl font-semibold underline underline-offset-4 decoration-red-600'>
Publikasi
<div className='flex flex-col gap-3 pt-3'>
<Image height={200} width={400} src="/publikasi1.png" alt="publikasi" />
<Image height={200} width={400} src="/publikasi2.png" alt="publikasi" />
@ -55,6 +73,9 @@ export default function SidebarNav() {
</div>
<div className='text-xl font-semibold underline underline-offset-4 decoration-red-600'>Channel Humas Polri
<div className='flex flex-col gap-3 m-10'>
<Link href='https://portal.humas.polri.go.id/library' target='_blank'>
<Image height={100} width={300} src="/portal-humas1.png" alt="humas-polri" />
</Link>
<Link href='https://mediahub.polri.go.id/' target='_blank'>
<Image height={100} width={300} src="/humas1.png" alt="humas-polri" />
</Link>
@ -64,9 +85,12 @@ export default function SidebarNav() {
<Link href='https://tvradio.polri.go.id/' target='_blank'>
<Image height={100} width={300} src="/humas3.png" alt="humas-polri" />
</Link>
<Link href='https://tribratanews.polri.go.id/' target='_blank' className='border-2 rounded-md shadow-md'>
<Link href='https://tribratanews.polri.go.id/' target='_blank' className='border-2 rounded-md shadow-sm'>
<Image height={100} width={300} src="/humas4.png" alt="humas-polri" />
</Link>
<Link href='https://inp.polri.go.id/' target='_blank' className='border-2 rounded-md shadow-sm px-2'>
<Image height={100} width={300} src="/humas5.png" alt="humas-polri" />
</Link>
</div>
</div>
</div>

View File

@ -1,6 +1,5 @@
'use client'
import { Card, CardBody, Tab, Tabs } from '@nextui-org/react'
import React from 'react'
import { Tab, Tabs } from '@nextui-org/react'
export default function Task() {
return (

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

@ -772,28 +772,140 @@ export const Checklist = ({
</svg>
);
export const AddIcon = ({
export const ChevronLeftIcon = ({
size,
height = 12,
width = 12,
fill = "none",
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 12 12"
fill={fill}
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
d="M5.1665 6.83341H0.166504V5.16675H5.1665V0.166748H6.83317V5.16675H11.8332V6.83341H6.83317V11.8334H5.1665V6.83341Z"
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,
@ -841,11 +953,54 @@ export const DeleteIcon = ({
</svg>
);
export const DotsYIcon = ({
export const AccIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
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
@ -854,17 +1009,146 @@ export const DotsYIcon = ({
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">
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 EyeIconMdi = ({
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,
@ -881,12 +1165,38 @@ export const EyeIconMdi = ({
>
<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"
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 TimesIcon = ({
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,
@ -898,10 +1208,272 @@ export const TimesIcon = ({
height={size || height}
width={size || width}
viewBox="0 0 24 24"
fill={fill}
{...props}
>
<path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z" />
<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

@ -1,20 +1,39 @@
'use client'
import { siteConfig } from '@/config/site';
import { Input } from '@nextui-org/input';
import { Navbar, NavbarContent, NavbarItem, NavbarMenu, NavbarMenuItem, NavbarMenuToggle } from '@nextui-org/navbar';
import { Button, Dropdown, DropdownItem, DropdownMenu, DropdownSection, DropdownTrigger, autocomplete } from '@nextui-org/react';
import Link from "next/link";
import { ChevronDownIcon, ChevronRightIcon, ChevronRightWhite, ChevronUpIcon, FbIcon, IdnIcon, IgIcon, SearchIcon, TtIcon, TwIcon, YtIcon } from '../icons';
import { ThemeSwitch } from '../theme-switch';
import { Button, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger } from '@nextui-org/react';
import Image from 'next/image';
import { siteConfig } from '@/config/site';
import Link from "next/link";
import { useState } from 'react';
import { ChevronDownIcon, ChevronRightIcon, ChevronUpIcon, FbIcon, IdnIcon, IgIcon, SearchIcon, TtIcon, TwIcon, YtIcon } from '../icons';
import { ThemeSwitch } from '../theme-switch';
interface MenuItem {
key: string;
label: string;
href: URL;
submenu?: SubMenuItem[];
}
interface SubMenuItem {
label: string;
href: string;
}
interface DropdownOpenState {
[key: string]: boolean;
}
export default function NavbarHumas() {
const [dropdownOpen, setDropdownOpen] = useState<DropdownOpenState>({});
const [dropdownOpen, setDropdownOpen] = useState(false);
const toggleDropdown = () => {
setDropdownOpen(!dropdownOpen);
const toggleDropdown = (key: any) => {
setDropdownOpen({
...dropdownOpen,
[key]: !dropdownOpen[key]
});
};
const searchInput = (
@ -138,7 +157,7 @@ export default function NavbarHumas() {
</DropdownMenu>
</Dropdown>
</div>
<div><Link href="/portal-ppid">Portal PPID</Link></div>
<div><Link href="http://103.82.242.92:5000/" target='_blank'>Portal PPID</Link></div>
<div>
<Dropdown className='dark:bg-[#1F1A17]'>
<NavbarItem>
@ -249,34 +268,38 @@ export default function NavbarHumas() {
<NavbarMenu>
{/* {searchInput} */}
<div className="mt-1 flex flex-col gap-1">
{siteConfig.humasMenuItems.map((item, index) => (
<NavbarMenuItem key={`${item}-${index}`}>
{item.submenu ? (
<div>
<button onClick={toggleDropdown} className="flex items-center gap-2">
{siteConfig.humasMenuItems.map((item) => (
<div key={item.key} className="relative">
<NavbarMenuItem>
<div onClick={() => toggleDropdown(item.key)} className='flex items-end gap-2'>
{item.href ? (
<Link href={item.href} target='_blank'>
<span>{item.label}</span>
</Link>
) : (
<span>{item.label}</span>
{dropdownOpen ? (
)}
{item.submenu && (
dropdownOpen[item.key] ? (
<ChevronUpIcon />
) : (
<ChevronDownIcon />
)}
</button>
{dropdownOpen && (
<div className="flex flex-col mt-1 ml-2 text-medium gap-1">
{item.submenu.map((subItem, subIndex) => (
<Link key={`${subItem}-${subIndex}`} href={subItem.href}>
{subItem.label}
</Link>
))}
</div>
)
)}
</div>
) : (
<Link href={item.href} >
{item.label}
</Link>
</NavbarMenuItem>
{dropdownOpen[item.key] && item.submenu && (
<div className='pl-2'>
{item.submenu.map((subItem, subIndex) => (
<div key={subIndex}>
<Link href={subItem.href}>
{subItem.label}
</Link>
</div>
))}
</div>
)}
</NavbarMenuItem>
</div>
))}
</div>
</NavbarMenu>

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 >
);
};

View File

@ -41,7 +41,7 @@ export const siteConfig = {
},
{
label: "Profile Pimpinan POLRI",
href: "/visi-misi"
href: "/profile-pimpinan-polri"
},
{
label: "Struktur Organisasi",
@ -76,43 +76,43 @@ export const siteConfig = {
},
{
label: "Pelayanan SIM",
href: "/visi-misi"
href: "https://www.digitalkorlantas.id/sim/"
},
{
label: "Pelayanan e-Rikkes SIM",
href: "/struktur-organisasi"
href: "https://erikkes.id/"
},
{
label: "Pelayanan Tes Psikologi SIM",
href: "/visi-misi"
href: "https://eppsi.id/"
},
{
label: "Pelayanan e-Avis",
href: "/tugas-dan-fungsi"
href: "https://e-avis.korlantas.polri.go.id/"
},
{
label: "Pelayanan Samsat Digital",
href: "#"
href: "https://samsatdigital.id/"
},
{
label: "Pelayanan SKCK",
href: "#"
href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi&hl=en_US"
},
{
label: "Pelayanan Propam Presisi",
href: "#"
href: "https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam"
},
{
label: "Pelayanan Dumas Presisi",
href: "#"
href: "https://dumaspresisi.polri.go.id/"
},
{
label: "Pelayanan Binmas",
href: "#"
href: "https://bos.polri.go.id/login"
},
{
label: "Wistle Blower System",
href: "#"
href: "https://play.google.com/store/apps/details?id=id.go.ssdmpolri.pengaduanappsbarupolri2"
},
]
},

View File

@ -24,7 +24,7 @@ export function loading(msg?: any) {
timerProgressBar: true,
didOpen: () => {
MySwal.showLoading();
timerInterval = setInterval(() => {}, 100);
timerInterval = setInterval(() => { }, 100);
},
willClose: () => {
clearInterval(timerInterval);

162
package-lock.json generated
View File

@ -28,6 +28,7 @@
"@types/react": "18.2.21",
"@types/react-datepicker": "^6.0.1",
"@types/react-dom": "18.2.7",
"apexcharts": "^3.48.0",
"autoprefixer": "10.4.16",
"axios": "^1.6.8",
"clsx": "^2.0.0",
@ -41,12 +42,15 @@
"next-themes": "^0.2.1",
"postcss": "8.4.31",
"react": "18.2.0",
"react-apexcharts": "^1.4.1",
"react-datepicker": "^6.1.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.50.1",
"react-icons": "^5.0.1",
"react-sweetalert2": "^0.6.0",
"react-tailwindcss-datepicker": "^1.6.6",
"react-tweet": "^3.2.0",
"sweetalert2": "^11.10.8",
"sweetalert2-react-content": "^5.0.7",
"swiper": "^11.0.6",
"tailwind-variants": "^0.1.18",
@ -2773,6 +2777,11 @@
"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": {
"version": "8.11.2",
"license": "MIT",
@ -2839,6 +2848,20 @@
"node": ">= 8"
}
},
"node_modules/apexcharts": {
"version": "3.49.0",
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.49.0.tgz",
"integrity": "sha512-2T9HnbQFLCuYRPndQLmh+bEQFoz0meUbvASaGgiSKDuYhWcLBodJtIpKql2aOtMx4B/sHrWW0dm90HsW4+h2PQ==",
"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": {
"version": "5.0.2",
"license": "MIT"
@ -4845,19 +4868,19 @@
}
},
"node_modules/jodit": {
"version": "4.1.16",
"resolved": "https://registry.npmjs.org/jodit/-/jodit-4.1.16.tgz",
"integrity": "sha512-rqBGuYkmaU4cJrmid2vtdBFMA0eCFp6S7qhP2aNf92wBiLYmo+UnvyW08lH+CcZ2ZoWtVjEiqzGMvj8kZ0zsKA==",
"version": "4.2.7",
"resolved": "https://registry.npmjs.org/jodit/-/jodit-4.2.7.tgz",
"integrity": "sha512-v3UbHMcQLRrrDN/s2tEg+jsOmW7E9BqSJnLbsV0OLT9JAHcsoOpMcxgWYXXXC5mCGOTuJKzikXowuBCfRE4Jsg==",
"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==",
"version": "4.0.28",
"resolved": "https://registry.npmjs.org/jodit-react/-/jodit-react-4.0.28.tgz",
"integrity": "sha512-u3v2cTekJU4F8SCOU1kMKwgqUBclPNCuLtsIZGH5qktTx5cx+xPVWJZyJmozN+YwzBHOP0xg/9VjkSQEtE/rfA==",
"dependencies": {
"jodit": "^4.1.16"
"jodit": "^4.2.7"
},
"peerDependencies": {
"react": "~0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
@ -5584,6 +5607,18 @@
"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": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.6.0.tgz",
@ -5720,6 +5755,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": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/react-tailwindcss-datepicker/-/react-tailwindcss-datepicker-1.6.6.tgz",
@ -6214,11 +6261,93 @@
"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.7",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz",
"integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==",
"peer": true,
"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"
@ -6731,9 +6860,12 @@
}
},
"node_modules/zod": {
"version": "1.11.17",
"resolved": "https://registry.npmjs.org/zod/-/zod-1.11.17.tgz",
"integrity": "sha512-UzIwO92D0dSFwIRyyqAfRXICITLjF0IP8tRbEK/un7adirMssWZx8xF/1hZNE7t61knWZ+lhEuUvxlu2MO8qqA=="
"version": "3.22.4",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz",
"integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}
}

View File

@ -29,6 +29,7 @@
"@types/react": "18.2.21",
"@types/react-datepicker": "^6.0.1",
"@types/react-dom": "18.2.7",
"apexcharts": "^3.48.0",
"autoprefixer": "10.4.16",
"axios": "^1.6.8",
"clsx": "^2.0.0",
@ -42,12 +43,15 @@
"next-themes": "^0.2.1",
"postcss": "8.4.31",
"react": "18.2.0",
"react-apexcharts": "^1.4.1",
"react-datepicker": "^6.1.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.50.1",
"react-icons": "^5.0.1",
"react-sweetalert2": "^0.6.0",
"react-tailwindcss-datepicker": "^1.6.6",
"react-tweet": "^3.2.0",
"sweetalert2": "^11.10.8",
"sweetalert2-react-content": "^5.0.7",
"swiper": "^11.0.6",
"tailwind-variants": "^0.1.18",
@ -55,4 +59,4 @@
"typescript": "5.0.4",
"zod": "^1.11.17"
}
}
}

BIN
public/assets/Footer.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 KiB

BIN
public/humas5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
public/portal-humas.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
public/portal-humas1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
public/sertifikat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
public/temp/mediahub1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

BIN
public/temp/mediahub2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

13
service/article.ts Normal file
View File

@ -0,0 +1,13 @@
import { httpGet, httpPost } from "./http-config/axios-base-service";
export async function getListArticle() {
const headers = {
"content-type": "application/json",
};
return await httpGet(`/articles`, headers);
}
export async function createArticle(data: any) {
const pathUrl = `/articles`;
return await httpPost(pathUrl, data);
}

View File

@ -0,0 +1,48 @@
import axiosBaseInstance from "./http-base-service";
export async function httpPost(pathUrl: any, headers: any, data?: any) {
const response = await axiosBaseInstance
.post(pathUrl, data, { headers })
.catch(function (error: any) {
console.log(error);
return error.response;
});
console.log("Response base svc : ", response);
if (response?.status == 200 || response?.status == 201) {
return {
error: false,
message: "success",
data: response?.data,
};
} else {
return {
error: true,
message: response?.data?.message || response?.data || null,
data: null,
};
}
}
export async function httpGet(pathUrl: any, headers: any) {
const response = await axiosBaseInstance
.get(pathUrl, { headers })
.catch(function (error: any) {
console.log(error);
return error.response;
});
console.log("Response base svc : ", response);
if (response?.status == 200 || response?.status == 201) {
return {
error: false,
message: "success",
data: response?.data,
};
} else {
return {
error: true,
message: response?.data?.message || response?.data || null,
data: null,
};
}
}

View File

@ -0,0 +1,12 @@
import axios from "axios";
const baseURL = "http://103.82.242.92:8888";
const axiosBaseInstance = axios.create({
baseURL,
headers: {
"content-type": "application/json",
},
});
export default axiosBaseInstance;

View File

@ -8,8 +8,9 @@
border:1px solid green;
} */
.custom-scrollbar::-webkit-scrollbar {
width: 12px;
width: 1px;
}
.custom-scrollbar::-webkit-scrollbar-track {
@ -17,6 +18,18 @@
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: rgb(190, 189, 189);
border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: transparent;
border-radius: 5px;
}
}
.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;
};