[QUDO-235,237]:feat:ember tawkto, ui improve dashboard stats
This commit is contained in:
parent
c3e33351b1
commit
64c42f8934
|
|
@ -9,6 +9,7 @@ import { Metadata } from "next";
|
|||
import { Providers } from "./providers";
|
||||
import LoadScript from "@/utils/global";
|
||||
import { type ReactNode } from "react";
|
||||
import LoadTawk from "@/components/ui/tawkto/load-tawk";
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
|
|
@ -56,6 +57,7 @@ export default function RootLayout({ children }: { children: ReactNode }) {
|
|||
<Providers themeProps={{ attribute: "class", defaultTheme: "light" }}>
|
||||
<main className="">{children}</main>
|
||||
</Providers>
|
||||
<LoadTawk />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,12 @@ import {
|
|||
Calendar,
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
CheckboxIcon,
|
||||
Image,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
Pagination,
|
||||
Popover,
|
||||
PopoverContent,
|
||||
|
|
@ -24,13 +29,14 @@ import {
|
|||
SelectItem,
|
||||
SelectSection,
|
||||
Skeleton,
|
||||
useDisclosure,
|
||||
} from "@heroui/react";
|
||||
import ApexChartColumn from "./chart/column-chart";
|
||||
import ApexChartDonut from "./chart/donut-chart";
|
||||
import ApexChartLineArea from "./chart/line-area-chart";
|
||||
import Cookies from "js-cookie";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import {
|
||||
getListArticle,
|
||||
getListArticleAdminPage,
|
||||
|
|
@ -46,6 +52,7 @@ import {
|
|||
textEllipsis,
|
||||
} from "@/utils/global";
|
||||
import { parseDate, getLocalTimeZone } from "@internationalized/date";
|
||||
import { Input } from "@heroui/input";
|
||||
|
||||
type ArticleData = Article & {
|
||||
no: number;
|
||||
|
|
@ -67,6 +74,8 @@ interface PostCount {
|
|||
}
|
||||
|
||||
export default function DashboardContainer() {
|
||||
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||
|
||||
const username = Cookies.get("username");
|
||||
const fullname = Cookies.get("ufne");
|
||||
const [page, setPage] = useState(1);
|
||||
|
|
@ -74,6 +83,7 @@ export default function DashboardContainer() {
|
|||
const [topPagespage, setTopPagesPage] = useState(1);
|
||||
const [topPagesTotalPage, setTopPagesTotalPage] = useState(1);
|
||||
const [article, setArticle] = useState<ArticleData[]>([]);
|
||||
const [selectedCategory, setSelectedCategory] = useState("polda");
|
||||
const [analyticsView, setAnalyticView] = useState<string[]>([
|
||||
"comment",
|
||||
"view",
|
||||
|
|
@ -108,7 +118,9 @@ export default function DashboardContainer() {
|
|||
const [postCount, setPostCount] = useState<PostCount[]>([]);
|
||||
const [polresData, setPolresData] = useState<any>({});
|
||||
const [selectedAccordion, setSelectedAccordion] = useState<any>(new Set([]));
|
||||
|
||||
const [recapArticleList, setRecapArticleList] = useState<any>([]);
|
||||
const [timeValue, setTimeValue] = useState("--:--");
|
||||
const [selectedUnit, setSelectedUnit] = useState("");
|
||||
const roleId = Cookies.get("urie");
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -281,6 +293,21 @@ export default function DashboardContainer() {
|
|||
}
|
||||
};
|
||||
|
||||
const openModalArticle = async (limit: number) => {
|
||||
const req = {
|
||||
limit: `${limit}`,
|
||||
page: topPagespage,
|
||||
search: "",
|
||||
sort: "desc",
|
||||
startDate: getDate(topContentDate.startDate),
|
||||
endDate: getDate(topContentDate.endDate),
|
||||
};
|
||||
const res = await getTopArticles(req);
|
||||
setRecapArticleList(getTableNumber(10, res.data?.data));
|
||||
// setTopPagesTotalPage(res?.data?.meta?.totalPage);
|
||||
onOpen();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="px-2 lg:p-8 flex justify-center">
|
||||
<div className="w-full flex flex-col gap-6">
|
||||
|
|
@ -342,7 +369,7 @@ export default function DashboardContainer() {
|
|||
<p className="font-semibold">
|
||||
Rekapitulasi Post Berita Polda/Polres Pada Website
|
||||
</p>
|
||||
<div className="w-[220px] flex flex-row gap-2 justify-between font-semibold">
|
||||
<div className="w-[300px] flex flex-row gap-2 justify-between font-semibold items-center">
|
||||
<Popover
|
||||
placement="bottom"
|
||||
classNames={{ content: ["!bg-transparent", "p-0"] }}
|
||||
|
|
@ -388,11 +415,54 @@ export default function DashboardContainer() {
|
|||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<Input
|
||||
type="time"
|
||||
variant="bordered"
|
||||
className="w-fit "
|
||||
value={timeValue}
|
||||
onValueChange={setTimeValue}
|
||||
endContent={
|
||||
<a>
|
||||
<CheckboxIcon />
|
||||
</a>
|
||||
}
|
||||
classNames={{
|
||||
inputWrapper: [
|
||||
"border-none rounded-lg !h-[30px] lg:h-[40px]",
|
||||
"dark:group-data-[focused=false]:bg-transparent border-none",
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row border-b-1 gap-1 py-1">
|
||||
<div className="flex flex-row border-b-1 gap-1 py-1 items-center">
|
||||
<div className="w-[5%]">NO</div>
|
||||
<div className="w-[50%] lg:w-[70%]">POLDA/POLRES</div>
|
||||
<div className="w-[50%] lg:w-[70%]">
|
||||
{Number(roleId) < 3 ? (
|
||||
<Select
|
||||
variant="underlined"
|
||||
className="max-w-xs border-none"
|
||||
label=""
|
||||
selectedKeys={[selectedCategory]}
|
||||
classNames={{
|
||||
innerWrapper: "!border-none",
|
||||
mainWrapper: "!border-none",
|
||||
trigger: "border-none",
|
||||
}}
|
||||
onChange={(e) =>
|
||||
e.target.value !== ""
|
||||
? setSelectedCategory(e.target.value)
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<SelectItem key="polda">POLDA</SelectItem>
|
||||
<SelectItem key="polres">POLRES</SelectItem>
|
||||
<SelectItem key="satker">SATKER MABES</SelectItem>
|
||||
</Select>
|
||||
) : (
|
||||
"POLDA/POLRES"
|
||||
)}
|
||||
</div>
|
||||
<div className="w-[45%] lg:w-[25%] text-right">
|
||||
JUMLAH POST BERITA
|
||||
</div>
|
||||
|
|
@ -417,9 +487,9 @@ export default function DashboardContainer() {
|
|||
<div className="w-[5%]">{list?.no}</div>
|
||||
<div className="w-[85%]">{list?.userLevelName}</div>
|
||||
<div
|
||||
className={`w-[10%] text-center ${
|
||||
className={`w-[10%] text-center ${
|
||||
list?.totalArticle === 0 &&
|
||||
"bg-red-600 text-white"
|
||||
"bg-red-600 text-white "
|
||||
}`}
|
||||
>
|
||||
{list?.totalArticle}
|
||||
|
|
@ -443,14 +513,20 @@ export default function DashboardContainer() {
|
|||
<div className="w-[85%]">
|
||||
{child?.userLevelName}
|
||||
</div>
|
||||
<div
|
||||
className={`w-[10%] text-start ${
|
||||
<a
|
||||
onClick={() => {
|
||||
if (list?.totalArticle !== 0) {
|
||||
setSelectedUnit(child?.userLevelName);
|
||||
openModalArticle(list?.totalArticle);
|
||||
}
|
||||
}}
|
||||
className={`w-[10%] text-start cursor-pointer ${
|
||||
list?.totalArticle === 0 &&
|
||||
"bg-red-600 text-white"
|
||||
"bg-red-600 text-white cursor-default"
|
||||
}`}
|
||||
>
|
||||
{child?.totalArticle}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
|
|
@ -705,6 +781,44 @@ export default function DashboardContainer() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange} size="3xl">
|
||||
<ModalContent>
|
||||
{(onClose) => (
|
||||
<>
|
||||
<ModalHeader className="flex flex-col gap-1">
|
||||
{selectedUnit} List Content
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<div className="grid grid-cols-12 text-xs ">
|
||||
<div className="col-span-1 font-bold">No</div>
|
||||
<div className="col-span-9 text-center font-bold">Judul</div>
|
||||
<div className="col-span-2 font-bold ">Dibuat</div>
|
||||
<div className="col-span-12 grid grid-cols-12 max-h-[480px] overflow-auto">
|
||||
{recapArticleList?.length > 0 &&
|
||||
recapArticleList?.map((list: any) => (
|
||||
<Fragment key={list.id}>
|
||||
<div className="col-span-1 my-2">{list.no}</div>
|
||||
<div className="col-span-9 my-2">
|
||||
<Link
|
||||
href={`/news/detail/${list.id}-${list.slug}`}
|
||||
target="_blank"
|
||||
className="hover:underline hover:text-primary"
|
||||
>
|
||||
{textEllipsis(list.title, 80)}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="my-2 col-span-2">
|
||||
{convertDateFormat(list?.createdAt)}
|
||||
</div>
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</ModalBody>
|
||||
</>
|
||||
)}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,29 +153,33 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
|
|||
</p>
|
||||
</div>
|
||||
<div className="flex justify-center my-2 lg:my-5">
|
||||
{data.files[0].file_name.split(".")[1].includes("doc") ||
|
||||
data.files[0].file_name.split(".")[1].includes("pdf") ? (
|
||||
<Image
|
||||
classNames={{
|
||||
wrapper: "!w-full !max-w-full",
|
||||
img: "!w-full",
|
||||
}}
|
||||
alt="Main Image"
|
||||
src={data.thumbnailUrl}
|
||||
className="object-cover w-[100%] rounded-md"
|
||||
/>
|
||||
) : (
|
||||
data?.files?.length > 0 && (
|
||||
{data?.files ? (
|
||||
data?.files[0]?.file_name.split(".")[1].includes("doc") ||
|
||||
data?.files[0]?.file_name.split(".")[1].includes("pdf") ? (
|
||||
<Image
|
||||
// classNames={{
|
||||
// wrapper: "!w-full !max-w-full",
|
||||
// img: "!w-full",
|
||||
// }}
|
||||
classNames={{
|
||||
wrapper: "!w-full !max-w-full",
|
||||
img: "!w-full",
|
||||
}}
|
||||
alt="Main Image"
|
||||
src={data?.files[imageNow]?.file_url}
|
||||
className="object-cover w-auto h-[360px] md:h-[480px] mx-auto rounded-md"
|
||||
src={data.thumbnailUrl}
|
||||
className="object-cover w-[100%] rounded-md"
|
||||
/>
|
||||
) : (
|
||||
data?.files?.length > 0 && (
|
||||
<Image
|
||||
// classNames={{
|
||||
// wrapper: "!w-full !max-w-full",
|
||||
// img: "!w-full",
|
||||
// }}
|
||||
alt="Main Image"
|
||||
src={data?.files[imageNow]?.file_url}
|
||||
className="object-cover w-auto h-[360px] md:h-[480px] mx-auto rounded-md"
|
||||
/>
|
||||
)
|
||||
)
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
{data?.files?.length > 0 &&
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
"use client";
|
||||
import { useEffect } from "react";
|
||||
|
||||
const LoadTawk = () => {
|
||||
useEffect(() => {
|
||||
const script = document.createElement("script");
|
||||
script.src = "https://embed.tawk.to/5d43069be5ae967ef80df561/default";
|
||||
script.async = true;
|
||||
script.charset = "UTF-8";
|
||||
script.setAttribute("crossorigin", "*");
|
||||
|
||||
document.body.appendChild(script);
|
||||
|
||||
return () => {
|
||||
document.body.removeChild(script);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default LoadTawk;
|
||||
Loading…
Reference in New Issue