feat:login button, auth, fix:admin - article page
This commit is contained in:
parent
e7482b346d
commit
d18bbfe568
|
|
@ -1,15 +1,103 @@
|
|||
"use client";
|
||||
import { Input } from "@nextui-org/input";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { EyeFilledIcon, EyeSlashFilledIcon } from "../icons";
|
||||
import { Button } from "@nextui-org/button";
|
||||
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() {
|
||||
const router = useRouter();
|
||||
const [isVisible, setIsVisible] = React.useState(false);
|
||||
|
||||
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 (
|
||||
<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">
|
||||
|
|
@ -39,6 +127,15 @@ export default function Login() {
|
|||
label="Username"
|
||||
placeholder="Masukkan username anda!"
|
||||
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>
|
||||
|
|
@ -77,50 +174,15 @@ export default function Login() {
|
|||
label="Password"
|
||||
placeholder="Masukkan password anda"
|
||||
variant="underlined"
|
||||
onChange={(event) => setPassword(event.target.value)}
|
||||
/>
|
||||
</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>
|
||||
<Button
|
||||
size="lg"
|
||||
className="w-full bg-[#DD8306] rounded-md font-semibold"
|
||||
onPress={onSubmit}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ export default function ENewsPolri() {
|
|||
|
||||
useEffect(() => {
|
||||
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);
|
||||
setArticle(response?.data?.data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ export default function HeaderNews() {
|
|||
|
||||
useEffect(() => {
|
||||
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);
|
||||
setArticle(response?.data?.data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -363,6 +363,9 @@ export default function NavbarHumas() {
|
|||
<div>
|
||||
<ThemeSwitch />
|
||||
</div>
|
||||
<Link href="/auth">
|
||||
<Button className="bg-[#DD8306]">Login</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -375,24 +378,30 @@ export default function NavbarHumas() {
|
|||
{siteConfig.humasMenuItems.map((item) => (
|
||||
<div key={item.key} className="relative">
|
||||
<NavbarMenuItem>
|
||||
<div
|
||||
onClick={() => toggleDropdown(item.key)}
|
||||
className="flex items-end gap-2"
|
||||
>
|
||||
{item.href ? (
|
||||
<Link href={item.href} target="_blank">
|
||||
<span>{item.label}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<span>{item.label}</span>
|
||||
)}
|
||||
{item.submenu &&
|
||||
(dropdownOpen[item.key] ? (
|
||||
<ChevronUpIcon />
|
||||
{item.key === "login" ? (
|
||||
<Link href="/auth" className="my-3">
|
||||
<Button className="bg-[#DD8306]">Login</Button>
|
||||
</Link>
|
||||
) : (
|
||||
<div
|
||||
onClick={() => toggleDropdown(item.key)}
|
||||
className="flex items-end gap-2"
|
||||
>
|
||||
{item.href ? (
|
||||
<Link href={item.href} target="_blank">
|
||||
<span>{item.label}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<ChevronDownIcon />
|
||||
))}
|
||||
</div>
|
||||
<span>{item.label}</span>
|
||||
)}
|
||||
{item.submenu &&
|
||||
(dropdownOpen[item.key] ? (
|
||||
<ChevronUpIcon />
|
||||
) : (
|
||||
<ChevronDownIcon />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</NavbarMenuItem>
|
||||
{dropdownOpen[item.key] && item.submenu && (
|
||||
<div className="pl-2">
|
||||
|
|
@ -410,219 +419,5 @@ export default function NavbarHumas() {
|
|||
</NavbarContent>
|
||||
</div>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { SidebarMenuTask } from "@/types/globals";
|
||||
import { Tooltip } from "@nextui-org/react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
ChevronLeftIcon,
|
||||
|
|
@ -24,6 +24,8 @@ import { SidebarCollapseItems } from "./sidebar-collapse-items";
|
|||
import { SidebarCollapseSubItems } from "./sidebar-collapse-sub-items";
|
||||
import { useSidebar } from "./sidebar-context";
|
||||
import { SidebarMenu } from "./sidebar-menu";
|
||||
import Image from "next/image";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
interface SubMenuItems {
|
||||
id: number;
|
||||
|
|
@ -176,20 +178,7 @@ const sideBarDummyData = [
|
|||
statusName: "Active",
|
||||
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,
|
||||
name: "Master User Role",
|
||||
|
|
@ -204,108 +193,32 @@ const sideBarDummyData = [
|
|||
statusName: "Active",
|
||||
childModule: null,
|
||||
},
|
||||
// {
|
||||
// id: 11,
|
||||
// name: "Form Wizard",
|
||||
// moduleId: 657,
|
||||
// moduleName: "Form Wizard",
|
||||
// modulePathUrl: "/admin/form-wizard",
|
||||
// parentId: -1,
|
||||
// icon: <FormWizardIcon />,
|
||||
// position: 1,
|
||||
// statusId: 1,
|
||||
// childMenu: [],
|
||||
// statusName: "Active",
|
||||
// childModule: null,
|
||||
// },
|
||||
// {
|
||||
// id: 13,
|
||||
// name: "Others",
|
||||
// moduleId: 658,
|
||||
// moduleName: "Others",
|
||||
// modulePathUrl: "/admin/basic",
|
||||
// isGroup: true,
|
||||
// parentId: -1,
|
||||
// icon: "table",
|
||||
// position: 1,
|
||||
// statusId: 1,
|
||||
// childMenu: [],
|
||||
// statusName: "Active",
|
||||
// childModule: null,
|
||||
// },
|
||||
// {
|
||||
// id: 13,
|
||||
// name: "Menu 1",
|
||||
// moduleId: 652,
|
||||
// moduleName: "Menu 1",
|
||||
// modulePathUrl: "/admin/menu1",
|
||||
// parentId: -1,
|
||||
// icon: <HomeIcon />,
|
||||
// position: 1,
|
||||
// statusId: 1,
|
||||
// statusName: "Active",
|
||||
// childMenu: [
|
||||
// {
|
||||
// id: 3,
|
||||
// name: "SubMenu 1",
|
||||
// moduleId: 653,
|
||||
// moduleName: "SubMenu 1",
|
||||
// modulePathUrl: "/admin/menu1/submenu1",
|
||||
// parentId: 702,
|
||||
// icon: <Submenu1Icon size={16} />,
|
||||
// position: 2,
|
||||
// statusId: 1,
|
||||
// statusName: "Active",
|
||||
// childMenu: [],
|
||||
// childModule: null,
|
||||
// },
|
||||
// {
|
||||
// id: 4,
|
||||
// name: "SubMenu 2",
|
||||
// moduleId: 653,
|
||||
// moduleName: "SubMenu 2",
|
||||
// modulePathUrl: "/admin/menu1/submenu2",
|
||||
// parentId: 702,
|
||||
// icon: <Submenu2Icon size={16} />,
|
||||
// position: 2,
|
||||
// statusId: 1,
|
||||
// statusName: "Active",
|
||||
// childMenu: [],
|
||||
// childModule: null,
|
||||
// }
|
||||
// ],
|
||||
// childModule: null,
|
||||
// },
|
||||
];
|
||||
|
||||
const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
|
||||
const { isOpen, toggleSidebar } = useSidebar();
|
||||
const token = Cookies.get("access_token");
|
||||
|
||||
const closeSidebar = () => {
|
||||
if (isOpen) {
|
||||
toggleSidebar();
|
||||
useEffect(() => {
|
||||
if (!token) {
|
||||
onLogout();
|
||||
}
|
||||
}, [token]);
|
||||
|
||||
const onLogout = () => {
|
||||
Object.keys(Cookies.get()).forEach((cookieName) => {
|
||||
Cookies.remove(cookieName);
|
||||
});
|
||||
router.push("/auth");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
updateSidebarData(isOpen);
|
||||
}, [isOpen]);
|
||||
|
||||
const renderIcon = (icon: string) => {
|
||||
switch (icon) {
|
||||
case "dashboard":
|
||||
return <DashboardIcon />;
|
||||
case "menu1":
|
||||
return <HomeIcon />;
|
||||
case "table":
|
||||
return <TableIcon />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`flex h-full ${isOpen ? "min-w-[290px]" : "min-w-[80px]"}`}>
|
||||
<div
|
||||
|
|
@ -383,6 +296,7 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
|
|||
? sideBarDummyData?.map((list: any, index: number) =>
|
||||
list.isGroup ? (
|
||||
<p
|
||||
key={list}
|
||||
className={`font-bold mr-4 ${!isOpen ? "text-center" : ""}`}
|
||||
>
|
||||
{isOpen ? list.name : "..."}
|
||||
|
|
@ -460,17 +374,26 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
|
|||
{isOpen && "Theme"}
|
||||
</div>
|
||||
{isOpen ? (
|
||||
<a
|
||||
className={`cursor-pointer flex flex-row ${
|
||||
isOpen ? "justify-start" : "justify-center"
|
||||
} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}
|
||||
>
|
||||
<InfoCircleIcon size={24} />
|
||||
{isOpen && "Support"}
|
||||
</a>
|
||||
<div className="flex flex-row gap-3">
|
||||
<Image
|
||||
src="/pengaduan.png"
|
||||
width={72}
|
||||
height={72}
|
||||
alt="profile"
|
||||
/>
|
||||
<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
|
||||
content="Support"
|
||||
content="Profile"
|
||||
delay={0}
|
||||
closeDelay={0}
|
||||
placement="right"
|
||||
|
|
@ -479,65 +402,20 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
|
|||
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`}
|
||||
onClick={toggleSidebar}
|
||||
>
|
||||
<InfoCircleIcon size={24} />
|
||||
{isOpen && "Support"}
|
||||
</a>
|
||||
</Tooltip>
|
||||
)}
|
||||
{isOpen ? (
|
||||
<a
|
||||
className={`ml-[1px] cursor-pointer flex flex-row ${
|
||||
isOpen ? "justify-start" : "justify-center"
|
||||
} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}
|
||||
>
|
||||
<MinusCircleIcon size={21} />
|
||||
{isOpen && "Log Out"}
|
||||
</a>
|
||||
) : (
|
||||
<Tooltip
|
||||
content="Log Out"
|
||||
delay={0}
|
||||
closeDelay={0}
|
||||
placement="right"
|
||||
>
|
||||
<a
|
||||
className={`cursor-pointer flex flex-row ${
|
||||
isOpen ? "justify-start" : "justify-center"
|
||||
} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}
|
||||
>
|
||||
<MinusCircleIcon size={21} />
|
||||
{isOpen && "Log Out"}
|
||||
<Image
|
||||
src="/pengaduan.png"
|
||||
width={48}
|
||||
height={48}
|
||||
alt="profile"
|
||||
/>
|
||||
</a>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <div className="hidden md:block w-20 bg-gray-100 dark:bg-stone-950 h-full text-black dark:text-white">
|
||||
<div className={`mt-4 flex justify-center w-full ${isOpen ? "hidden" : ""}`}>
|
||||
<button
|
||||
className="w-6 h-6 z-40"
|
||||
onClick={toggleSidebar}
|
||||
>
|
||||
<MenuBurgerIcon />
|
||||
|
||||
</button>
|
||||
</div>
|
||||
{sideBarDummyData.map((list) => (
|
||||
<div key={list.id} className='w-full flex justify-center my-2'>
|
||||
<ClosedSidebarIcon icon={list.icon} isActive={pathname.includes(list.modulePathUrl)} childMenu={list.childMenu} path={list.modulePathUrl} title={list.name} />
|
||||
</div>
|
||||
))}
|
||||
|
||||
</div>
|
||||
{isOpen && (
|
||||
<div
|
||||
className="block md:hidden fixed top-0 left-0 h-full w-full bg-black opacity-50 z-30"
|
||||
onClick={toggleSidebar}
|
||||
></div>
|
||||
)} */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,290 +1,337 @@
|
|||
"use client";
|
||||
import {
|
||||
CreateIconIon,
|
||||
DeleteIcon,
|
||||
DotsYIcon,
|
||||
EyeIconMdi
|
||||
CreateIconIon,
|
||||
DeleteIcon,
|
||||
DotsYIcon,
|
||||
EyeIconMdi,
|
||||
SearchIcon,
|
||||
} from "@/components/icons";
|
||||
import { error, success, } from "@/config/swal";
|
||||
import { error, success } from "@/config/swal";
|
||||
import { deleteArticle, 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
|
||||
Chip,
|
||||
ChipProps,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DropdownMenu,
|
||||
DropdownTrigger,
|
||||
Input,
|
||||
Pagination,
|
||||
Select,
|
||||
SelectItem,
|
||||
Spinner,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableColumn,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@nextui-org/react";
|
||||
import Link from "next/link";
|
||||
import { Key, useCallback, useEffect, useState } from "react";
|
||||
import Datepicker from "react-tailwindcss-datepicker";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
|
||||
type UserObject = {
|
||||
id: number;
|
||||
user: string;
|
||||
status: string;
|
||||
projectName: string;
|
||||
avatar: string;
|
||||
};
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
{ name: "Judul", uid: "title" },
|
||||
{ name: "Kategori", uid: "categoryName" },
|
||||
{ name: "Tanggal Unggah", uid: "createdAt" },
|
||||
{ name: "Kreator", uid: "createdByName" },
|
||||
|
||||
const statusColorMap = {
|
||||
active: "success",
|
||||
paused: "danger",
|
||||
vacation: "warning",
|
||||
};
|
||||
{ name: "Aksi", uid: "actions" },
|
||||
];
|
||||
|
||||
type ArticleData = Article & {
|
||||
no: number;
|
||||
};
|
||||
|
||||
export default function ArticleTable() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [article, setArticle] = useState<Article[]>([]);
|
||||
const MySwal = withReactContent(Swal);
|
||||
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(() => {
|
||||
async function initState() {
|
||||
const res = await getListArticle();
|
||||
setArticle(res.data?.data);
|
||||
useEffect(() => {
|
||||
initState();
|
||||
}, [page, showData, startDateValue]);
|
||||
|
||||
console.log("List Article", res.data.data);
|
||||
}
|
||||
async function initState() {
|
||||
const startDate: string = `${startDateValue.startDate}`;
|
||||
|
||||
initState();
|
||||
}, []);
|
||||
type TableRow = (typeof usersTable)[0];
|
||||
const req = { limit: showData, page: page, search: search };
|
||||
const res = await getListArticle(req);
|
||||
getTableNumber(parseInt(showData), res.data?.data);
|
||||
console.log("res.data?.data", res.data);
|
||||
setTotalPage(res?.data?.meta?.totalPage);
|
||||
}
|
||||
|
||||
const columns = [
|
||||
|
||||
{ name: "No", uid: "no" },
|
||||
{ name: "Judul", uid: "title" },
|
||||
{ name: "Kategori", uid: "categoryName" },
|
||||
{ name: "Tanggal Unggah", uid: "createdAt" },
|
||||
{ name: "Kreator", uid: "createdByName" },
|
||||
// { name: "Sumber", uid: "source" },
|
||||
// { name: "Users", uid: "users" },
|
||||
// { name: "Status", uid: "status" },
|
||||
{ name: "Aksi", uid: "actions" },
|
||||
];
|
||||
|
||||
|
||||
async function doDelete(id: any) {
|
||||
// loading();
|
||||
const resDelete = await deleteArticle(id);
|
||||
|
||||
if (resDelete?.error) {
|
||||
error(resDelete.message);
|
||||
return false;
|
||||
}
|
||||
close();
|
||||
success("Success Deleted");
|
||||
const getTableNumber = (limit: number, data: Article[]) => {
|
||||
if (data) {
|
||||
const startIndex = limit * (page - 1);
|
||||
let iterate = 0;
|
||||
const newData = data.map((value: any) => {
|
||||
iterate++;
|
||||
value.no = startIndex + iterate;
|
||||
return value;
|
||||
});
|
||||
console.log("daata", data);
|
||||
setArticle(newData);
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
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) => {
|
||||
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() {
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// initStete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 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>
|
||||
switch (columnKey) {
|
||||
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;
|
||||
}
|
||||
}, []);
|
||||
|
||||
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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
262
config/site.ts
262
config/site.ts
|
|
@ -1,133 +1,139 @@
|
|||
export type SiteConfig = typeof siteConfig;
|
||||
|
||||
export const siteConfig = {
|
||||
name: "DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri",
|
||||
description: "DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri.",
|
||||
navItems: [
|
||||
{
|
||||
label: "Home",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
label: "Docs",
|
||||
href: "/docs",
|
||||
},
|
||||
{
|
||||
label: "Pricing",
|
||||
href: "/pricing",
|
||||
},
|
||||
{
|
||||
label: "Blog",
|
||||
href: "/blog",
|
||||
},
|
||||
{
|
||||
label: "About",
|
||||
href: "/about",
|
||||
}
|
||||
],
|
||||
humasMenuItems: [
|
||||
{
|
||||
key: "home",
|
||||
label: "Beranda",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
key: "about",
|
||||
label: "Tentang",
|
||||
submenu: [
|
||||
{
|
||||
label: "Tentang Humas POLRI",
|
||||
href: "/tentang-humas-polri"
|
||||
},
|
||||
{
|
||||
label: "Profile Pimpinan POLRI",
|
||||
href: "/profile-pimpinan-polri"
|
||||
},
|
||||
{
|
||||
label: "Struktur Organisasi",
|
||||
href: "/struktur-organisasi"
|
||||
},
|
||||
{
|
||||
label: "Visi dan Misi",
|
||||
href: "/visi-misi"
|
||||
},
|
||||
{
|
||||
label: "Tugas dan Fungsi",
|
||||
href: "/tugas-dan-fungsi"
|
||||
},
|
||||
{
|
||||
label: "Logo",
|
||||
href: "#"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "ppid",
|
||||
label: "Portal PPID",
|
||||
href: "/portal-ppid",
|
||||
},
|
||||
{
|
||||
key: "service",
|
||||
label: "Pelayanan Masyarakat",
|
||||
submenu: [
|
||||
{
|
||||
label: "Formulir Permohonan Informasi",
|
||||
href: "/form-permohonan-informasi"
|
||||
},
|
||||
{
|
||||
label: "Pelayanan SIM",
|
||||
href: "https://www.digitalkorlantas.id/sim/"
|
||||
},
|
||||
{
|
||||
label: "Pelayanan e-Rikkes SIM",
|
||||
href: "https://erikkes.id/"
|
||||
},
|
||||
{
|
||||
label: "Pelayanan Tes Psikologi SIM",
|
||||
href: "https://eppsi.id/"
|
||||
},
|
||||
{
|
||||
label: "Pelayanan e-Avis",
|
||||
href: "https://e-avis.korlantas.polri.go.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 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 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"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "contact",
|
||||
label: "Kontak",
|
||||
href: "/kontak-kami",
|
||||
},
|
||||
],
|
||||
name: "DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri",
|
||||
description:
|
||||
"DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri.",
|
||||
navItems: [
|
||||
{
|
||||
label: "Home",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
label: "Docs",
|
||||
href: "/docs",
|
||||
},
|
||||
{
|
||||
label: "Pricing",
|
||||
href: "/pricing",
|
||||
},
|
||||
{
|
||||
label: "Blog",
|
||||
href: "/blog",
|
||||
},
|
||||
{
|
||||
label: "About",
|
||||
href: "/about",
|
||||
},
|
||||
],
|
||||
humasMenuItems: [
|
||||
{
|
||||
key: "home",
|
||||
label: "Beranda",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
key: "about",
|
||||
label: "Tentang",
|
||||
submenu: [
|
||||
{
|
||||
label: "Tentang Humas POLRI",
|
||||
href: "/tentang-humas-polri",
|
||||
},
|
||||
{
|
||||
label: "Profile Pimpinan POLRI",
|
||||
href: "/profile-pimpinan-polri",
|
||||
},
|
||||
{
|
||||
label: "Struktur Organisasi",
|
||||
href: "/struktur-organisasi",
|
||||
},
|
||||
{
|
||||
label: "Visi dan Misi",
|
||||
href: "/visi-misi",
|
||||
},
|
||||
{
|
||||
label: "Tugas dan Fungsi",
|
||||
href: "/tugas-dan-fungsi",
|
||||
},
|
||||
{
|
||||
label: "Logo",
|
||||
href: "#",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "ppid",
|
||||
label: "Portal PPID",
|
||||
href: "/portal-ppid",
|
||||
},
|
||||
{
|
||||
key: "service",
|
||||
label: "Pelayanan Masyarakat",
|
||||
submenu: [
|
||||
{
|
||||
label: "Formulir Permohonan Informasi",
|
||||
href: "/form-permohonan-informasi",
|
||||
},
|
||||
{
|
||||
label: "Pelayanan SIM",
|
||||
href: "https://www.digitalkorlantas.id/sim/",
|
||||
},
|
||||
{
|
||||
label: "Pelayanan e-Rikkes SIM",
|
||||
href: "https://erikkes.id/",
|
||||
},
|
||||
{
|
||||
label: "Pelayanan Tes Psikologi SIM",
|
||||
href: "https://eppsi.id/",
|
||||
},
|
||||
{
|
||||
label: "Pelayanan e-Avis",
|
||||
href: "https://e-avis.korlantas.polri.go.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 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 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",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "contact",
|
||||
label: "Kontak",
|
||||
href: "/kontak-kami",
|
||||
},
|
||||
{
|
||||
key: "login",
|
||||
label: "Login",
|
||||
href: "/auth",
|
||||
},
|
||||
],
|
||||
|
||||
links: {
|
||||
github: "https://github.com/nextui-org/nextui",
|
||||
twitter: "https://twitter.com/getnextui",
|
||||
docs: "https://nextui.org",
|
||||
discord: "https://discord.gg/9b6yyZKmH4",
|
||||
sponsor: "https://patreon.com/jrgarciadev"
|
||||
},
|
||||
links: {
|
||||
github: "https://github.com/nextui-org/nextui",
|
||||
twitter: "https://twitter.com/getnextui",
|
||||
docs: "https://nextui.org",
|
||||
discord: "https://discord.gg/9b6yyZKmH4",
|
||||
sponsor: "https://patreon.com/jrgarciadev",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"html-react-parser": "^5.1.10",
|
||||
"intl-messageformat": "^10.5.0",
|
||||
"jodit-react": "^4.0.25",
|
||||
"js-cookie": "^3.0.5",
|
||||
"next": "14.0.2",
|
||||
"next-themes": "^0.2.1",
|
||||
"postcss": "8.4.31",
|
||||
|
|
@ -4887,6 +4888,14 @@
|
|||
"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": {
|
||||
"version": "4.0.0",
|
||||
"license": "MIT"
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
"html-react-parser": "^5.1.10",
|
||||
"intl-messageformat": "^10.5.0",
|
||||
"jodit-react": "^4.0.25",
|
||||
"js-cookie": "^3.0.5",
|
||||
"next": "14.0.2",
|
||||
"next-themes": "^0.2.1",
|
||||
"postcss": "8.4.31",
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/articles`, headers);
|
||||
export async function getListArticle(props: PaginationRequest) {
|
||||
const { page, limit, search } = props;
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(
|
||||
`/articles?limit=${limit}&page=${page}&title=${search}`,
|
||||
headers
|
||||
);
|
||||
}
|
||||
|
||||
export async function createArticle(data: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/articles`;
|
||||
return await httpPost(pathUrl, headers, data);
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/articles`;
|
||||
return await httpPost(pathUrl, headers, data);
|
||||
}
|
||||
|
||||
export async function updateArticle(id: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/articles/${id}`;
|
||||
return await httpPut(pathUrl, headers);
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/articles/${id}`;
|
||||
return await httpPut(pathUrl, headers);
|
||||
}
|
||||
|
||||
export async function getArticleById(id: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/articles/${id}`, headers);
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/articles/${id}`, headers);
|
||||
}
|
||||
|
||||
export async function deleteArticle(id: string) {
|
||||
return await httpDeleteInterceptor(`articles/${id}`);
|
||||
}
|
||||
return await httpDeleteInterceptor(`articles/${id}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/users`, headers);
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/users`, headers);
|
||||
}
|
||||
|
||||
export async function createMasterUser(data: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/users`;
|
||||
return await httpPost(pathUrl, headers, data);
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/users`;
|
||||
return await httpPost(pathUrl, headers, data);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,62 @@
|
|||
import { SVGProps } from "react";
|
||||
|
||||
export type IconSvgProps = SVGProps<SVGSVGElement> & {
|
||||
size?: number;
|
||||
size?: number;
|
||||
};
|
||||
|
||||
export type SidebarMenuTask = {
|
||||
childMenu: any[];
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number;
|
||||
position: number;
|
||||
statusId: number;
|
||||
statusName: string;
|
||||
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;
|
||||
id: number;
|
||||
title: string;
|
||||
articleCategory: string;
|
||||
updated_at: string;
|
||||
creator: string;
|
||||
source: string;
|
||||
status: string;
|
||||
actions: string;
|
||||
};
|
||||
|
||||
export type MasterUser = {
|
||||
id: number;
|
||||
address: string,
|
||||
dateOfBirth: string,
|
||||
email: string,
|
||||
fullname: string,
|
||||
genderType: string,
|
||||
identityNumber: string,
|
||||
identityType: string,
|
||||
lastEducation: string,
|
||||
phoneNumber: string,
|
||||
userLevelsId: number,
|
||||
userRoleId: number,
|
||||
username: string,
|
||||
workType: string
|
||||
id: number;
|
||||
address: string;
|
||||
dateOfBirth: string;
|
||||
email: string;
|
||||
fullname: string;
|
||||
genderType: string;
|
||||
identityNumber: string;
|
||||
identityType: string;
|
||||
lastEducation: string;
|
||||
phoneNumber: string;
|
||||
userLevelsId: number;
|
||||
userRoleId: number;
|
||||
username: string;
|
||||
workType: string;
|
||||
};
|
||||
|
||||
export type MasterUserRole = {
|
||||
id: number,
|
||||
name: string,
|
||||
description: string,
|
||||
code: string,
|
||||
level_number: number,
|
||||
status_id: number,
|
||||
created_by_id: string | number,
|
||||
is_active: true,
|
||||
created_at: string,
|
||||
updated_at: string
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
code: string;
|
||||
level_number: number;
|
||||
status_id: number;
|
||||
created_by_id: string | number;
|
||||
is_active: true;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
export type PaginationRequest = {
|
||||
limit: string;
|
||||
page: number;
|
||||
search: string;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue