feat:login button, auth, fix:admin - article page

This commit is contained in:
Rama Priyanto 2024-11-08 16:01:21 +07:00
parent e7482b346d
commit d18bbfe568
12 changed files with 736 additions and 900 deletions

View File

@ -1,15 +1,103 @@
"use client"; "use client";
import { Input } from "@nextui-org/input"; import { Input } from "@nextui-org/input";
import React from "react"; import React, { useState } from "react";
import { EyeFilledIcon, EyeSlashFilledIcon } from "../icons"; import { EyeFilledIcon, EyeSlashFilledIcon } from "../icons";
import { Button } from "@nextui-org/button"; import { Button } from "@nextui-org/button";
import Link from "next/link"; import Link from "next/link";
import Cookies from "js-cookie";
import { close, error, loading } from "@/config/swal";
import { getProfile, postSignIn } from "@/service/master-user";
import { useRouter } from "next/navigation";
export default function Login() { export default function Login() {
const router = useRouter();
const [isVisible, setIsVisible] = React.useState(false); const [isVisible, setIsVisible] = React.useState(false);
const toggleVisibility = () => setIsVisible(!isVisible); const toggleVisibility = () => setIsVisible(!isVisible);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const onSubmit = async () => {
const data = {
username: username,
password: password,
};
if (!username || !password) {
error("Username & Password Wajib Diisi !");
} else {
loading();
const response = await postSignIn(data);
if (response?.error) {
error("Username / Password Tidak Sesuai");
} else {
const access_token: any = response?.data?.data?.id_token;
const refresh_token: any = response?.data?.data?.refresh_token;
const dateTime: any = new Date();
const newTime: any = dateTime.getTime() + 10 * 60 * 1000;
Cookies.set("access_token", access_token, {
expires: 1,
});
Cookies.set("refresh_token", refresh_token, {
expires: 1,
});
Cookies.set("time_refresh", newTime, {
expires: 1,
});
Cookies.set("is_first_login", "true", {
secure: true,
sameSite: "strict",
});
const profile = await getProfile();
console.log("PROFILE : ", profile?.data);
Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, {
expires: 1,
});
Cookies.set("uie", profile?.data?.data?.id, {
expires: 1,
});
Cookies.set("ufne", profile?.data?.data?.fullname, {
expires: 1,
});
Cookies.set("username", profile?.data?.data?.username, {
expires: 1,
});
Cookies.set("urie", profile?.data?.data?.roleId, {
expires: 1,
});
Cookies.set("roleName", profile?.data?.data?.roleName, {
expires: 1,
});
Cookies.set("masterPoldaId", profile?.data?.data?.masterPoldaId, {
expires: 1,
});
Cookies.set("ulne", profile?.data?.data?.roleLevelNumber, {
expires: 1,
});
Cookies.set("urce", profile?.data?.data?.roleCode, {
expires: 1,
});
Cookies.set("email", profile?.data?.data?.email, {
expires: 1,
});
close();
router.push("/admin/dashboard");
Cookies.set("status", "login", {
expires: 1,
});
}
}
// }
};
const setValUsername = (e: any) => {
const uname = e.replaceAll(/[^\w.-]/g, "");
setUsername(uname.toLowerCase());
};
return ( return (
<div className="bg-white text-black md:flex px-0 md:px-2 lg:px-5"> <div className="bg-white text-black md:flex px-0 md:px-2 lg:px-5">
<div className="w-auto md:w-1/2 p-2 md:p-5 lg:p-10 space-y-5"> <div className="w-auto md:w-1/2 p-2 md:p-5 lg:p-10 space-y-5">
@ -39,6 +127,15 @@ export default function Login() {
label="Username" label="Username"
placeholder="Masukkan username anda!" placeholder="Masukkan username anda!"
variant="underlined" variant="underlined"
onChange={(e: any) => {
setValUsername(e.target.value.trim());
}}
onPaste={(e: any) => {
setValUsername(e.target.value.trim());
}}
onCopy={(e: any) => {
setValUsername(e.target.value.trim());
}}
/> />
</div> </div>
<div> <div>
@ -77,50 +174,15 @@ export default function Login() {
label="Password" label="Password"
placeholder="Masukkan password anda" placeholder="Masukkan password anda"
variant="underlined" variant="underlined"
onChange={(event) => setPassword(event.target.value)}
/> />
</div> </div>
<div>
<Input
classNames={{
input: ["w-full", "bg-transparent", "!text-black"],
mainWrapper: ["w-full", "bg-transparent"],
innerWrapper: ["bg-transparent"],
label: ["!text-black", "font-semibold"],
inputWrapper: [
"bg-transparent",
"dark:bg-transparent",
"hover:bg-transparent",
"dark:hover:bg-transparent",
"group-data-[focused=true]:bg-transparent",
"dark:group-data-[focused=true]:bg-transaparent",
"group-data-[focused=false]:bg-transparent",
"focus-within:!bg-transparent",
],
}}
isRequired
endContent={
<button
className="focus:outline-none"
type="button"
onClick={toggleVisibility}
>
{isVisible ? (
<EyeSlashFilledIcon className="text-2xl text-default-400 pointer-events-none" />
) : (
<EyeFilledIcon className="text-2xl text-default-400 pointer-events-none" />
)}
</button>
}
type={isVisible ? "text" : "password"}
label="Konfirmasi Password"
placeholder="Masukkan password anda"
variant="underlined"
/>
</div>
<div> <div>
<Button <Button
size="lg" size="lg"
className="w-full bg-[#DD8306] rounded-md font-semibold" className="w-full bg-[#DD8306] rounded-md font-semibold"
onPress={onSubmit}
> >
Login Login
</Button> </Button>

View File

@ -14,7 +14,9 @@ export default function ENewsPolri() {
useEffect(() => { useEffect(() => {
async function getArticle() { async function getArticle() {
const response = await getListArticle(); const req = { page: 1, search: "", limit: "10" };
const response = await getListArticle(req);
console.log("res", response?.data?.data); console.log("res", response?.data?.data);
setArticle(response?.data?.data); setArticle(response?.data?.data);
} }

View File

@ -17,7 +17,8 @@ export default function HeaderNews() {
useEffect(() => { useEffect(() => {
async function getArticle() { async function getArticle() {
const response = await getListArticle(); const req = { page: 1, search: "", limit: "10" };
const response = await getListArticle(req);
console.log("res", response?.data?.data); console.log("res", response?.data?.data);
setArticle(response?.data?.data); setArticle(response?.data?.data);
} }

View File

@ -363,6 +363,9 @@ export default function NavbarHumas() {
<div> <div>
<ThemeSwitch /> <ThemeSwitch />
</div> </div>
<Link href="/auth">
<Button className="bg-[#DD8306]">Login</Button>
</Link>
</div> </div>
</div> </div>
</div> </div>
@ -375,24 +378,30 @@ export default function NavbarHumas() {
{siteConfig.humasMenuItems.map((item) => ( {siteConfig.humasMenuItems.map((item) => (
<div key={item.key} className="relative"> <div key={item.key} className="relative">
<NavbarMenuItem> <NavbarMenuItem>
<div {item.key === "login" ? (
onClick={() => toggleDropdown(item.key)} <Link href="/auth" className="my-3">
className="flex items-end gap-2" <Button className="bg-[#DD8306]">Login</Button>
> </Link>
{item.href ? ( ) : (
<Link href={item.href} target="_blank"> <div
<span>{item.label}</span> onClick={() => toggleDropdown(item.key)}
</Link> className="flex items-end gap-2"
) : ( >
<span>{item.label}</span> {item.href ? (
)} <Link href={item.href} target="_blank">
{item.submenu && <span>{item.label}</span>
(dropdownOpen[item.key] ? ( </Link>
<ChevronUpIcon />
) : ( ) : (
<ChevronDownIcon /> <span>{item.label}</span>
))} )}
</div> {item.submenu &&
(dropdownOpen[item.key] ? (
<ChevronUpIcon />
) : (
<ChevronDownIcon />
))}
</div>
)}
</NavbarMenuItem> </NavbarMenuItem>
{dropdownOpen[item.key] && item.submenu && ( {dropdownOpen[item.key] && item.submenu && (
<div className="pl-2"> <div className="pl-2">
@ -410,219 +419,5 @@ export default function NavbarHumas() {
</NavbarContent> </NavbarContent>
</div> </div>
</Navbar> </Navbar>
// <Navbar
// shouldHideOnScroll
// position='static'
// maxWidth='full' isBlurred={true} className='h-28 md:h-36 dark:bg-[#1F1A17]'>
// <div className='w-1/12 min-w-max'>
// <img src="/logohumas.png" alt="" />
// </div>
// <div className='w-11/12 lg:w-8/12 font-semibold hidden md:block '>
// <div className='flex justify-around items-center'>
// <Link href={'/'}>
// <div>Beranda</div>
// </Link>
// <div>
// <Dropdown className=' dark:bg-[#1F1A17]'>
// <NavbarItem>
// <DropdownTrigger>
// <Button
// disableRipple
// className="p-0 bg-transparent data-[hover=true]:bg-transparent text-medium font font-semibold"
// radius="sm"
// variant="light"
// endContent={<ChevronDownIcon className="pt-1" />}
// >
// Tentang
// </Button>
// </DropdownTrigger>
// </NavbarItem>
// <DropdownMenu
// // aria-label="tentang"
// // title='Tentang'
// className="pt-4"
// classNames={{
// // base: "flex",
// // list: "border-2 gap-2 flex flex-row flex-wrap"
// list: "gap-2 flex flex-row flex-wrap"
// }}
// itemClasses={{
// // base: "border border-red-700 w-[350px]"
// base: "w-[350px]"
// }}
// >
// <DropdownItem
// endContent={<ChevronRightWhite />}
// >
// <Link href='/tentang-humas-polri'>
// Tentang Humas POLRI
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}
// >
// <Link href='/profile-pimpinan-polri'>
// Profile Pimpinan POLRI
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='/struktur-organisasi'>
// Struktur Organisasi
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='/visi-misi'>
// Visi & Misi
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='/tugas-dan-fungsi'>
// Tugas & Fungsi
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// Logo
// </DropdownItem>
// </DropdownMenu>
// </Dropdown>
// </div>
// <div><Link href="/portal-ppid">Portal PPID</Link></div>
// <div>
// <Dropdown className='dark:bg-[#1F1A17]'>
// <NavbarItem>
// <DropdownTrigger>
// <Button
// disableRipple
// className="p-0 bg-transparent data-[hover=true]:bg-transparent text-medium font font-semibold"
// radius="sm"
// variant="light"
// endContent={<ChevronDownIcon className="pt-1" />}
// >
// Pelayanan Masyarakat
// </Button>
// </DropdownTrigger>
// </NavbarItem>
// <DropdownMenu
// aria-label="pelayanan-masyarakat"
// title='pelayanan-masyarakat'
// className="pt-4"
// classNames={{
// list: "gap-2 flex flex-row flex-wrap"
// }}
// itemClasses={{
// base: "w-[350px]"
// }}
// >
// <DropdownItem
// endContent={<ChevronRightWhite />}
// >
// <Link href={'/form-permohonan-informasi'}>
// Formulir Permohonan Informasi
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}
// >
// <Link href='https://www.digitalkorlantas.id/sim/' target="_blank">
// Pelayanan SIM
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='https://erikkes.id/' target="_blank">
// Pelayanan e-Rikkes SIM
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='https://eppsi.id/' target="_blank">
// Pelayanan Test Psikologi SIM
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href="https://e-avis.korlantas.polri.go.id/" target='_blank'>
// Pelayanan e-Arvis
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href="https://samsatdigital.id/" target='_blank'>
// Pelayanan Samsat Digital
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi&hl=en_US' target='_blank'>
// Pelayanan SKCK
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam' target='_blank'>
// Pelayanan Propam Presisi
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='https://dumaspresisi.polri.go.id/' target='_blank'>
// Pelayanan Dumas Presisi
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='https://bos.polri.go.id/login' target='_blank'>
// Pelayanan Binmas
// </Link>
// </DropdownItem>
// <DropdownItem
// endContent={<ChevronRightWhite />}>
// <Link href='https://play.google.com/store/apps/details?id=id.go.ssdmpolri.pengaduanappsbarupolri2' target='_blank'>
// Whistle Blower System
// </Link>
// </DropdownItem>
// </DropdownMenu>
// </Dropdown>
// </div>
// <div>
// <Link href={'/kontak-kami'}>Kontak</Link></div>
// <div><ThemeSwitch /></div>
// </div>
// </div>
// <div className='w-3/12 hidden lg:block'>
// <div className='flex items-center justify-between'>
// <div className="flex gap-1 lg:gap-3 items-center">
// <Link href='https://www.facebook.com/DivHumasPolri' target='_blank'>
// <FbIcon />
// </Link>
// <Link href='https://www.instagram.com/divisihumaspolri/' target='_blank'>
// <IgIcon />
// </Link>
// <Link href='https://www.youtube.com/user/pidhumaspolri' target='_blank'>
// <YtIcon />
// </Link>
// <Link href='https://twitter.com/DivHumas_Polri' target='_blank'>
// <TwIcon />
// </Link>
// <Link href='https://www.tiktok.com/@divhumas_polri' target='_blank'>
// <TtIcon />
// </Link>
// </div>
// <div className=''><IdnIcon /></div>
// </div>
// <div className='pb-10 pt-3'>
// {searchInput}
// </div>
// </div>
// <NavbarContent className="sm:hidden basis-1 pl-4" justify="end">
// <ThemeSwitch />
// <NavbarMenuToggle />
// </NavbarContent>
// </Navbar>
); );
} }

View File

@ -1,7 +1,7 @@
import { SidebarMenuTask } from "@/types/globals"; import { SidebarMenuTask } from "@/types/globals";
import { Tooltip } from "@nextui-org/react"; import { Tooltip } from "@nextui-org/react";
import Link from "next/link"; import Link from "next/link";
import { usePathname } from "next/navigation"; import { usePathname, useRouter } from "next/navigation";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { import {
ChevronLeftIcon, ChevronLeftIcon,
@ -24,6 +24,8 @@ import { SidebarCollapseItems } from "./sidebar-collapse-items";
import { SidebarCollapseSubItems } from "./sidebar-collapse-sub-items"; import { SidebarCollapseSubItems } from "./sidebar-collapse-sub-items";
import { useSidebar } from "./sidebar-context"; import { useSidebar } from "./sidebar-context";
import { SidebarMenu } from "./sidebar-menu"; import { SidebarMenu } from "./sidebar-menu";
import Image from "next/image";
import Cookies from "js-cookie";
interface SubMenuItems { interface SubMenuItems {
id: number; id: number;
@ -176,20 +178,7 @@ const sideBarDummyData = [
statusName: "Active", statusName: "Active",
childModule: null, childModule: null,
}, },
// {
// id: 9,
// name: "Master User Level",
// moduleId: 655,
// moduleName: "Form User Level",
// modulePathUrl: "/admin/master-user-level",
// parentId: -1,
// icon: <FormLayoutIcon />,
// position: 1,
// statusId: 1,
// childMenu: [],
// statusName: "Active",
// childModule: null,
// },
{ {
id: 10, id: 10,
name: "Master User Role", name: "Master User Role",
@ -204,108 +193,32 @@ const sideBarDummyData = [
statusName: "Active", statusName: "Active",
childModule: null, 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 Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
const pathname = usePathname(); const pathname = usePathname();
const router = useRouter();
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>(); const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
const { isOpen, toggleSidebar } = useSidebar(); const { isOpen, toggleSidebar } = useSidebar();
const token = Cookies.get("access_token");
const closeSidebar = () => { useEffect(() => {
if (isOpen) { if (!token) {
toggleSidebar(); onLogout();
} }
}, [token]);
const onLogout = () => {
Object.keys(Cookies.get()).forEach((cookieName) => {
Cookies.remove(cookieName);
});
router.push("/auth");
}; };
useEffect(() => { useEffect(() => {
updateSidebarData(isOpen); updateSidebarData(isOpen);
}, [isOpen]); }, [isOpen]);
const renderIcon = (icon: string) => {
switch (icon) {
case "dashboard":
return <DashboardIcon />;
case "menu1":
return <HomeIcon />;
case "table":
return <TableIcon />;
default:
return null;
}
};
return ( return (
<div className={`flex h-full ${isOpen ? "min-w-[290px]" : "min-w-[80px]"}`}> <div className={`flex h-full ${isOpen ? "min-w-[290px]" : "min-w-[80px]"}`}>
<div <div
@ -383,6 +296,7 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
? sideBarDummyData?.map((list: any, index: number) => ? sideBarDummyData?.map((list: any, index: number) =>
list.isGroup ? ( list.isGroup ? (
<p <p
key={list}
className={`font-bold mr-4 ${!isOpen ? "text-center" : ""}`} className={`font-bold mr-4 ${!isOpen ? "text-center" : ""}`}
> >
{isOpen ? list.name : "..."} {isOpen ? list.name : "..."}
@ -460,17 +374,26 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
{isOpen && "Theme"} {isOpen && "Theme"}
</div> </div>
{isOpen ? ( {isOpen ? (
<a <div className="flex flex-row gap-3">
className={`cursor-pointer flex flex-row ${ <Image
isOpen ? "justify-start" : "justify-center" src="/pengaduan.png"
} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`} width={72}
> height={72}
<InfoCircleIcon size={24} /> alt="profile"
{isOpen && "Support"} />
</a> <div className="flex flex-col">
<a className="cursor-pointer">Nama User</a>
<a
className="hover:text-red-600 underline text-sm cursor-pointer"
onClick={() => onLogout()}
>
Logout
</a>
</div>
</div>
) : ( ) : (
<Tooltip <Tooltip
content="Support" content="Profile"
delay={0} delay={0}
closeDelay={0} closeDelay={0}
placement="right" placement="right"
@ -479,65 +402,20 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
className={`cursor-pointer flex flex-row ${ className={`cursor-pointer flex flex-row ${
isOpen ? "justify-start" : "justify-center" 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`} } gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}
onClick={toggleSidebar}
> >
<InfoCircleIcon size={24} /> <Image
{isOpen && "Support"} src="/pengaduan.png"
</a> width={48}
</Tooltip> height={48}
)} alt="profile"
{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> </a>
</Tooltip> </Tooltip>
)} )}
</div> </div>
</div> </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> </div>
); );
}; };

View File

@ -1,290 +1,337 @@
"use client"; "use client";
import { import {
CreateIconIon, CreateIconIon,
DeleteIcon, DeleteIcon,
DotsYIcon, DotsYIcon,
EyeIconMdi EyeIconMdi,
SearchIcon,
} from "@/components/icons"; } from "@/components/icons";
import { error, success, } from "@/config/swal"; import { error, success } from "@/config/swal";
import { deleteArticle, getListArticle } from "@/service/article"; import { deleteArticle, getListArticle } from "@/service/article";
import { Article } from "@/types/globals"; import { Article } from "@/types/globals";
import { Button } from "@nextui-org/button"; import { Button } from "@nextui-org/button";
import { import {
Chip, Chip,
ChipProps, ChipProps,
Dropdown, Dropdown,
DropdownItem, DropdownItem,
DropdownMenu, DropdownMenu,
DropdownTrigger, DropdownTrigger,
Spinner, Input,
Table, Pagination,
TableBody, Select,
TableCell, SelectItem,
TableColumn, Spinner,
TableHeader, Table,
TableRow TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
} from "@nextui-org/react"; } from "@nextui-org/react";
import Link from "next/link"; import Link from "next/link";
import { Key, useCallback, useEffect, useState } from "react"; import { Key, useCallback, useEffect, useState } from "react";
import Datepicker from "react-tailwindcss-datepicker";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
type UserObject = { const columns = [
id: number; { name: "No", uid: "no" },
user: string; { name: "Judul", uid: "title" },
status: string; { name: "Kategori", uid: "categoryName" },
projectName: string; { name: "Tanggal Unggah", uid: "createdAt" },
avatar: string; { name: "Kreator", uid: "createdByName" },
};
const statusColorMap = { { name: "Aksi", uid: "actions" },
active: "success", ];
paused: "danger",
vacation: "warning",
};
type ArticleData = Article & {
no: number;
};
export default function ArticleTable() { export default function ArticleTable() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const [article, setArticle] = useState<Article[]>([]); const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1);
const [article, setArticle] = useState<ArticleData[]>([]);
const [showData, setShowData] = useState("10");
const [search, setSearch] = useState("");
const [startDateValue, setStartDateValue] = useState({
startDate: null,
endDate: null,
});
useEffect(() => { useEffect(() => {
async function initState() { initState();
const res = await getListArticle(); }, [page, showData, startDateValue]);
setArticle(res.data?.data);
console.log("List Article", res.data.data); async function initState() {
} const startDate: string = `${startDateValue.startDate}`;
initState(); const req = { limit: showData, page: page, search: search };
}, []); const res = await getListArticle(req);
type TableRow = (typeof usersTable)[0]; getTableNumber(parseInt(showData), res.data?.data);
console.log("res.data?.data", res.data);
setTotalPage(res?.data?.meta?.totalPage);
}
const columns = [ const getTableNumber = (limit: number, data: Article[]) => {
if (data) {
{ name: "No", uid: "no" }, const startIndex = limit * (page - 1);
{ name: "Judul", uid: "title" }, let iterate = 0;
{ name: "Kategori", uid: "categoryName" }, const newData = data.map((value: any) => {
{ name: "Tanggal Unggah", uid: "createdAt" }, iterate++;
{ name: "Kreator", uid: "createdByName" }, value.no = startIndex + iterate;
// { name: "Sumber", uid: "source" }, return value;
// { name: "Users", uid: "users" }, });
// { name: "Status", uid: "status" }, console.log("daata", data);
{ name: "Aksi", uid: "actions" }, setArticle(newData);
];
async function doDelete(id: any) {
// loading();
const resDelete = await deleteArticle(id);
if (resDelete?.error) {
error(resDelete.message);
return false;
}
close();
success("Success Deleted");
} }
};
const handleDelete = (id: any) => { async function doDelete(id: any) {
MySwal.fire({ // loading();
title: "Hapus Data", const resDelete = await deleteArticle(id);
icon: "warning",
showCancelButton: true, if (resDelete?.error) {
cancelButtonColor: "#3085d6", error(resDelete.message);
confirmButtonColor: "#d33", return false;
confirmButtonText: "Hapus", }
}).then((result) => { close();
if (result.isConfirmed) { success("Success Deleted");
doDelete(id); }
}
}); const handleDelete = (id: any) => {
MySwal.fire({
title: "Hapus Data",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#3085d6",
confirmButtonColor: "#d33",
confirmButtonText: "Hapus",
}).then((result) => {
if (result.isConfirmed) {
doDelete(id);
}
});
};
function successSubmit() {
MySwal.fire({
title: "Sukses",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then((result) => {
if (result.isConfirmed) {
// initStete();
}
});
}
const renderCell = useCallback((article: ArticleData, columnKey: Key) => {
const cellValue = article[columnKey as keyof ArticleData];
const statusColorMap: Record<string, ChipProps["color"]> = {
active: "primary",
cancel: "danger",
pending: "success",
}; };
function successSubmit() { switch (columnKey) {
MySwal.fire({ case "status":
title: "Sukses", return (
icon: "success", <Chip
confirmButtonColor: "#3085d6", className="capitalize "
confirmButtonText: "OK", color={statusColorMap[article.status]}
}).then((result) => { size="lg"
if (result.isConfirmed) { variant="flat"
// initStete(); >
} <div className="flex flex-row items-center gap-2 justify-center">
}); {cellValue}
}
// 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={`/admin/article/detail/${article.id}`}
>
<EyeIconMdi className="inline mr-2 mb-1" />
Detail
</Link>
</DropdownItem>
<DropdownItem
>
<Link
href={`/admin/article/edit/${article.id}`}
>
<CreateIconIon className="inline mr-2 mb-1" />
Edit
</Link>
</DropdownItem>
<DropdownItem
onClick={() => handleDelete(article.id)}
>
<DeleteIcon
color="red"
width={20}
height={16}
className="inline mr-2 mb-1"
/>
Delete
</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> </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={`/admin/article/detail/${article.id}`}>
<EyeIconMdi className="inline mr-2 mb-1" />
Detail
</Link>
</DropdownItem>
<DropdownItem>
<Link href={`/admin/article/edit/${article.id}`}>
<CreateIconIon className="inline mr-2 mb-1" />
Edit
</Link>
</DropdownItem>
<DropdownItem onClick={() => handleDelete(article.id)}>
<DeleteIcon
color="red"
width={20}
height={16}
className="inline mr-2 mb-1"
/>
Delete
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
);
default:
return cellValue;
}
}, []);
let typingTimer: NodeJS.Timeout;
const doneTypingInterval = 1500;
const handleKeyUp = () => {
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
};
const handleKeyDown = () => {
clearTimeout(typingTimer);
};
async function doneTyping() {
initState();
}
return (
<>
<div className="mx-5 my-5">
<div className="flex flex-col items-start rounded-2xl gap-3">
<div className="flex flex-row gap-3 w-full">
<div className="flex flex-col gap-1 w-1/3">
<p className="font-semibold text-sm">Search</p>
<Input
aria-label="Search"
classNames={{
inputWrapper: "bg-default-100",
input: "text-sm",
}}
labelPlacement="outside"
startContent={
<SearchIcon className="text-base text-default-400 pointer-events-none flex-shrink-0" />
}
type="text"
onChange={(e) => setSearch(e.target.value)}
onKeyUp={handleKeyUp}
onKeyDown={handleKeyDown}
/>
</div>
<div className="flex flex-col gap-1 w-[72px]">
<p className="font-semibold text-sm">Show</p>
<Select
label=""
variant="bordered"
labelPlacement="outside"
placeholder="Select"
selectedKeys={[showData]}
className="w-full"
onChange={(e) =>
e.target.value === "" ? "" : setShowData(e.target.value)
}
>
<SelectItem key="5" value="5">
5
</SelectItem>
<SelectItem key="10" value="10">
10
</SelectItem>
</Select>
</div>
<div className="flex flex-col gap-1 w-[170px]">
<p className="font-semibold text-sm">Category</p>
<Select
label=""
variant="bordered"
labelPlacement="outside"
placeholder="Select"
selectedKeys={[showData]}
className="w-full"
onChange={(e) =>
e.target.value === "" ? "" : setShowData(e.target.value)
}
>
<SelectItem key="10" value="10">
Polda Metro Jaya
</SelectItem>
<SelectItem key="5" value="5">
Polda Sumatera Utara
</SelectItem>
</Select>
</div>
<div className="flex flex-col gap-1 w-[170px]">
<p className="font-semibold text-sm">Date</p>
<Datepicker
useRange={false}
asSingle={true}
value={startDateValue}
displayFormat="DD/MM/YYYY"
onChange={(e: any) => setStartDateValue(e)}
inputClassName="z-50 w-full text-sm bg-transparent border-1 border-gray-200 px-2 py-[6px] rounded-xl h-[40px]"
/>
</div>
</div>
<Table
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 className="my-2 w-full flex justify-center">
<Pagination
isCompact
showControls
showShadow
color="primary"
classNames={{
base: "bg-transparent",
wrapper: "bg-transparent",
}}
page={page}
total={totalPage}
onChange={(page) => setPage(page)}
/>
</div>
</div>
</div>
</>
);
} }

View File

@ -1,133 +1,139 @@
export type SiteConfig = typeof siteConfig; export type SiteConfig = typeof siteConfig;
export const siteConfig = { export const siteConfig = {
name: "DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri", name: "DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri",
description: "DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri.", description:
navItems: [ "DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri.",
{ navItems: [
label: "Home", {
href: "/", label: "Home",
}, href: "/",
{ },
label: "Docs", {
href: "/docs", label: "Docs",
}, href: "/docs",
{ },
label: "Pricing", {
href: "/pricing", label: "Pricing",
}, href: "/pricing",
{ },
label: "Blog", {
href: "/blog", label: "Blog",
}, href: "/blog",
{ },
label: "About", {
href: "/about", label: "About",
} href: "/about",
], },
humasMenuItems: [ ],
{ humasMenuItems: [
key: "home", {
label: "Beranda", key: "home",
href: "/", label: "Beranda",
}, href: "/",
{ },
key: "about", {
label: "Tentang", key: "about",
submenu: [ label: "Tentang",
{ submenu: [
label: "Tentang Humas POLRI", {
href: "/tentang-humas-polri" label: "Tentang Humas POLRI",
}, href: "/tentang-humas-polri",
{ },
label: "Profile Pimpinan POLRI", {
href: "/profile-pimpinan-polri" label: "Profile Pimpinan POLRI",
}, href: "/profile-pimpinan-polri",
{ },
label: "Struktur Organisasi", {
href: "/struktur-organisasi" label: "Struktur Organisasi",
}, href: "/struktur-organisasi",
{ },
label: "Visi dan Misi", {
href: "/visi-misi" label: "Visi dan Misi",
}, href: "/visi-misi",
{ },
label: "Tugas dan Fungsi", {
href: "/tugas-dan-fungsi" label: "Tugas dan Fungsi",
}, href: "/tugas-dan-fungsi",
{ },
label: "Logo", {
href: "#" label: "Logo",
} href: "#",
] },
}, ],
{ },
key: "ppid", {
label: "Portal PPID", key: "ppid",
href: "/portal-ppid", label: "Portal PPID",
}, href: "/portal-ppid",
{ },
key: "service", {
label: "Pelayanan Masyarakat", key: "service",
submenu: [ label: "Pelayanan Masyarakat",
{ submenu: [
label: "Formulir Permohonan Informasi", {
href: "/form-permohonan-informasi" label: "Formulir Permohonan Informasi",
}, href: "/form-permohonan-informasi",
{ },
label: "Pelayanan SIM", {
href: "https://www.digitalkorlantas.id/sim/" label: "Pelayanan SIM",
}, href: "https://www.digitalkorlantas.id/sim/",
{ },
label: "Pelayanan e-Rikkes SIM", {
href: "https://erikkes.id/" label: "Pelayanan e-Rikkes SIM",
}, href: "https://erikkes.id/",
{ },
label: "Pelayanan Tes Psikologi SIM", {
href: "https://eppsi.id/" label: "Pelayanan Tes Psikologi SIM",
}, href: "https://eppsi.id/",
{ },
label: "Pelayanan e-Avis", {
href: "https://e-avis.korlantas.polri.go.id/" label: "Pelayanan e-Avis",
}, href: "https://e-avis.korlantas.polri.go.id/",
{ },
label: "Pelayanan Samsat Digital", {
href: "https://samsatdigital.id/" label: "Pelayanan Samsat Digital",
}, href: "https://samsatdigital.id/",
{ },
label: "Pelayanan SKCK", {
href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi&hl=en_US" label: "Pelayanan SKCK",
}, href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi&hl=en_US",
{ },
label: "Pelayanan Propam Presisi", {
href: "https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam" label: "Pelayanan Propam Presisi",
}, href: "https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam",
{ },
label: "Pelayanan Dumas Presisi", {
href: "https://dumaspresisi.polri.go.id/" label: "Pelayanan Dumas Presisi",
}, href: "https://dumaspresisi.polri.go.id/",
{ },
label: "Pelayanan Binmas", {
href: "https://bos.polri.go.id/login" label: "Pelayanan Binmas",
}, href: "https://bos.polri.go.id/login",
{ },
label: "Wistle Blower System", {
href: "https://play.google.com/store/apps/details?id=id.go.ssdmpolri.pengaduanappsbarupolri2" label: "Wistle Blower System",
}, href: "https://play.google.com/store/apps/details?id=id.go.ssdmpolri.pengaduanappsbarupolri2",
] },
}, ],
{ },
key: "contact", {
label: "Kontak", key: "contact",
href: "/kontak-kami", label: "Kontak",
}, href: "/kontak-kami",
], },
{
key: "login",
label: "Login",
href: "/auth",
},
],
links: { links: {
github: "https://github.com/nextui-org/nextui", github: "https://github.com/nextui-org/nextui",
twitter: "https://twitter.com/getnextui", twitter: "https://twitter.com/getnextui",
docs: "https://nextui.org", docs: "https://nextui.org",
discord: "https://discord.gg/9b6yyZKmH4", discord: "https://discord.gg/9b6yyZKmH4",
sponsor: "https://patreon.com/jrgarciadev" sponsor: "https://patreon.com/jrgarciadev",
}, },
}; };

9
package-lock.json generated
View File

@ -39,6 +39,7 @@
"html-react-parser": "^5.1.10", "html-react-parser": "^5.1.10",
"intl-messageformat": "^10.5.0", "intl-messageformat": "^10.5.0",
"jodit-react": "^4.0.25", "jodit-react": "^4.0.25",
"js-cookie": "^3.0.5",
"next": "14.0.2", "next": "14.0.2",
"next-themes": "^0.2.1", "next-themes": "^0.2.1",
"postcss": "8.4.31", "postcss": "8.4.31",
@ -4887,6 +4888,14 @@
"react-dom": "~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-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
"engines": {
"node": ">=14"
}
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"license": "MIT" "license": "MIT"

View File

@ -40,6 +40,7 @@
"html-react-parser": "^5.1.10", "html-react-parser": "^5.1.10",
"intl-messageformat": "^10.5.0", "intl-messageformat": "^10.5.0",
"jodit-react": "^4.0.25", "jodit-react": "^4.0.25",
"js-cookie": "^3.0.5",
"next": "14.0.2", "next": "14.0.2",
"next-themes": "^0.2.1", "next-themes": "^0.2.1",
"postcss": "8.4.31", "postcss": "8.4.31",

View File

@ -1,35 +1,45 @@
import { httpDeleteInterceptor, httpGet, httpPost, httpPut } from "./http-config/axios-base-service"; import { PaginationRequest } from "@/types/globals";
import {
httpDeleteInterceptor,
httpGet,
httpPost,
httpPut,
} from "./http-config/axios-base-service";
export async function getListArticle() { export async function getListArticle(props: PaginationRequest) {
const headers = { const { page, limit, search } = props;
"content-type": "application/json", const headers = {
}; "content-type": "application/json",
return await httpGet(`/articles`, headers); };
return await httpGet(
`/articles?limit=${limit}&page=${page}&title=${search}`,
headers
);
} }
export async function createArticle(data: any) { export async function createArticle(data: any) {
const headers = { const headers = {
"content-type": "application/json", "content-type": "application/json",
}; };
const pathUrl = `/articles`; const pathUrl = `/articles`;
return await httpPost(pathUrl, headers, data); return await httpPost(pathUrl, headers, data);
} }
export async function updateArticle(id: any) { export async function updateArticle(id: any) {
const headers = { const headers = {
"content-type": "application/json", "content-type": "application/json",
}; };
const pathUrl = `/articles/${id}`; const pathUrl = `/articles/${id}`;
return await httpPut(pathUrl, headers); return await httpPut(pathUrl, headers);
} }
export async function getArticleById(id: any) { export async function getArticleById(id: any) {
const headers = { const headers = {
"content-type": "application/json", "content-type": "application/json",
}; };
return await httpGet(`/articles/${id}`, headers); return await httpGet(`/articles/${id}`, headers);
} }
export async function deleteArticle(id: string) { export async function deleteArticle(id: string) {
return await httpDeleteInterceptor(`articles/${id}`); return await httpDeleteInterceptor(`articles/${id}`);
} }

View File

@ -1,20 +1,39 @@
import { httpDeleteInterceptor, httpGet, httpPost } from "./http-config/axios-base-service"; import {
httpDeleteInterceptor,
httpGet,
httpPost,
} from "./http-config/axios-base-service";
export async function listMasterUsers() { export async function listMasterUsers() {
const headers = { const headers = {
"content-type": "application/json", "content-type": "application/json",
}; };
return await httpGet(`/users`, headers); return await httpGet(`/users`, headers);
} }
export async function createMasterUser(data: any) { export async function createMasterUser(data: any) {
const headers = { const headers = {
"content-type": "application/json", "content-type": "application/json",
}; };
const pathUrl = `/users`; const pathUrl = `/users`;
return await httpPost(pathUrl, headers, data); return await httpPost(pathUrl, headers, data);
} }
export async function deleteMasterUser(id: string) { export async function deleteMasterUser(id: string) {
return await httpDeleteInterceptor(`/users/${id}`); return await httpDeleteInterceptor(`/users/${id}`);
}
export async function postSignIn(data: any) {
const headers = {
"content-type": "application/json",
};
const pathUrl = `/users/login`;
return await httpPost(pathUrl, headers, data);
}
export async function getProfile() {
const headers = {
"content-type": "application/json",
};
return await httpGet(`/users/info`, headers);
} }

View File

@ -1,56 +1,62 @@
import { SVGProps } from "react"; import { SVGProps } from "react";
export type IconSvgProps = SVGProps<SVGSVGElement> & { export type IconSvgProps = SVGProps<SVGSVGElement> & {
size?: number; size?: number;
}; };
export type SidebarMenuTask = { export type SidebarMenuTask = {
childMenu: any[]; childMenu: any[];
name: string; name: string;
id: number; id: number;
parentId: number; parentId: number;
position: number; position: number;
statusId: number; statusId: number;
statusName: string; statusName: string;
}; };
export type Article = { export type Article = {
id: number; id: number;
title: string; title: string;
articleCategory: string; articleCategory: string;
updated_at: string; updated_at: string;
creator: string; creator: string;
source: string; source: string;
status: string; status: string;
actions: string; actions: string;
}; };
export type MasterUser = { export type MasterUser = {
id: number; id: number;
address: string, address: string;
dateOfBirth: string, dateOfBirth: string;
email: string, email: string;
fullname: string, fullname: string;
genderType: string, genderType: string;
identityNumber: string, identityNumber: string;
identityType: string, identityType: string;
lastEducation: string, lastEducation: string;
phoneNumber: string, phoneNumber: string;
userLevelsId: number, userLevelsId: number;
userRoleId: number, userRoleId: number;
username: string, username: string;
workType: string workType: string;
}; };
export type MasterUserRole = { export type MasterUserRole = {
id: number, id: number;
name: string, name: string;
description: string, description: string;
code: string, code: string;
level_number: number, level_number: number;
status_id: number, status_id: number;
created_by_id: string | number, created_by_id: string | number;
is_active: true, is_active: true;
created_at: string, created_at: string;
updated_at: string updated_at: string;
};
export type PaginationRequest = {
limit: string;
page: number;
search: string;
}; };