fix:mobile admin feat:detail comment

This commit is contained in:
Rama Priyanto 2025-01-30 18:34:29 +07:00
parent 19e019fbe9
commit 308e708a3f
32 changed files with 906 additions and 256 deletions

View File

@ -4,7 +4,7 @@ import { Card } from "@nextui-org/react";
export default function CreateArticle() {
return (
<div className="bg-transparent p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<div className="bg-transparent p-3 lg:p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
{/* <FormArticle /> */}
<CreateArticleForm />
</div>

View File

@ -2,7 +2,7 @@ import EditArticleForm from "@/components/form/article/edit-article-form";
export default function DetailArticlePage() {
return (
<div className="h-[96vh] bg-transparent p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<div className="h-[96vh] bg-transparent p-3 lg:p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
{/* <FormDetailArticle /> */}
<EditArticleForm isDetail={true} />
</div>

View File

@ -2,7 +2,7 @@ import EditArticleForm from "@/components/form/article/edit-article-form";
export default function UpdateArticlePage() {
return (
<div className="h-[96vh] bg-transparent p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<div className="h-[96vh] bg-transparent p-3 lg:p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<EditArticleForm isDetail={false} />
</div>
);

View File

@ -10,9 +10,12 @@ export default function BasicPage() {
return (
<div className="overflow-x-hidden overflow-y-scroll">
<div className="px-2 md:px-4 md:py-4 w-full">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl py-3">
<Link href="/admin/article/create" className="mx-3">
<Button size="md" className="bg-[#F07C00] text-white">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl p-3">
<Link href="/admin/article/create">
<Button
size="md"
className="bg-[#F07C00] text-white w-full lg:w-fit"
>
Tambah Artikel
<AddIcon />
</Button>

View File

@ -3,7 +3,7 @@ import DashboardContainer from "@/components/main/dashboard/dashboard-container"
export default function AdminPage() {
return (
<div className="h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid">
<div className="px-4">
<div className="lg:px-4 !w-screen lg:!w-auto">
<DashboardContainer />
</div>
</div>

View File

@ -4,7 +4,7 @@ import React from "react";
const AdminMagazineCreate = () => {
return (
<div className="h-[96vh] bg-transparent p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<div className="h-[96vh] bg-transparent p-3 lg:p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<NewCreateMagazineForm />
</div>
);

View File

@ -2,7 +2,7 @@ import EditMagazineForm from "@/components/form/magazine/edit-magazine-form";
export default function DetailArticlePage() {
return (
<div className="h-[96vh] bg-transparent p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<div className="h-[96vh] bg-transparent p-3 lg:p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<EditMagazineForm isDetail={true} />
</div>
);

View File

@ -2,7 +2,7 @@ import EditMagazineForm from "@/components/form/magazine/edit-magazine-form";
export default function EditArticlePage() {
return (
<div className="h-[96vh] bg-transparent p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<div className="h-[96vh] bg-transparent p-3 lg:p-8 !bg-slate-100 dark:!bg-black overflow-y-auto">
<EditMagazineForm isDetail={false} />
</div>
);

View File

@ -8,9 +8,12 @@ export default function MagazineTablePage() {
return (
<div className="overflow-x-hidden overflow-y-scroll">
<div className="px-2 md:px-4 md:py-4 w-full">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl py-3">
<Link href="/admin/magazine/create" className="mx-3">
<Button size="md" className="bg-[#F07C00] text-white">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl p-3">
<Link href="/admin/magazine/create">
<Button
size="md"
className="bg-[#F07C00] text-white w-full lg:w-fit"
>
Tambah Majalah
<AddIcon />
</Button>

View File

@ -164,10 +164,10 @@ export default function MasterCategoryTable() {
return (
<div className="overflow-x-hidden overflow-y-scroll">
<div className="px-2 md:px-4 md:py-4 w-full">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl py-3">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl p-3">
<Button
size="md"
className="bg-[#F07C00] text-white mx-3"
className="bg-[#F07C00] text-white w-full lg:w-fit"
onPress={onOpen}
>
Tambah Kategori

View File

@ -7,12 +7,12 @@ export default function StaticPageGeneratorList() {
return (
<div className="overflow-x-hidden overflow-y-scroll rounded-lg">
<div className="px-2 md:px-4 md:py-4 w-full">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl py-3">
<Link href="/admin/static-page/create" className="mx-3">
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl p-3">
<Link href="/admin/static-page/create">
<Button
size="md"
color="primary"
className="bg-[#F07C00] text-white"
className="bg-[#F07C00] text-white w-full lg:w-fit"
>
Tambah Halaman
<AddIcon />

View File

@ -1,6 +1,7 @@
"use client";
import PasswordForm from "@/components/form/settings/password";
import ProfileForm from "@/components/form/settings/profile";
import { close, loading } from "@/config/swal";
import { getProfile } from "@/service/master-user";
import { Tab, Tabs } from "@nextui-org/react";
import { useEffect, useState } from "react";
@ -11,11 +12,13 @@ export default function Settings() {
initFetch();
}, []);
const initFetch = async () => {
loading();
const profile = await getProfile();
setProfile(profile?.data?.data);
close();
};
return (
<div className="w-full lg:w-[60%] p-5">
<div className="w-full lg:w-[60%] p-3">
<div className="flex flex-col bg-gray-50 shadow-md dark:bg-stone-900 text-black dark:text-white rounded-md p-5">
<Tabs aria-label="Tabs radius" radius="sm">
<Tab key="profile" title="Profile">

View File

@ -410,10 +410,10 @@ export default function CreateArticleForm() {
return (
<form
className="flex flex-row gap-8 text-black"
className="flex flex-col lg:flex-row gap-8 text-black"
onSubmit={handleSubmit(onSubmit)}
>
<div className="w-[65%] bg-white rounded-lg p-8 flex flex-col gap-1">
<div className="w-full lg:w-[65%] bg-white rounded-lg p-8 flex flex-col gap-1">
<p className="text-sm">Judul</p>
<Controller
control={control}
@ -527,7 +527,7 @@ export default function CreateArticleForm() {
) : null}
</Fragment>
</div>
<div className="w-[35%] flex flex-col gap-8">
<div className="w-full lg:w-[35%] flex flex-col gap-8">
<div className="h-fit bg-white rounded-lg p-8 flex flex-col gap-1">
<p className="text-sm">Thubmnail</p>

View File

@ -372,10 +372,10 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
return (
<form
className="flex flex-row gap-8 text-black"
className="flex flex-col lg:flex-row gap-8 text-black"
onSubmit={handleSubmit(onSubmit)}
>
<div className="w-[65%] bg-white rounded-lg p-8 flex flex-col gap-1">
<div className="w-full lg:w-[65%] bg-white rounded-lg p-8 flex flex-col gap-1">
{isDetail && <GetSeoScore id={String(diseId)} />}
<p className="text-sm">Judul</p>
<Controller
@ -580,7 +580,7 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
</div>
)}
</div>
<div className="w-[35%] flex flex-col gap-8">
<div className="w-full lg:w-[35%] flex flex-col gap-8">
<div className="h-fit bg-white rounded-lg p-8 flex flex-col gap-1">
<p className="text-sm">Thubmnail</p>
{isDetail ? (

View File

@ -254,7 +254,7 @@ export default function NewCreateMagazineForm() {
<div className="flex gap-3 grow">
<div className="file-preview">{renderPreview(file)}</div>
<div className="flex flex-col gap-1 grow">
<div className="flex flex-col gap-1 grow w-[45vw] md:w-auto">
<p className="text-sm font-semibold">Nama File</p>
<div className="flex flex-row gap-2 items-center">
<p className=" text-sm text-card-foreground">{file.name}</p>
@ -446,7 +446,9 @@ export default function NewCreateMagazineForm() {
</div>
{files.length ? (
<Fragment>
<div className="grid grid-cols-2 gap-2">{fileList}</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2">
{fileList}
</div>
{files.length > 1 && (
<div className=" flex justify-between gap-2">
<Button onPress={() => setFiles([])} size="sm">

View File

@ -303,7 +303,7 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
<div className="flex gap-3 grow">
<div className="file-preview">{renderPreview(file)}</div>
<div className="flex flex-col gap-1 grow">
<div className="flex flex-col gap-1 grow w-[45vw] md:w-auto">
<p className="text-sm font-semibold">Nama File</p>
<div className="flex flex-row gap-2 items-center">
<p className=" text-sm text-card-foreground">{file.name}</p>
@ -557,7 +557,7 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-2">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2">
{files.length ? (
<Fragment>
{fileList}
@ -574,14 +574,14 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
{detailfiles?.map((file: any, index: number) => (
<div
key={file.fileName + index}
className=" flex justify-between border p-3 rounded-md"
className=" flex flex-row lg:justify-between border p-3 rounded-md grow"
>
<div className="flex gap-3 grow">
<div className="file-preview">
{renderPreview(file, file.fileName)}
</div>
<div className="flex flex-col gap-1 grow">
<div className="flex flex-col grow gap-1 w-[45vw] md:w-auto">
<p className="text-sm font-semibold">Nama File</p>
<div className="flex flex-row gap-2 items-center">
<p className=" text-sm text-card-foreground">
@ -644,7 +644,7 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
</div>
<Button
className=" border-none rounded-full"
className=" border-none rounded-full m-0 p-0"
variant="bordered"
color="danger"
onClick={() => handleDeleteFile(file?.id)}
@ -657,7 +657,7 @@ export default function EditMagazineForm(props: { isDetail: boolean }) {
</Fragment>
)}
{isDetail && (
<div className="grid grid-cols-2 gap-2">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2">
{detailfiles?.map((file: any, index: number) => (
<div
key={file.fileName + index}

View File

@ -100,6 +100,38 @@ export default function ProfileForm(props: {
return (
<form className="flex flex-col gap-3 " onSubmit={handleSubmit(onSubmit)}>
<div className="flex flex-col gap-1">
<p className="text-sm">Username</p>
<Controller
control={control}
name="username"
render={({ field: { onChange, value } }) => (
<Input
type="text"
id="username"
placeholder=""
label=""
isReadOnly
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.username && (
<p className="text-red-400 text-sm mb-3">
{errors.username?.message}
</p>
)}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm">Nama Lengkap</p>
<Controller
@ -131,37 +163,6 @@ export default function ProfileForm(props: {
</p>
)}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm">Username</p>
<Controller
control={control}
name="username"
render={({ field: { onChange, value } }) => (
<Input
type="text"
id="username"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.username && (
<p className="text-red-400 text-sm mb-3">
{errors.username?.message}
</p>
)}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm">Email</p>

View File

@ -2178,14 +2178,16 @@ export const TimesIcon = ({
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
width={size || width}
height={size || height}
viewBox="0 0 24 24"
stroke-width="1.5"
strokeWidth="1.5"
stroke="currentColor"
className="size-6"
{...props}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
strokeLinecap="round"
strokeLinejoin="round"
d="M6 18 18 6M6 6l12 12"
/>
</svg>
@ -2208,9 +2210,9 @@ export const CalendarIcon = ({
<path fill="currentColor" d="M4 7v2h16V7a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2" />
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M16 5h2a2 2 0 0 1 2 2v2H4V7a2 2 0 0 1 2-2h2m8 0V3m0 2H8m0-2v2M4 9.5V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9.5"
/>
</g>
@ -2350,3 +2352,25 @@ export const CloudUploadIcon = ({
/>
</svg>
);
export const BurgerButtonIcon = ({
size,
height = 24,
width = 24,
fill = "currentColor",
...props
}: IconSvgProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={size || width}
height={size || height}
{...props}
viewBox="0 0 16 16"
>
<path
fill="currentColor"
fillRule="evenodd"
d="M0 3.75A.75.75 0 0 1 .75 3h14.5a.75.75 0 0 1 0 1.5H.75A.75.75 0 0 1 0 3.75M0 8a.75.75 0 0 1 .75-.75h14.5a.75.75 0 0 1 0 1.5H.75A.75.75 0 0 1 0 8m.75 3.5a.75.75 0 0 0 0 1.5h14.5a.75.75 0 0 0 0-1.5z"
clipRule="evenodd"
/>
</svg>
);

View File

@ -71,7 +71,11 @@ export default function HeaderNews() {
<Card isFooterBlurred radius="lg" className="border-none">
<img
alt="headernews"
src={newsItem.thumbnailUrl}
src={
newsItem?.thumbnailUrl == ""
? "no-image.jpg"
: newsItem?.thumbnailUrl
}
className="h-[25vh] object-cover"
/>
@ -113,7 +117,9 @@ export default function HeaderNews() {
>
<img
alt="headernews"
src={data.thumbnailUrl}
src={
data?.thumbnailUrl == "" ? "no-image.jpg" : data?.thumbnailUrl
}
className="object-cover w-[18%] rounded-md"
/>
<div>
@ -193,7 +199,11 @@ export default function HeaderNews() {
>
<img
alt="headernews"
src={newsItem.thumbnailUrl}
src={
newsItem?.thumbnailUrl == ""
? "no-image.jpg"
: newsItem?.thumbnailUrl
}
className="w-full h-[67vh] object-cover rounded-lg"
/>

View File

@ -4,13 +4,14 @@ import { useEffect, useState } from "react";
import Sidebar from "./sidebar/sidebar";
import { SidebarProvider } from "./sidebar/sidebar-context";
import { Breadcrumb } from "../ui/breadcrumb";
import SidebarMobile from "./sidebar/sidebar-mobile";
interface Props {
children: React.ReactNode;
}
export const AdminLayout = ({ children }: Props) => {
const [isOpen, setIsOpen] = useState(true);
const [isOpen, setIsOpen] = useState(false);
const updateSidebarData = (newData: boolean) => {
setIsOpen(newData);
};
@ -29,6 +30,10 @@ export const AdminLayout = ({ children }: Props) => {
<SidebarProvider>
<div className="!h-screen flex items-center flex-row !overflow-y-hidden">
<Sidebar sidebarData={isOpen} updateSidebarData={updateSidebarData} />
<SidebarMobile
sidebarData={isOpen}
updateSidebarData={updateSidebarData}
/>
<div className={`w-full h-full flex flex-col overflow-hidden`}>
<Breadcrumb />
{children}

View File

@ -0,0 +1,481 @@
import { SidebarMenuTask } from "@/types/globals";
import { Tooltip } from "@nextui-org/react";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import React, { useEffect, useState } from "react";
import {
ChevronLeftIcon,
ChevronRightIcon,
FormCustomIcon,
FormHorizontalIcon,
FormLayoutIcon,
FormValidationIcon,
FormVerticalIcon,
} from "../../icons";
import {
ArticleIcon,
DashboardIcon,
HomeIcon,
InfoCircleIcon,
MagazineIcon,
MasterCategoryIcon,
MasterRoleIcon,
MasterUsersIcon,
MinusCircleIcon,
StaticPageIcon,
TableIcon,
} from "../../icons/sidebar-icon";
import { ThemeSwitch } from "../../theme-switch";
import { SidebarCollapseItems } from "./sidebar-collapse-items";
import { SidebarCollapseSubItems } from "./sidebar-collapse-sub-items";
import { useSidebar } from "./sidebar-context";
import { SidebarMenu } from "./sidebar-menu";
import Image from "next/image";
import Cookies from "js-cookie";
import { SettingsIcon, UserProfileIcon } from "@/components/icons/globals";
interface SubMenuItems {
id: number;
name: string;
modulePathUrl: string;
isSubActive: boolean;
}
interface MenuItems {
id: number;
name: string;
modulePathUrl: string;
isSubActive: boolean;
childMenu?: SubMenuItems[];
icon?: string;
}
interface SidebarProps {
sidebarData: boolean;
updateSidebarData: (newData: boolean) => void;
}
const sideBarDummyData = [
{
id: 1,
name: "Dashboard",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/dashboard",
isGroup: true,
parentId: -1,
icon: "dashboard",
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 2,
name: "Dashboard",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/dashboard",
parentId: -1,
icon: <DashboardIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 3,
name: "Apps",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/basic",
isGroup: true,
parentId: -1,
icon: "table",
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 4,
name: "Artikel",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/article",
parentId: -1,
icon: <ArticleIcon size={24} />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 30,
name: "Kategori",
moduleId: 654,
moduleName: "Master",
modulePathUrl: "/admin/master-category",
parentId: -1,
icon: <MasterCategoryIcon size={22} />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 4,
name: "Majalah",
moduleId: 652,
moduleName: "Apps",
modulePathUrl: "/admin/magazine",
parentId: -1,
icon: <MagazineIcon size={23} />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
// {
// id: 4,
// name: "E-Magazine",
// moduleId: 652,
// moduleName: "Dashboard",
// modulePathUrl: "/admin/e-magazine",
// parentId: -1,
// icon: <TableIcon />,
// position: 1,
// statusId: 1,
// childMenu: [],
// statusName: "Active",
// childModule: null,
// },
{
id: 5,
name: "Master",
moduleId: 652,
moduleName: "Dashboard",
isGroup: true,
modulePathUrl: "/admin/basic",
parentId: -1,
icon: "table",
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
// {
// id: 6,
// name: "Master Menu",
// moduleId: 652,
// moduleName: "Form Custom",
// modulePathUrl: "/admin/master-menu",
// parentId: -1,
// icon: <FormCustomIcon />,
// position: 1,
// statusId: 1,
// childMenu: [],
// statusName: "Active",
// childModule: null,
// },
// {
// id: 7,
// name: "Master Module",
// moduleId: 653,
// moduleName: "Form Horizontal",
// modulePathUrl: "/admin/master-module",
// parentId: -1,
// icon: <FormHorizontalIcon />,
// position: 1,
// statusId: 1,
// childMenu: [],
// statusName: "Active",
// childModule: null,
// },
{
id: 11,
name: "Master Static Page",
moduleId: 652,
moduleName: "Dashboard",
modulePathUrl: "/admin/static-page",
parentId: -1,
icon: <StaticPageIcon size={24} />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 8,
name: "Master User",
moduleId: 654,
moduleName: "Form Vertical",
modulePathUrl: "/admin/master-user",
parentId: -1,
icon: <MasterUsersIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
{
id: 10,
name: "Master User Role",
moduleId: 656,
moduleName: "Form Validation",
modulePathUrl: "/admin/master-role",
parentId: -1,
icon: <MasterRoleIcon />,
position: 1,
statusId: 1,
childMenu: [],
statusName: "Active",
childModule: null,
},
];
const SidebarMobile: 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 username = Cookies.get("username");
const isAuthenticated = Cookies.get("is_authenticated");
useEffect(() => {
if (!token) {
onLogout();
}
}, [token]);
const onLogout = () => {
Object.keys(Cookies.get()).forEach((cookieName) => {
Cookies.remove(cookieName);
});
router.push("/auth");
};
useEffect(() => {
updateSidebarData(isOpen);
}, [isOpen]);
return (
<div
className={`flex lg:hidden absolute h-screen flex-grow ${
isOpen ? "min-w-[240px]" : "hidden"
}`}
>
<div
className={` flex h-full flex-col p-4 mb-0 bg-gray-950 z-40 transition-width !ease-in-out justify-between ${
isOpen ? "w-[238px]" : "w-[80px]"
}`}
>
<div>
{!isOpen && (
<div className="w-full flex justify-center items-center">
<button
className="w-5 h-5 mb-3 text-zinc-400 dark:text-zinc-400 z-50 border-1 border-zinc-400 rounded-full flex justify-center items-center"
onClick={toggleSidebar}
>
<ChevronRightIcon />
</button>
</div>
)}
<div
className={`flex ${
isOpen ? "justify-between" : "justify-center"
} w-full items-center px-2`}
>
<Link
href="/"
className="flex flex-row items-center gap-3 font-bold"
>
<img src="/logohumas.png" className="w-20" />
{/* {isOpen && <span>ACME</span>} */}
</Link>
{isOpen && (
<button
className="w-5 h-5 text-zinc-400 z-50 border-1 border-zinc-400 rounded-full flex justify-center items-center"
onClick={toggleSidebar}
>
<ChevronLeftIcon />
</button>
)}
</div>
<SidebarMenu>
{sideBarDummyData
? sideBarDummyData?.map((list: any, index: number) =>
list.isGroup ? (
<p
key={list}
className={`font-bold mr-4 text-white ${
!isOpen ? "text-center" : ""
}`}
>
{isOpen ? list.name : "..."}
</p>
) : list.childMenu?.length < 1 ? (
<>
{isOpen ? (
<Link key={list.id} href={list.modulePathUrl}>
{/* <div
className={`px-3.5 py-2 mr-4 rounded-lg hover:bg-zinc-400 dark:hover:text-zinc-600 flex flex-row gap-2 ${
pathname.includes(list.modulePathUrl)
? "bg-zinc-600 dark:bg-zinc-300 text-zinc-300 dark:text-zinc-500 font-bold"
: "text-zinc-600 dark:text-zinc-400"
}`}
> */}
<div
className={`px-3.5 py-2 mr-4 rounded-lg flex flex-row gap-2 ${
pathname.includes(list.modulePathUrl)
? "bg-white text-black font-bold"
: "text-white hover:bg-gray-200 hover:text-black"
}`}
>
{list.icon} {isOpen && list.name}
</div>
</Link>
) : (
<Tooltip
content={list.name}
placement="right"
delay={0}
closeDelay={0}
>
<Link key={list.id} href={list.modulePathUrl}>
<div
className={`py-2 mr-4 rounded-lg hover:bg-zinc-400 dark:hover:text-zinc-600 flex flex-row justify-center gap-1 ${
pathname.includes(list.modulePathUrl)
? "bg-zinc-300 text-zinc-500 font-bold hover:text-black"
: "text-zinc-400 hover:text-black"
}`}
>
{list.icon} {isOpen && list.name}
</div>
</Link>
</Tooltip>
)}
</>
) : (
<SidebarCollapseItems
key={list.id}
title={list.name}
isActive={pathname.includes(list.modulePathUrl)}
icon={list.icon}
items={[
list?.childMenu?.map((item: any) => (
<SidebarCollapseSubItems
key={item.id}
title={item?.name}
isActive={pathname.includes(item.modulePathUrl)}
isParentActive={pathname.includes(
list.modulePathUrl
)}
path={item.modulePathUrl}
icon={item.icon}
/>
)),
]}
/>
)
)
: ""}
</SidebarMenu>
</div>
<div
className={`mt-12 p-2 flex ${
isOpen ? "justify-start ml-2" : "justify-center"
} mt-auto flex flex-col items-between`}
>
<div className="flex flex-col gap-4">
<div
className={`flex flex-row ${
isOpen ? "justify-start" : "justify-center"
} gap-2 items-center text-white `}
>
<ThemeSwitch />
{isOpen && "Theme"}
</div>
{isOpen ? (
<Link href="/settings">
<div
className={`py-2 mr-4 rounded-lg flex flex-row gap-2 ${
pathname.includes("/settings")
? "bg-white text-black font-bold px-2"
: "text-white "
}`}
>
<SettingsIcon /> {isOpen && "Settings"}
</div>
</Link>
) : (
<Tooltip
content="Setting"
placement="right"
delay={0}
closeDelay={0}
>
<Link href="/settings">
<div
className={`py-2 rounded-lg hover:text-zinc-600 flex flex-row justify-center gap-1 ${
pathname.includes("/settings")
? "bg-zinc-300 text-zinc-500 font-bold "
: "text-zinc-400 "
}`}
>
<SettingsIcon /> {isOpen && "Settings"}
</div>
</Link>
</Tooltip>
)}
{isOpen ? (
<div className="flex flex-row gap-3 items-center text-white">
<UserProfileIcon size={36} />
<div className="flex flex-col ">
<a className="cursor-pointer ">{username}</a>
<a
className="hover:text-red-600 underline text-sm cursor-pointer"
onClick={() => onLogout()}
>
Logout
</a>
</div>
</div>
) : (
<Tooltip
content="Profile"
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`}
onClick={toggleSidebar}
>
<UserProfileIcon size={28} />
</a>
</Tooltip>
)}
</div>
</div>
</div>
</div>
);
};
export default SidebarMobile;

View File

@ -90,10 +90,10 @@ export default function DashboardContainer() {
};
return (
<div className="p-8 flex justify-center">
<div className="px-2 lg:p-8 flex justify-center">
<div className="w-full flex flex-col gap-6">
<div className="w-full flex flex-col md:flex-row gap-6 justify-center">
<div className="px-8 py-4 justify-between w-full md:w-[37%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col rounded-lg">
<div className="w-full flex flex-col lg:flex-row gap-6 justify-center">
<div className="px-4 lg:px-8 py-4 justify-between w-full lg:w-[37%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col rounded-lg">
<div className="flex justify-between w-full items-center">
<div className="flex flex-col gap-2">
<p className="font-bold text-xl ">{fullname}</p>
@ -111,28 +111,28 @@ export default function DashboardContainer() {
</div>
</div>
<div className="w-full md:w-[20%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="lg:w-[20%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center">
<DashboardSpeecIcon />
</div>
<div className="">Total post</div>
<div className="font-semibold text-lg">121</div>
</div>
<div className="w-full md:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="w-full lg:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center">
<DashboardConnectIcon />
</div>
<div className="">Total views</div>
<div className="font-semibold text-lg">154</div>
</div>
<div className="w-full md:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="w-full lg:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center">
<DashboardShareIcon />
</div>
<div className="">Total share</div>
<div className="font-semibold text-lg">154</div>
</div>
<div className="w-full md:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="w-full lg:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
<div className="h-1/2 flex items-center justify-center">
<DashboardCommentIcon size={50} />
</div>
@ -140,17 +140,35 @@ export default function DashboardContainer() {
<div className="font-semibold text-lg">530</div>
</div>
</div>
<div className="w-full flex flex-row gap-6 justify-center ">
<div className="border-1 shadow-sm w-full rounded-lg md:w-[55%] p-6 flex flex-col">
<div className="w-full flex flex-col lg:flex-row gap-6 justify-center ">
<div className="border-1 shadow-sm w-screen rounded-lg lg:w-[55%] p-6 flex flex-col">
<div className="flex justify-between mb-3">
<div className="font-semibold flex flex-col">
Analytics
<div className="font-normal text-xs text-gray-600 flex flex-row gap-2">
<CheckboxGroup
label=""
value={analyticsView}
orientation="vertical"
onValueChange={setAnalyticView}
className="lg:hidden"
>
<Checkbox size="sm" value="visit">
Visit
</Checkbox>
<Checkbox size="sm" value="view" color="success">
View
</Checkbox>
<Checkbox size="sm" value="share" color="warning">
Share
</Checkbox>
</CheckboxGroup>
<CheckboxGroup
label=""
value={analyticsView}
orientation="horizontal"
onValueChange={setAnalyticView}
className="hidden lg:block"
>
<Checkbox size="sm" value="visit">
Visit
@ -164,11 +182,12 @@ export default function DashboardContainer() {
</CheckboxGroup>
</div>
</div>
<div className="flex flex-row gap-2">
<div className="flex flex-col lg:flex-row gap-2">
<Button
color="primary"
variant={typeDate === "monthly" ? "solid" : "bordered"}
onClick={() => setTypeDate("monthly")}
className="w-[140px] text-xs lg:text-sm h-[30px] lg:h-[40px] rounded-sm lg:rounded-lg"
>
Bulanan
</Button>
@ -176,23 +195,24 @@ export default function DashboardContainer() {
color="primary"
onClick={() => setTypeDate("weekly")}
variant={typeDate === "weekly" ? "solid" : "bordered"}
className="w-[140px] text-xs lg:text-sm h-[30px] lg:h-[40px] rounded-sm lg:rounded-lg"
>
Mingguan
</Button>
<div className="w-auto md:w-[140px]">
<div className="w-[140px]">
<Datepicker
value={startDateValue}
displayFormat="DD/MM/YYYY"
asSingle={true}
useRange={false}
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] text-gray-600 dark:text-gray-300"
inputClassName="z-50 w-full text-xs lg:text-sm bg-transparent border-1 border-gray-200 px-2 py-[6px] rounded-sm lg:rounded-lg h-[30px] lg:h-[40px] text-gray-600 dark:text-gray-300"
/>
</div>
</div>
</div>
<div className="flex flex-row w-full h-full">
<div className="w-full h-full">
<div className="w-full h-[30vh] lg:h-full text-black">
<ApexChartColumn
type={typeDate}
date={getMonthYear(startDateValue.startDate)}
@ -201,7 +221,7 @@ export default function DashboardContainer() {
</div>
</div>
</div>
<div className="flex flex-col w-[45%] gap-6 shadow-md bg-white dark:bg-[#18181b] rounded-lg p-8">
<div className="flex flex-col w-full lg:w-[45%] gap-6 shadow-md bg-white dark:bg-[#18181b] rounded-lg p-8">
<div className="flex justify-between">
<p>Recent Article</p>
<Link href="/admin/article/create">
@ -220,7 +240,7 @@ export default function DashboardContainer() {
className="h-[70px] w-[70px] object-cover rounded-lg"
/>
<div className="flex flex-col gap-2">
<p>{textEllipsis(list?.title, 40)}</p>
<p>{textEllipsis(list?.title, 58)}</p>
<p className="text-xs">
{convertDateFormat(list?.createdAt)}
</p>

View File

@ -6,6 +6,11 @@ import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { otpRequest, otpValidation } from "@/service/master-user";
import { error } from "@/config/swal";
import { UserProfileIcon } from "@/components/icons/globals";
import { convertDateFormat } from "@/utils/global";
import Cookies from "js-cookie";
const userId = Cookies.get("uie");
const commentSchema = z.object({
name: z.string().min(1, {
@ -24,6 +29,23 @@ const commentSchema = z.object({
}),
});
const dummyData = [
{
id: 1,
createdByName: "User 2",
comment: "test comment",
createdAt: "2025-01-30T00:09:39.352384Z",
createdById: 32,
},
{
id: 2,
createdByName: "User 2",
comment: "test comment 22",
createdAt: "2025-01-31T00:10:50.352384Z",
createdById: 23,
},
];
export default function Comment() {
const [needOtp, setNeedOtp] = useState(false);
const [otpValue, setOtpValue] = useState("");
@ -61,130 +83,159 @@ export default function Comment() {
}
};
return (
<form className="p-3 flex flex-col gap-3" onSubmit={handleSubmit(onSubmit)}>
<b>Tinggalkan balasan</b>
<p className="text-xs">
Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai{" "}
<span className="text-red-600">*</span>
</p>
<div className="flex flex-col gap-1">
<p className="text-sm">Komentar</p>
<Controller
control={control}
name="comment"
render={({ field: { onChange, value } }) => (
<Textarea
type="text"
id="comment"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.comment && (
<p className="text-red-400 text-sm mb-3">{errors.comment?.message}</p>
)}
<div className="py-5 px-8 flex flex-col gap-3">
<div className="flex flex-col gap-2 text-black">
{dummyData.map((list) => (
<div
key={list?.id}
className="flex justify-between items-center border-b-2 py-3 shadow-md px-4 rounded-md"
>
<div className="flex flex-row gap-2 ">
<UserProfileIcon size={44} />
<div className="flex flex-col gap-1">
<p className="text-sm font-semibold">{list.createdByName}</p>
<p className="text-sm">{list.comment}</p>
</div>
</div>
<div className="flex flex-col gap-1 text-right">
<p className="text-xs">{convertDateFormat(list.createdAt)}</p>
{(userId === String(list.createdById) || userId === "16") && (
<a className="text-danger cursor-pointer text-xs">Hapus</a>
)}
</div>
</div>
))}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm">
Nama <span className="text-red-600">*</span>
<form
className="py-3 px-4 flex flex-col gap-3 bg-gray-50 text-black dark:bg-stone-900 dark:text-white rounded-lg shadow-md"
onSubmit={handleSubmit(onSubmit)}
>
<b>Tinggalkan balasan</b>
<p className="text-xs">
Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai{" "}
<span className="text-red-600">*</span>
</p>
<Controller
control={control}
name="name"
render={({ field: { onChange, value } }) => (
<Input
type="text"
id="name"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.name && (
<p className="text-red-400 text-sm mb-3">{errors.name?.message}</p>
)}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm">
Email <span className="text-red-600">*</span>
</p>
<Controller
control={control}
name="email"
render={({ field: { onChange, value } }) => (
<Input
type="email"
id="email"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.email && (
<p className="text-red-400 text-sm mb-3">{errors.email?.message}</p>
)}
</div>
{needOtp && (
<div className="flex flex-col gap-1">
<p>OTP</p>
<Input
type="number"
id="otp"
placeholder=""
label=""
value={otpValue}
onValueChange={setOtpValue}
labelPlacement="outside"
className="w-[100px] "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
<p className="text-sm">Komentar</p>
<Controller
control={control}
name="comment"
render={({ field: { onChange, value } }) => (
<Textarea
type="text"
id="comment"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.comment && (
<p className="text-red-400 text-sm mb-3">
{errors.comment?.message}
</p>
)}
</div>
)}
<div className="flex flex-col gap-1">
<p className="text-sm">
Nama <span className="text-red-600">*</span>
</p>
<Button className="bg-[#DD8306] text-white" radius="md" type="submit">
Kirim
</Button>
</form>
<Controller
control={control}
name="name"
render={({ field: { onChange, value } }) => (
<Input
type="text"
id="name"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.name && (
<p className="text-red-400 text-sm mb-3">{errors.name?.message}</p>
)}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm">
Email <span className="text-red-600">*</span>
</p>
<Controller
control={control}
name="email"
render={({ field: { onChange, value } }) => (
<Input
type="email"
id="email"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.email && (
<p className="text-red-400 text-sm mb-3">{errors.email?.message}</p>
)}
</div>
{needOtp && (
<div className="flex flex-col gap-1">
<p>OTP</p>
<Input
type="number"
id="otp"
placeholder=""
label=""
value={otpValue}
onValueChange={setOtpValue}
labelPlacement="outside"
className="w-[100px] "
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
</div>
)}
<Button className="bg-[#DD8306] text-white" radius="md" type="submit">
Kirim
</Button>
</form>
</div>
);
}

View File

@ -7,7 +7,7 @@ import Comment from "./comment";
import { getArticleById, getListArticle } from "@/service/article";
import { useParams } from "next/navigation";
import Link from "next/link";
import { ChevronRightIcon } from "@/components/icons";
import { ChevronRightIcon, UserIcon } from "@/components/icons";
import { close, loading } from "@/config/swal";
export default function NewsDetailPage() {
@ -36,7 +36,7 @@ export default function NewsDetailPage() {
};
return (
<div className="bg-white">
<div className="px-5 lg:px-0 lg:w-[70vw] mx-auto py-8">
<div className="px-5 lg:px-0 lg:w-[75vw] lg:mx-auto py-8">
<div className="flex flex-row gap-4 items-end text-black">
<Link href="/" className=" font-semibold text-lg">
Beranda
@ -44,18 +44,18 @@ export default function NewsDetailPage() {
<ChevronRightIcon />
<p className=" text-lg">Berita</p>
</div>
<div className="text-black lg:flex bg-white gap-4">
<div className="text-black lg:flex lg:justify-around bg-white gap-4 lg:gap-16 w-full">
<DetailNews data={detailArticle} listArticle={articles} />
<div className="w-auto lg:w-[25%] hidden lg:block">
<SidebarDetail />
</div>
</div>
<div className="bg-gray-50 text-black dark:bg-stone-900 dark:text-white h-auto my-2 md:my-5 lg:my-10 px-3 lg:px-36 rounded-lg shadow-md">
<div className="w-[70%] h-auto my-2 md:my-5 lg:my-10 px-3">
<Comment />
</div>
<div className="bg-gray-50 text-black dark:bg-stone-900 dark:text-white lg:px-24 my-4 lg:my-8 pt-3 lg:pb-4 rounded-lg shadow-md h-fit">
<div className="bg-gray-50 text-black dark:bg-stone-900 dark:text-white lg:px-24 my-4 lg:my-8 pt-3 lg:pb-4 rounded-lg shadow-md h-fit ">
<RelatedNews />
</div>
<div className="md:hidden text-black">

View File

@ -23,11 +23,13 @@ import { Button } from "@nextui-org/button";
import { usePathname } from "next/navigation";
import Link from "next/link";
import { useEffect, useState } from "react";
import { image } from "@nextui-org/theme";
export default function DetailNews(props: { data: any; listArticle: any }) {
const { data, listArticle } = props;
const [prevArticle, setPrevArticle] = useState("");
const [nextArticle, setNextArticle] = useState("");
const [imageNow, setImageNow] = useState(0);
const pathname = usePathname();
const shareText = "Humas Polri";
@ -102,7 +104,7 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
return { __html: doc.body.innerHTML };
}
return (
<div className="flex flex-col gap-2 py-4">
<div className="flex flex-col gap-2 py-4 lg:w-[65%] lg:mx-auto">
<p className="font-semibold text-xl lg:text-3xl">{data?.title}</p>
<div className="flex flex-row items-center py-1 text-xs lg:text-lg gap-2 lg:gap-4">
<div className="flex flex-row items-center gap-1">
@ -135,34 +137,51 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
<div className="flex justify-center my-2 lg:my-5">
<img
alt="NextUI hero Image"
src={data?.thumbnailUrl}
className="object-cover w-[100%]"
src={`http://38.47.180.165:8802${data?.files[imageNow]?.file_url}`}
className="object-cover w-[100%] rounded-md"
/>
</div>
{data?.files?.length > 1 && (
<div className="flex flex-row gap-3 flex-nowrap overflow-x-auto">
{data?.files?.map((file: any, index: number) => (
<a
key={file.id}
onClick={() => setImageNow(index)}
className="cursor-pointer"
>
<img
alt="NextUI hero Image"
src={`http://38.47.180.165:8802${file?.file_url}`}
className="object-cover h-[50px] lg:h-[100px] rounded-md"
/>
</a>
))}
</div>
)}
<div
dangerouslySetInnerHTML={removeImgTags(
formatTextToHtmlTag(data?.htmlDescription)
)}
className="text-sm lg:text-xl lg:leading-8"
className="text-sm lg:text-xl lg:leading-8 text-justify"
/>
<div className="grid grid-cols-2 md:grid-cols-4 gap-5 my-8">
<div className="grid grid-cols-2 md:grid-cols-4 gap-2 lg:gap-5 my-8">
<Button
variant="solid"
radius="none"
onPress={() => handleShare("facebook")}
className="w-[80%] bg-[#3b5998] text-white px-4 py-2 flex flex-row"
className="lg:w-[80%] bg-[#3b5998] text-white px-4 py-2 flex flex-row"
>
<div className="w-1/4 ">
<SquareFacebookIcon />
</div>
<div className="w-3/4 text-xl ">Facebook</div>
<div className=" text-xl ">Facebook</div>
</Button>
<Button
variant="solid"
radius="none"
onPress={() => handleShare("x")}
className="w-[80%] bg-black text-white px-4 py-2 flex flex-row"
className="lg:w-[80%] bg-black text-white px-4 py-2 flex flex-row"
>
<div className="w-1/4 ">
<SquareXIcon />
@ -173,7 +192,7 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
variant="solid"
radius="none"
onPress={() => handleShare("linkedin")}
className="w-[80%] bg-[#0E76A8] text-white px-4 py-2 flex flex-row"
className="lg:w-[80%] bg-[#0E76A8] text-white px-4 py-2 flex flex-row"
>
<div className="w-1/4 ">
<SquareLinkedInIcon />
@ -184,7 +203,7 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
variant="solid"
radius="none"
onPress={() => handleShare("whatsapp")}
className="w-[80%] bg-[#25D366] text-white px-4 py-2 flex flex-row"
className="lg:w-[80%] bg-[#25D366] text-white px-4 py-2 flex flex-row"
>
<div className="w-1/4 ">
<SquareWhatsappIcon />

View File

@ -69,8 +69,12 @@ export default function RelatedNews() {
<Card isFooterBlurred radius="lg" className="border-none">
<img
alt="headernews"
src={newsItem.thumbnailUrl}
className="h-[25vh] object-cover rounded-none"
src={
newsItem?.thumbnailUrl == ""
? "/no-image.jpg"
: newsItem?.thumbnailUrl
}
className="!h-[25vh] object-cover rounded-none"
/>
<CardFooter className="before:bg-white/10 border-white/20 border-1 overflow-hidden py-1 md:absolute bottom-1 shadow-small z-10">
<div className="text-black dark:text-white lg:text-white">

View File

@ -56,7 +56,11 @@ export default function SidebarDetail() {
<div className="h-[230px] lg:h-[180px] flex flex-col gap-2 bg-gray-50 dark:bg-stone-900 p-5 rounded-lg">
<img
alt="headernews"
src={newsItem.thumbnailUrl}
src={
newsItem?.thumbnailUrl == ""
? "/no-image.jpg"
: newsItem?.thumbnailUrl
}
className="object-cover !h-[70%] rounded-lg"
/>
<div className="text-black dark:text-white flex flex-col">
@ -106,7 +110,11 @@ export default function SidebarDetail() {
<div className="h-[230px] lg:h-[180px] flex flex-col gap-2 bg-gray-50 dark:bg-stone-900 p-5 rounded-lg">
<img
alt="headernews"
src={newsItem.thumbnailUrl}
src={
newsItem?.thumbnailUrl == ""
? "/no-image.jpg"
: newsItem?.thumbnailUrl
}
className="object-cover !h-[70%] rounded-lg"
/>
<div className="text-black dark:text-white flex flex-col">

View File

@ -225,10 +225,10 @@ export default function ArticleTable() {
return (
<>
<div className="p-3">
<div className="py-3">
<div className="flex flex-col items-start rounded-2xl gap-3">
<div className="flex flex-col md:flex-row gap-3 w-full">
<div className="flex flex-col gap-1 w-1/3">
<div className="flex flex-col gap-1 w-full lg:w-1/3">
<p className="font-semibold text-sm">Pencarian</p>
<Input
aria-label="Search"
@ -246,7 +246,7 @@ export default function ArticleTable() {
onKeyDown={handleKeyDown}
/>
</div>
<div className="flex flex-col gap-1 w-[72px]">
<div className="flex flex-col gap-1 w-full lg:w-[72px]">
<p className="font-semibold text-sm">Data</p>
<Select
label=""
@ -268,7 +268,7 @@ export default function ArticleTable() {
</SelectItem>
</Select>
</div>
<div className="flex flex-col gap-1 w-[230px]">
<div className="flex flex-col gap-1 w-full lg:w-[230px]">
<p className="font-semibold text-sm">Kategori</p>
<Select
label=""
@ -293,7 +293,7 @@ export default function ArticleTable() {
))}
</Select>
</div>
<div className="flex flex-col gap-1 w-full md:w-[240px]">
<div className="flex flex-col gap-1 w-full lg:w-[240px]">
<p className="font-semibold text-sm">Tanggal</p>
<Datepicker
value={startDateValue}

View File

@ -226,10 +226,10 @@ export default function MagazineTable() {
return (
<>
<div className="p-3">
<div className="py-3">
<div className="flex flex-col items-start rounded-2xl gap-3">
<div className="flex flex-col md:flex-row gap-3 w-full">
<div className="flex flex-col gap-1 w-1/3">
<div className="flex flex-col gap-1 w-full lg:w-1/3">
<p className="font-semibold text-sm">Pencarian</p>
<Input
aria-label="Search"
@ -247,7 +247,7 @@ export default function MagazineTable() {
onKeyDown={handleKeyDown}
/>
</div>
<div className="flex flex-col gap-1 w-[72px]">
<div className="flex flex-col gap-1 w-full lg:w-[72px]">
<p className="font-semibold text-sm">Data</p>
<Select
label=""
@ -294,7 +294,7 @@ export default function MagazineTable() {
))}
</Select>
</div> */}
<div className="flex flex-col gap-1 w-full md:w-[240px]">
<div className="flex flex-col gap-1 w-full lg:w-[240px]">
<p className="font-semibold text-sm">Tanggal</p>
<Datepicker
value={startDateValue}

View File

@ -341,10 +341,10 @@ export default function CategoriesTable(props: { triggerRefresh: boolean }) {
return (
<>
<div className="p-3">
<div className="py-3">
<div className="flex flex-col items-start rounded-2xl gap-3">
<div className="flex flex-col md:flex-row gap-3 w-full">
<div className="flex flex-col gap-1 w-1/3">
<div className="flex flex-col gap-1 w-full lg:w-1/3">
<p className="font-semibold text-sm">Pencarian</p>
<Input
aria-label="Search"
@ -362,7 +362,7 @@ export default function CategoriesTable(props: { triggerRefresh: boolean }) {
onKeyDown={handleKeyDown}
/>
</div>
<div className="flex flex-col gap-1 w-[72px]">
<div className="flex flex-col gap-1 w-full lg:w-[72px]">
<p className="font-semibold text-sm">Data</p>
<Select
label=""
@ -523,7 +523,7 @@ export default function CategoriesTable(props: { triggerRefresh: boolean }) {
onValueChange={setTag}
startContent={
<div className="flex flex-row gap-1">
{value.map((item, index) => (
{value?.map((item, index) => (
<Chip
color="primary"
key={index}

View File

@ -200,10 +200,10 @@ export default function StaticPageTable() {
return (
<>
<div className="p-3">
<div className="py-3">
<div className="flex flex-col items-start rounded-2xl gap-3">
<div className="flex flex-col md:flex-row gap-3 w-full">
<div className="flex flex-col gap-1 w-1/3">
<div className="flex flex-col gap-1 w-full lg:w-1/3">
<p className="font-semibold text-sm">Pencarian</p>
<Input
aria-label="Pencarian..."
@ -221,7 +221,7 @@ export default function StaticPageTable() {
onKeyDown={handleKeyDown}
/>
</div>
<div className="flex flex-col gap-1 w-[72px]">
<div className="flex flex-col gap-1 w-full lg:w-[72px]">
<p className="font-semibold text-sm">Data</p>
<Select
label=""
@ -243,7 +243,7 @@ export default function StaticPageTable() {
</Select>
</div>
<div className="flex flex-col gap-1 w-full md:w-[340px]">
<div className="flex flex-col gap-1 w-full lg:w-[340px]">
<p className="font-semibold text-sm">Tanggal</p>
<Datepicker
value={startDateValue}

View File

@ -5,7 +5,7 @@ import { Button } from "@nextui-org/button";
import { BreadcrumbItem, Breadcrumbs } from "@nextui-org/react";
import { usePathname, useRouter } from "next/navigation";
import { Image } from "@nextui-org/react";
import { FormLayoutIcon } from "../icons";
import { BurgerButtonIcon, FormLayoutIcon } from "../icons";
import {
ArticleIcon,
DashboardIcon,
@ -13,14 +13,18 @@ import {
MasterCategoryIcon,
MasterRoleIcon,
MasterUsersIcon,
MenuBurgerIcon,
StaticPageIcon,
} from "../icons/sidebar-icon";
import { useSidebar } from "../layout/sidebar/sidebar-context";
export const Breadcrumb = () => {
const [currentPage, setCurrentPage] = useState<React.Key>("");
const router = useRouter();
const pathname = usePathname();
const pathnameSplit = pathname.split("/");
const { isOpen, toggleSidebar } = useSidebar();
pathnameSplit.shift();
let pathnameTransformed = pathnameSplit.map((item) => {
let words = item.split("-");
@ -67,16 +71,28 @@ export const Breadcrumb = () => {
)}
</Breadcrumbs>
</div>
{pathname.includes("dashboard") && <DashboardIcon size={50} />}
{pathname.includes("article") && <ArticleIcon size={50} />}
{pathname.includes("master-category") && (
<MasterCategoryIcon size={50} />
)}
{pathname.includes("magazine") && <MagazineIcon size={50} />}
{pathname.includes("static-page") && <StaticPageIcon size={50} />}
{pathname.includes("master-user") && <MasterUsersIcon size={50} />}
{pathname.includes("master-role") && <MasterRoleIcon size={50} />}
{/* <FormLayoutIcon width={50} height={50} /> */}
<div className="lg:hidden">
{!isOpen && (
<button
className="w-5 h-5 mb-3 text-zinc-400 dark:text-zinc-400 z-50 flex justify-center items-center"
onClick={toggleSidebar}
>
<BurgerButtonIcon />
</button>
)}
</div>
<div className="hidden lg:block">
{pathname.includes("dashboard") && <DashboardIcon size={50} />}
{pathname.includes("article") && <ArticleIcon size={50} />}
{pathname.includes("master-category") && (
<MasterCategoryIcon size={50} />
)}
{pathname.includes("magazine") && <MagazineIcon size={50} />}
{pathname.includes("static-page") && <StaticPageIcon size={50} />}
{pathname.includes("master-user") && <MasterUsersIcon size={50} />}
{pathname.includes("master-role") && <MasterRoleIcon size={50} />}
{/* <FormLayoutIcon width={50} height={50} /> */}
</div>
</div>
</div>
</div>