diff --git a/app/(admin)/admin/(basic-form)/form-costum/page.tsx b/app/(admin)/admin/(basic-form)/form-costum/page.tsx new file mode 100644 index 0000000..224d54c --- /dev/null +++ b/app/(admin)/admin/(basic-form)/form-costum/page.tsx @@ -0,0 +1,30 @@ +"use client" +import { Image } from "@nextui-org/react"; + +export default function CustumPage() { + return ( +
+
+
+
+ +
+
+

Custum Form

+

custom designed elemnt

+
+
+ NextUI hero Image +
+
+
+
+ {/* */} +
+
+ ); +} diff --git a/app/(admin)/admin/(basic-form)/form-horizontal/page.tsx b/app/(admin)/admin/(basic-form)/form-horizontal/page.tsx new file mode 100644 index 0000000..63b5dc8 --- /dev/null +++ b/app/(admin)/admin/(basic-form)/form-horizontal/page.tsx @@ -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 ( +
+
+
+
+ +
+
+

Horizontal Form

+

Home{" > "} Horizontal Form

+
+
+ NextUI hero Image +
+
+
+
+ +
+
+ ); +} diff --git a/app/(admin)/admin/(basic-form)/form-layout/page.tsx b/app/(admin)/admin/(basic-form)/form-layout/page.tsx new file mode 100644 index 0000000..74c70ca --- /dev/null +++ b/app/(admin)/admin/(basic-form)/form-layout/page.tsx @@ -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 ( +
+
+
+
+
+
+

Form Layout

+

Home{" > "} Form Layout

+
+
+ NextUI hero Image +
+
+
+
+ +
+
+ ); +} diff --git a/app/(admin)/admin/(basic-form)/form-validation/page.tsx b/app/(admin)/admin/(basic-form)/form-validation/page.tsx new file mode 100644 index 0000000..8480b7e --- /dev/null +++ b/app/(admin)/admin/(basic-form)/form-validation/page.tsx @@ -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 ( +
+
+
+
+ +
+
+

Form Validation

+

Home{" > "} Form Validation

+
+
+ NextUI hero Image +
+
+
+
+ +
+
+ ); +} diff --git a/app/(admin)/admin/(basic-form)/form-vertical/page.tsx b/app/(admin)/admin/(basic-form)/form-vertical/page.tsx new file mode 100644 index 0000000..1667561 --- /dev/null +++ b/app/(admin)/admin/(basic-form)/form-vertical/page.tsx @@ -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 ( +
+
+
+
+ +
+
+

Vertical Form

+

Home{" > "} Verical Form

+
+
+ NextUI hero Image +
+
+
+
+ +
+
+ ); +} diff --git a/app/(admin)/admin/(basic-form)/form-wizard/page.tsx b/app/(admin)/admin/(basic-form)/form-wizard/page.tsx new file mode 100644 index 0000000..b096f16 --- /dev/null +++ b/app/(admin)/admin/(basic-form)/form-wizard/page.tsx @@ -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 ( +
+
+
+
+ +
+
+

Form Wizard

+

This is Form WizardPage

+
+
+ NextUI hero Image +
+
+
+
+ +

Form Wizard

+ +
+ +
+ + +
+
+
+ ); +} diff --git a/app/(admin)/admin/article/create/page.tsx b/app/(admin)/admin/article/create/page.tsx new file mode 100644 index 0000000..e0230bd --- /dev/null +++ b/app/(admin)/admin/article/create/page.tsx @@ -0,0 +1,10 @@ +import FormArticle from '@/components/form/form-article' +import { Card } from '@nextui-org/react' + +export default function CreateArticle() { + return ( + + + + ) +} diff --git a/app/(admin)/admin/article/page.tsx b/app/(admin)/admin/article/page.tsx new file mode 100644 index 0000000..f71a4fd --- /dev/null +++ b/app/(admin)/admin/article/page.tsx @@ -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 ( +
+
+ + + + + + + + +
+
+ ); +} diff --git a/app/(admin)/admin/basic/page.tsx b/app/(admin)/admin/basic/page.tsx new file mode 100644 index 0000000..f9d5058 --- /dev/null +++ b/app/(admin)/admin/basic/page.tsx @@ -0,0 +1,39 @@ +"use client" +import { Card, Divider, Image } from "@nextui-org/react"; + +export default function BasicPage() { + return ( +
+
+
+
+
+
+

Basic Table

+

Home{" > "} Basic Table

+
+
+ NextUI hero Image +
+
+
+
+ +

Basic Table

+ +
+ {/* + + + + */} +
+
+
+
+ ); +} diff --git a/app/(admin)/admin/dashboard/page.tsx b/app/(admin)/admin/dashboard/page.tsx new file mode 100644 index 0000000..7f3d529 --- /dev/null +++ b/app/(admin)/admin/dashboard/page.tsx @@ -0,0 +1,11 @@ +import DashboardContainer from "@/components/main/dashboard/dashboard-container"; + +export default function AdminPage() { + return ( +
+
+ +
+
+ ) +} \ No newline at end of file diff --git a/app/(admin)/admin/layout.tsx b/app/(admin)/admin/layout.tsx new file mode 100644 index 0000000..4205ed4 --- /dev/null +++ b/app/(admin)/admin/layout.tsx @@ -0,0 +1,15 @@ +"use client"; + +import { AdminLayout } from "@/components/layout/admin-layout"; + +export default function AdminPageLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/app/(admin)/admin/menu1/submenu1/page.tsx b/app/(admin)/admin/menu1/submenu1/page.tsx new file mode 100644 index 0000000..e87ac7f --- /dev/null +++ b/app/(admin)/admin/menu1/submenu1/page.tsx @@ -0,0 +1,8 @@ +import { ThemeSwitch } from "@/components/theme-switch"; + +export default function Submenu1Page() { + return ( +
Submenu1 +
+ ) +} \ No newline at end of file diff --git a/app/(admin)/admin/menu1/submenu2/page.tsx b/app/(admin)/admin/menu1/submenu2/page.tsx new file mode 100644 index 0000000..648391b --- /dev/null +++ b/app/(admin)/admin/menu1/submenu2/page.tsx @@ -0,0 +1,8 @@ +import { ThemeSwitch } from "@/components/theme-switch"; + +export default function Submenu2Page() { + return ( +
Submenu2 +
+ ) +} \ No newline at end of file diff --git a/app/(admin)/admin/page.tsx b/app/(admin)/admin/page.tsx new file mode 100644 index 0000000..5d41348 --- /dev/null +++ b/app/(admin)/admin/page.tsx @@ -0,0 +1,11 @@ +"use client" + +export default function HomePage() { + return ( +
+
+

Welcome

+
+
+ ); +} diff --git a/app/admin/dashboard/page.tsx b/app/(admin)/dashboard-old/page.tsx similarity index 100% rename from app/admin/dashboard/page.tsx rename to app/(admin)/dashboard-old/page.tsx diff --git a/app/admin/layout.tsx b/app/admin/layout.tsx deleted file mode 100644 index 1909d3a..0000000 --- a/app/admin/layout.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import HumasAdminLayout from "@/components/layout/HumasAdminLayout"; - -export default function HumasLayoutAdmin({ - children, -}: { - children: React.ReactNode; -}) { - return ( - - {children} - - ); -} diff --git a/app/admin/page.tsx b/app/admin/page.tsx deleted file mode 100644 index 0084293..0000000 --- a/app/admin/page.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react' - -export default function AdminHumasPage() { - return ( -
-
1
-
1
- -
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
- ) -} diff --git a/app/layout.tsx b/app/layout.tsx index 9872d6a..d2581cc 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -37,7 +37,7 @@ export default function RootLayout({ )} > -
+
{children}
diff --git a/components/Landing Page/MedolUpdate.tsx b/components/Landing Page/MedolUpdate.tsx index 7f84d9b..af27a03 100644 --- a/components/Landing Page/MedolUpdate.tsx +++ b/components/Landing Page/MedolUpdate.tsx @@ -1,28 +1,55 @@ 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() { - let tabs = [ + + const mediaHubUpdate = [ { - id: "photos", - label: "Photos", - content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." + 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: "music", - label: "Music", - content: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." + 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: "videos", - label: "Videos", - content: "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - } - ]; + 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 (
- Media Online Update + Top 5 News Update
-
- console.log("item pressed")} className='w-[45%] bg-white text-black'> - - tes - - -

02-04-2024 09:31 WITA

- Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan -
-
- console.log("item pressed")} className='w-[45%] bg-white text-black'> - - tes - - -

02-04-2024 09:16 WIB

- Kapolri Tinjau Langsung Kondisi Pelayanan Pemudik di Dermaga 1 Pelabuhan Merak -
-
-
+ + {mediaHubUpdate.map((newsItem) => ( + + + + tes + + +

02-04-2024 09:31 WITA

+ Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan +
+
+
+ ))} +
+ + +
+ ) +} diff --git a/components/icons.tsx b/components/icons.tsx index 99fd9b9..a417d7c 100644 --- a/components/icons.tsx +++ b/components/icons.tsx @@ -770,4 +770,710 @@ export const Checklist = ({ -); \ No newline at end of file +); + +export const ChevronLeftIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const DotsYIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + +); + + +export const DotsXIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + +); + +export const EyeIconMdi = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + + +export const OnlineIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + +); + +export const OfflineIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + + +); + +export const CreateIconIon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + +); + +export const DeleteIcon = ({ + size, + height = 12, + width = 10, + fill = "none", + ...props +}: IconSvgProps) => ( + + + +); + + +export const AccIcon = ({ + size, + height = 12, + width = 10, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + +); + +export const CloseIcon = ({ + size, + height = 12, + width = 10, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + +); + +export const RefundIcon = ({ + size, + height = 12, + width = 10, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + + +); + +export const AddIcon = ({ + size, + height = 12, + width = 12, + fill = "none", + ...props +}: IconSvgProps) => ( + + + +); + +export const CompanyIcon = ({ + size, + height = 12, + width = 12, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + +); + +export const EmailIcon = ({ + size, + height = 12, + width = 12, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + + +); + +export const PhoneIcon = ({ + size, + height = 12, + width = 12, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + +); + +export const MessageIcon = ({ + size, + height = 12, + width = 12, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + + +); + + +export const UserIcon = ({ + size, + height = 12, + width = 12, + fill = "none", + ...props +}: IconSvgProps) => ( + + + + + + +); + +export const EyeOffIconMdi = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const DateIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + +); + +export const WarningIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + +); + +export const PasswordIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + +); + +export const TimeIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + +); + +export const VolumeLowIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + +); + +export const VolumeHighIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + + +); + +export const FormVerticalIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const FormHorizontalIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const FormCustomIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const FormLayoutIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const FormValidationIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const FormWizardIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const FacebookIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + +); + +export const GoogleIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + + + + + + +); diff --git a/components/icons/dashboard-icon.tsx b/components/icons/dashboard-icon.tsx new file mode 100644 index 0000000..0ba10c7 --- /dev/null +++ b/components/icons/dashboard-icon.tsx @@ -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) => ( + + + +); + +export const DashboardBriefcaseIcon = ({ + size, + height = 48, + width = 48, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + +); +export const DashboardMailboxIcon = ({ + size, + height = 48, + width = 48, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + +); +export const DashboardBookmarkIcon = ({ + size, + height = 48, + width = 48, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + + + + +); +export const DashboardSpeecIcon = ({ + size, + height = 48, + width = 48, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + +); + +export const DashboardConnectIcon = ({ + size, + height = 48, + width = 48, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + + + +); + + +export const DashboardTopLeftPointIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + + +export const DashboardRightDownPointIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + +); \ No newline at end of file diff --git a/components/icons/sidebar-icon.tsx b/components/icons/sidebar-icon.tsx new file mode 100644 index 0000000..691ca2c --- /dev/null +++ b/components/icons/sidebar-icon.tsx @@ -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) => ( + + + +); + +export const DashboardIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const HomeIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + +); + +export const Submenu1Icon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + + + + + +); + +export const Submenu2Icon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); + +export const InfoCircleIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + +); + + +export const MinusCircleIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + + + + +); + +export const TableIcon = ({ + size, + height = 24, + width = 22, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + +); \ No newline at end of file diff --git a/components/layout/admin-layout.tsx b/components/layout/admin-layout.tsx new file mode 100644 index 0000000..2b4e2c4 --- /dev/null +++ b/components/layout/admin-layout.tsx @@ -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 ( + +
+ +
+ + {children} +
+
+
+ ); +}; \ No newline at end of file diff --git a/components/main/dashboard/chart/column-chart.tsx b/components/main/dashboard/chart/column-chart.tsx new file mode 100644 index 0000000..e1a9181 --- /dev/null +++ b/components/main/dashboard/chart/column-chart.tsx @@ -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 ( +
+
+ { + 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} /> +
+
+
+ ); + } +} + +export default ApexChartColumn; \ No newline at end of file diff --git a/components/main/dashboard/chart/donut-chart.tsx b/components/main/dashboard/chart/donut-chart.tsx new file mode 100644 index 0000000..921c099 --- /dev/null +++ b/components/main/dashboard/chart/donut-chart.tsx @@ -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 ( +
+
+ +
+
+
+ ); + } +} + +export default ApexChartDonut; \ No newline at end of file diff --git a/components/main/dashboard/chart/line-area-chart.tsx b/components/main/dashboard/chart/line-area-chart.tsx new file mode 100644 index 0000000..7ea3ed9 --- /dev/null +++ b/components/main/dashboard/chart/line-area-chart.tsx @@ -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 ( +
+ +
+ ); + } +} + +export default ApexChartLineArea; \ No newline at end of file diff --git a/components/main/dashboard/dashboard-container.tsx b/components/main/dashboard/dashboard-container.tsx new file mode 100644 index 0000000..0d09829 --- /dev/null +++ b/components/main/dashboard/dashboard-container.tsx @@ -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 ( +
+
+
+
+
+
Employees
+
96
+
+
+
+
Clients
+
3650
+
+
+
+
Projects
+
356
+
+
+
+
Events
+
696
+
+
+
+
Payroll
+
$96k
+
+
+
+
Reports
+
56
+
+
+
+
+
+
Revenue Update + Overview of Profit +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+

$63,489.50

+

Total Earnings

+
+
+
+
+
+

Earning this month

+

$48,820

+
+
+
+
+
+

Expense this month

+

$26,498

+
+
+ +
+
+
+
+
+
+

Yearly Breakup

+
+

$36,358

+
+
+

+9% last year

+
+

+

+
+ 2020 +
+
+
+ 2020 +
+

+ +
+
+
+
+
+
+ Monthly Earning + $ +
+
+

$6,820

+
+
+ +
+

-6% last year

+
+
+
+
+
+
+
bawah
+
+
+ ) +} \ No newline at end of file diff --git a/components/sidebar/sidebar-closed-icon.tsx b/components/sidebar/sidebar-closed-icon.tsx new file mode 100644 index 0000000..b6aa291 --- /dev/null +++ b/components/sidebar/sidebar-closed-icon.tsx @@ -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 ; + case 'menu1': + return ; + case 'table': + return ; + default: + return null; // Tidak ada ikon yang sesuai + } + }; + return ( + + {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()} + + + : + + {renderIcon()} + + } + + ) +} \ No newline at end of file diff --git a/components/sidebar/sidebar-collapse-items.tsx b/components/sidebar/sidebar-collapse-items.tsx new file mode 100644 index 0000000..1d2fd93 --- /dev/null +++ b/components/sidebar/sidebar-collapse-items.tsx @@ -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 ; + case 'menu1': + return ; + case 'table': + return ; + default: + return null; // Tidak ada ikon yang sesuai + } + }; + return ( +
+ + } + 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={ +
+ {icon && {icon}} + {/* {isOpen && {title}} */} + {isOpen && {title}} +
+ + } + > +
+
    {items}
+
+
+
+
+ ); +}; diff --git a/components/sidebar/sidebar-collapse-sub-items.tsx b/components/sidebar/sidebar-collapse-sub-items.tsx new file mode 100644 index 0000000..a9ba224 --- /dev/null +++ b/components/sidebar/sidebar-collapse-sub-items.tsx @@ -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 ; + case 'submenu2': + return ; + default: + return null; // Tidak ada ikon yang sesuai + } + }; + return ( +
  • + + {isOpen ? + +
    + {icon} {isOpen && title} +
    + + : + + +
    + {icon} {isOpen && title} +
    + +
    + + } + +
  • + ); +}; diff --git a/components/sidebar/sidebar-context.tsx b/components/sidebar/sidebar-context.tsx new file mode 100644 index 0000000..a566005 --- /dev/null +++ b/components/sidebar/sidebar-context.tsx @@ -0,0 +1,58 @@ +'use client' +import React, { createContext, useContext, useEffect, useState } from 'react'; + +interface SidebarContextType { + isOpen: boolean; + toggleSidebar: () => void; +} + +const SidebarContext = createContext(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 ( + + {children} + + ); +}; + +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); +}; \ No newline at end of file diff --git a/components/sidebar/sidebar-menu.tsx b/components/sidebar/sidebar-menu.tsx new file mode 100644 index 0000000..b98128e --- /dev/null +++ b/components/sidebar/sidebar-menu.tsx @@ -0,0 +1,15 @@ +import React from "react"; + +interface Props { + title?: string; + children?: React.ReactNode; +} + +export const SidebarMenu = ({ title, children }: Props) => { + return ( +
    + {title} + {children} +
    + ); +}; diff --git a/components/sidebar/sidebar.tsx b/components/sidebar/sidebar.tsx new file mode 100644 index 0000000..d3f5974 --- /dev/null +++ b/components/sidebar/sidebar.tsx @@ -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: , + 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: , + 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: , + 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: , + 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: , + 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: , + 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: , + 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: , + 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: , + // 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: , + // position: 1, + // statusId: 1, + // statusName: "Active", + // childMenu: [ + // { + // id: 3, + // name: "SubMenu 1", + // moduleId: 653, + // moduleName: "SubMenu 1", + // modulePathUrl: "/admin/menu1/submenu1", + // parentId: 702, + // icon: , + // 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: , + // position: 2, + // statusId: 1, + // statusName: "Active", + // childMenu: [], + // childModule: null, + // } + // ], + // childModule: null, + // }, +] + +const Sidebar: React.FC = ({ updateSidebarData }) => { + const pathname = usePathname(); + const [sidebarMenu, setSidebarMenu] = useState(); + const { isOpen, toggleSidebar } = useSidebar(); + + const closeSidebar = () => { + if (isOpen) { + toggleSidebar(); + } + }; + + useEffect(() => { + updateSidebarData(isOpen) + }, [isOpen]) + + const renderIcon = (icon: string) => { + switch (icon) { + case 'dashboard': + return ; + case 'menu1': + return ; + case 'table': + return ; + default: + return null; + } + }; + + return ( +
    +
    + + {!isOpen && +
    + +
    + } +
    +
    + + {isOpen && ACME} +
    + {isOpen && + + } +
    +
    +
    + + + + + + +

    Signed in as

    +

    @tonyreichert

    +
    + Profile Settings + + Analytics + + + Help & Feedback + + + Log Out + +
    +
    +
    +
    + + {sideBarDummyData + ? sideBarDummyData?.map((list: any, index: number) => ( + list.isGroup ? +

    {isOpen ? list.name : "..."}

    + : + list.childMenu?.length < 1 ? + <> + {isOpen ? + +
    + {list.icon} {isOpen && list.name} +
    + : + + +
    + {list.icon} {isOpen && list.name} +
    + +
    + } + + : + ( + + )), + ]} + /> + )) + : ""} +
    +
    +
    +
    + + {isOpen && "Theme"} +
    + {isOpen ? + + + {isOpen && "Support"} + + : + + + + {isOpen && "Support"} + + + } + {isOpen ? + + + {isOpen && "Log Out"} + + : + + + + {isOpen && "Log Out"} + + + + } + +
    +
    +
    + + {/*
    +
    + +
    + {sideBarDummyData.map((list) => ( +
    + +
    + ))} + +
    + {isOpen && ( +
    + )} */} +
    + ); +}; + +export default Sidebar; \ No newline at end of file diff --git a/components/table/article-table.tsx b/components/table/article-table.tsx new file mode 100644 index 0000000..7248b24 --- /dev/null +++ b/components/table/article-table.tsx @@ -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([]); + + 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 = { + active: "primary", + cancel: "danger", + pending: "success", + }; + + switch (columnKey) { + case "no": + return ( +
    {article.id}
    + ) + + case "status": + return ( + +
    + {cellValue} +
    +
    + ); + + case "actions": + return ( +
    + + + + + + + + + + Detail + + + + + + + + Edit + + + + + + + + Delete + + + + + + +
    + ); + + default: + return cellValue; + } + }, []); + + return ( + <> + +
    +
    + + + {(column) => ( + {column.name} + )} + + } + > + {(item) => ( + + {(columnKey) => ( + {renderCell(item, columnKey)} + )} + + )} + +
    +
    +
    + + + ); +} diff --git a/components/table/users-table.tsx b/components/table/users-table.tsx new file mode 100644 index 0000000..fd1055c --- /dev/null +++ b/components/table/users-table.tsx @@ -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 = { + Active: "success", + Cancel: "danger", + Pending: "warning", + Completed: "primary" + }; + + switch (columnKey) { + case "no": + return ( +
    {basic.id}
    + ) + + case "user": + return ( + + {basic.description} + + ) + + case "team": + return ( +
    {cellValue}
    + ) + + case "status": + return ( + +
    + {cellValue} +
    +
    + ); + + case "budget": + return ( +
    +

    {cellValue}

    +
    + ); + + default: + return cellValue; + } + }, []); + + return ( + <> + +
    +
    + + + {(column) => ( + {column.name} + )} + + + {(item) => ( + + {(columnKey) => ( + {renderCell(item, columnKey)} + )} + + )} + +
    +
    +
    + + + ); +} diff --git a/components/ui/breadcrumb.tsx b/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..b277ff9 --- /dev/null +++ b/components/ui/breadcrumb.tsx @@ -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(""); + 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 ( +
    +
    +
    +
    +

    {pathnameTransformed[pathnameTransformed.length - 1]}

    + handleAction(key)}> + {pathnameTransformed?.map((item, index) => ( + + {item} + + ))} + +
    +
    + +
    +
    +
    +
    + ); +}; diff --git a/config/swal.ts b/config/swal.ts new file mode 100644 index 0000000..47faf4e --- /dev/null +++ b/config/swal.ts @@ -0,0 +1,95 @@ +import Swal from "sweetalert2"; +import withReactContent from "sweetalert2-react-content"; +import { useRouter } from "next/navigation"; + +const MySwal = withReactContent(Swal); + +const Toast = MySwal.mixin({ + toast: true, + position: "top-end", + showConfirmButton: false, + timer: 3000, + timerProgressBar: true, + didOpen: (toast) => { + toast.addEventListener("mouseenter", Swal.stopTimer); + toast.addEventListener("mouseleave", Swal.resumeTimer); + }, +}); + +export function loading(msg?: any) { + let timerInterval: any; + MySwal.fire({ + title: msg || "Loading...", + allowOutsideClick: false, + timerProgressBar: true, + didOpen: () => { + MySwal.showLoading(); + timerInterval = setInterval(() => { }, 100); + }, + willClose: () => { + clearInterval(timerInterval); + }, + }); +} + +export function error(msg?: any) { + MySwal.fire({ + icon: "error", + title: "Failed...", + text: msg || "Unknown Error", + }); +} + +export function successRouter(redirect: string, router?: any) { + MySwal.fire({ + title: "Success!", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "Ok", + allowOutsideClick: false, + }).then((result) => { + if (result.isConfirmed) { + router.push(redirect); + } + }); +} + +export function success(title: string) { + MySwal.fire({ + title: title || "Success!", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + return true; + } + }); +} + +export function close() { + MySwal.close(); +} + +export function warning(text: string, redirect: string, router?: any) { + MySwal.fire({ + title: text, + icon: "warning", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + router.push(redirect); + } + }); +} + +export function successToast(title: string, text: string) { + Toast.fire({ + icon: "success", + title: title, + text: text, + }); +} + + diff --git a/package-lock.json b/package-lock.json index 24cd358..495b9cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,22 +27,29 @@ "@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", "eslint": "8.48.0", "eslint-config-next": "14.0.2", "framer-motion": "^10.18.0", "intl-messageformat": "^10.5.0", + "jodit-react": "^4.0.25", "next": "14.0.2", "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", "tailwindcss": "3.3.5", @@ -2954,6 +2961,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", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", @@ -3027,6 +3039,20 @@ "node": ">= 8" } }, + "node_modules/apexcharts": { + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.48.0.tgz", + "integrity": "sha512-Lhpj1Ij6lKlrUke8gf+P+SE6uGUn+Pe1TnCJ+zqrY0YMvbqM3LMb1lY+eybbTczUyk0RmMZomlTa2NgX2EUs4Q==", + "dependencies": { + "@yr/monotone-cubic-spline": "^1.0.3", + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -3180,6 +3206,20 @@ "has-symbols": "^1.0.3" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/autobind-decorator": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/autobind-decorator/-/autobind-decorator-2.4.0.tgz", + "integrity": "sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw==", + "engines": { + "node": ">=8.10", + "npm": ">=6.4.1" + } + }, "node_modules/autoprefixer": { "version": "10.4.16", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", @@ -3235,6 +3275,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -3478,6 +3528,17 @@ "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz", "integrity": "sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -3609,6 +3670,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -4302,6 +4371,25 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -4310,6 +4398,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -5033,6 +5134,26 @@ "jiti": "bin/jiti.js" } }, + "node_modules/jodit": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/jodit/-/jodit-4.1.16.tgz", + "integrity": "sha512-rqBGuYkmaU4cJrmid2vtdBFMA0eCFp6S7qhP2aNf92wBiLYmo+UnvyW08lH+CcZ2ZoWtVjEiqzGMvj8kZ0zsKA==", + "dependencies": { + "autobind-decorator": "^2.4.0" + } + }, + "node_modules/jodit-react": { + "version": "4.0.25", + "resolved": "https://registry.npmjs.org/jodit-react/-/jodit-react-4.0.25.tgz", + "integrity": "sha512-HFbbpabQlE3UdD5mOVm/ZHCRVMtNHCy5oZi4mWquM1W6uNrQG5sO7GuIYTxmW84qfTpuKPWjyw2q1ov/YFW8ug==", + "dependencies": { + "jodit": "^4.1.16" + }, + "peerDependencies": { + "react": "~0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "~0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5233,6 +5354,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5764,6 +5904,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5802,6 +5947,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.1.0", "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.1.0.tgz", @@ -5947,6 +6104,18 @@ } } }, + "node_modules/react-sweetalert2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/react-sweetalert2/-/react-sweetalert2-0.6.0.tgz", + "integrity": "sha512-4MEWGAJamSfoj56m7MUs7IfBnev9wJYs0RayvoHvxshSQeH62iK0N/EkDiHr3VuZ3vTy34kOpzL1Yg3b3VYF8w==", + "dependencies": { + "sweetalert2": "^11.7.5" + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, "node_modules/react-tailwindcss-datepicker": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/react-tailwindcss-datepicker/-/react-tailwindcss-datepicker-1.6.6.tgz", @@ -6449,6 +6618,108 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "dependencies": { + "svg.js": "^2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==", + "dependencies": { + "svg.js": ">=2.3.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "node_modules/svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "dependencies": { + "svg.js": "^2.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "dependencies": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js/node_modules/svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "dependencies": { + "svg.js": "^2.6.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/sweetalert2": { + "version": "11.10.8", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.8.tgz", + "integrity": "sha512-oAkYROBfXBY+4sVbQEIcN+ZxAx69lsmz5WEBwdEpyS4m59vOBNlRU5/fJpAI1MVfiDwFZiGwVzB/KBpOyfLNtg==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, + "node_modules/sweetalert2-react-content": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/sweetalert2-react-content/-/sweetalert2-react-content-5.0.7.tgz", + "integrity": "sha512-8Fk82Mpk45lFXpJWKIFF/lq8k/dJKDDQGFcuqVosaL/qRdViyAs5+u37LoTGfnOIvf+rfQB3PAXcp1XLLn+0ew==", + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "sweetalert2": "^11.0.0" + } + }, "node_modules/swiper": { "version": "11.0.6", "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.0.6.tgz", diff --git a/package.json b/package.json index c024a50..2cc4592 100644 --- a/package.json +++ b/package.json @@ -28,22 +28,29 @@ "@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", "eslint": "8.48.0", "eslint-config-next": "14.0.2", "framer-motion": "^10.18.0", "intl-messageformat": "^10.5.0", + "jodit-react": "^4.0.25", "next": "14.0.2", "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", "tailwindcss": "3.3.5", diff --git a/service/article.ts b/service/article.ts index 5a2f632..57c8ade 100644 --- a/service/article.ts +++ b/service/article.ts @@ -1,8 +1,13 @@ -import { httpGet } from "./http-config/axios-base-service"; +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); } \ No newline at end of file diff --git a/service/http-config/axios-base-service.ts b/service/http-config/axios-base-service.ts index b9e2163..4d26451 100644 --- a/service/http-config/axios-base-service.ts +++ b/service/http-config/axios-base-service.ts @@ -3,7 +3,7 @@ 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) { + .catch(function (error: any) { console.log(error); return error.response; }); @@ -26,7 +26,7 @@ export async function httpPost(pathUrl: any, headers: any, data?: any) { export async function httpGet(pathUrl: any, headers: any) { const response = await axiosBaseInstance .get(pathUrl, { headers }) - .catch(function (error) { + .catch(function (error: any) { console.log(error); return error.response; }); diff --git a/styles/globals.css b/styles/globals.css index 2d72638..62aae12 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -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; -} \ No newline at end of file +} + +.hidden-tooltip { + display: none; +} + +.sidebar-scrollbar { + --scroll-shadow-size: 40px; +} diff --git a/types/globals.tsx b/types/globals.tsx new file mode 100644 index 0000000..2408a4e --- /dev/null +++ b/types/globals.tsx @@ -0,0 +1,26 @@ +import { SVGProps } from "react"; + +export type IconSvgProps = SVGProps & { + 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; +};