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";
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>

View File

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

View File

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

View File

@ -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,6 +378,11 @@ export default function NavbarHumas() {
{siteConfig.humasMenuItems.map((item) => (
<div key={item.key} className="relative">
<NavbarMenuItem>
{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"
@ -393,6 +401,7 @@ export default function NavbarHumas() {
<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>
);
}

View File

@ -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 ? (
<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={`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`}
className="hover:text-red-600 underline text-sm cursor-pointer"
onClick={() => onLogout()}
>
<InfoCircleIcon size={24} />
{isOpen && "Support"}
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>
);
};

View File

@ -3,9 +3,10 @@ import {
CreateIconIon,
DeleteIcon,
DotsYIcon,
EyeIconMdi
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";
@ -16,63 +17,77 @@ import {
DropdownItem,
DropdownMenu,
DropdownTrigger,
Input,
Pagination,
Select,
SelectItem,
Spinner,
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow
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 statusColorMap = {
active: "success",
paused: "danger",
vacation: "warning",
};
export default function ArticleTable() {
const MySwal = withReactContent(Swal);
const [article, setArticle] = useState<Article[]>([]);
useEffect(() => {
async function initState() {
const res = await getListArticle();
setArticle(res.data?.data);
console.log("List Article", res.data.data);
}
initState();
}, []);
type TableRow = (typeof usersTable)[0];
const columns = [
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" },
];
{ name: "Aksi", uid: "actions" },
];
type ArticleData = Article & {
no: number;
};
export default function ArticleTable() {
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(() => {
initState();
}, [page, showData, startDateValue]);
async function initState() {
const startDate: string = `${startDateValue.startDate}`;
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 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);
}
};
async function doDelete(id: any) {
// loading();
@ -114,55 +129,8 @@ export default function ArticleTable() {
});
}
// 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 renderCell = useCallback((article: ArticleData, columnKey: Key) => {
const cellValue = article[columnKey as keyof ArticleData];
const statusColorMap: Record<string, ChipProps["color"]> = {
active: "primary",
cancel: "danger",
@ -170,11 +138,6 @@ export default function ArticleTable() {
};
switch (columnKey) {
case "no":
return (
<div>{article.id}</div>
)
case "status":
return (
<Chip
@ -199,35 +162,19 @@ export default function ArticleTable() {
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem
>
<Link
href={`/admin/article/detail/${article.id}`}
>
<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}`}
>
<DropdownItem>
<Link href={`/admin/article/edit/${article.id}`}>
<CreateIconIon className="inline mr-2 mb-1" />
Edit
</Link>
</DropdownItem>
<DropdownItem
onClick={() => handleDelete(article.id)}
>
<DropdownItem onClick={() => handleDelete(article.id)}>
<DeleteIcon
color="red"
width={20}
@ -235,9 +182,7 @@ export default function ArticleTable() {
className="inline mr-2 mb-1"
/>
Delete
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
@ -248,19 +193,107 @@ export default function ArticleTable() {
}
}, []);
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-center rounded-2xl">
<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
// 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 ",
wrapper:
"min-h-[50px] bg-transpararent text-black dark:text-white ",
}}
>
<TableHeader columns={columns}>
@ -282,9 +315,23 @@ export default function ArticleTable() {
)}
</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

@ -2,7 +2,8 @@ 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.",
description:
"DIVISI HUMAS POLRI - Pengelola Informasi dan Dokumentasi Polri.",
navItems: [
{
label: "Home",
@ -23,7 +24,7 @@ export const siteConfig = {
{
label: "About",
href: "/about",
}
},
],
humasMenuItems: [
{
@ -37,29 +38,29 @@ export const siteConfig = {
submenu: [
{
label: "Tentang Humas POLRI",
href: "/tentang-humas-polri"
href: "/tentang-humas-polri",
},
{
label: "Profile Pimpinan POLRI",
href: "/profile-pimpinan-polri"
href: "/profile-pimpinan-polri",
},
{
label: "Struktur Organisasi",
href: "/struktur-organisasi"
href: "/struktur-organisasi",
},
{
label: "Visi dan Misi",
href: "/visi-misi"
href: "/visi-misi",
},
{
label: "Tugas dan Fungsi",
href: "/tugas-dan-fungsi"
href: "/tugas-dan-fungsi",
},
{
label: "Logo",
href: "#"
}
]
href: "#",
},
],
},
{
key: "ppid",
@ -72,55 +73,60 @@ export const siteConfig = {
submenu: [
{
label: "Formulir Permohonan Informasi",
href: "/form-permohonan-informasi"
href: "/form-permohonan-informasi",
},
{
label: "Pelayanan SIM",
href: "https://www.digitalkorlantas.id/sim/"
href: "https://www.digitalkorlantas.id/sim/",
},
{
label: "Pelayanan e-Rikkes SIM",
href: "https://erikkes.id/"
href: "https://erikkes.id/",
},
{
label: "Pelayanan Tes Psikologi SIM",
href: "https://eppsi.id/"
href: "https://eppsi.id/",
},
{
label: "Pelayanan e-Avis",
href: "https://e-avis.korlantas.polri.go.id/"
href: "https://e-avis.korlantas.polri.go.id/",
},
{
label: "Pelayanan Samsat Digital",
href: "https://samsatdigital.id/"
href: "https://samsatdigital.id/",
},
{
label: "Pelayanan SKCK",
href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi&hl=en_US"
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"
href: "https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam",
},
{
label: "Pelayanan Dumas Presisi",
href: "https://dumaspresisi.polri.go.id/"
href: "https://dumaspresisi.polri.go.id/",
},
{
label: "Pelayanan Binmas",
href: "https://bos.polri.go.id/login"
href: "https://bos.polri.go.id/login",
},
{
label: "Wistle Blower System",
href: "https://play.google.com/store/apps/details?id=id.go.ssdmpolri.pengaduanappsbarupolri2"
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: {
@ -128,6 +134,6 @@ export const siteConfig = {
twitter: "https://twitter.com/getnextui",
docs: "https://nextui.org",
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",
"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"

View File

@ -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",

View File

@ -1,10 +1,20 @@
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 { page, limit, search } = props;
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) {

View File

@ -1,4 +1,8 @@
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 = {
@ -18,3 +22,18 @@ export async function createMasterUser(data: any) {
export async function deleteMasterUser(id: string) {
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

@ -27,30 +27,36 @@ export type Article = {
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
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;
};