feat:koorkurator dashboard

This commit is contained in:
Rama Priyanto 2024-12-13 01:38:15 +07:00
parent f20a26cf07
commit c2f0d44ac1
19 changed files with 421 additions and 109 deletions

View File

@ -185,7 +185,7 @@ const ContestTable = () => {
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 6,
pageSize: 2,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
@ -219,6 +219,7 @@ const ContestTable = () => {
async function initState() {
try {
const res = await listContest(limit, page);
console.log("res", res?.data?.data);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
hastagCode: item.hastagCode,

View File

@ -1,3 +1,4 @@
"use client";
import { StatisticsBlock } from "@/components/blocks/statistics-block";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import DashboardDropdown from "@/components/dashboard-dropdown";
@ -10,10 +11,22 @@ import CompanyTable from "./routine-task/routine-task-table";
import TaskTable from "../task/components/task-table";
import PressConferenceTable from "../schedule/press-release/components/pressrilis-table";
import BlogTable from "../blog/components/blog-table";
import Cookies from "js-cookie";
import { useEffect } from "react";
import { getCookiesDecrypt } from "@/lib/utils";
import DashboardVisualization from "@/components/visualization/dashboard-viz";
const DashboardPage = () => {
const t = useTranslations("AnalyticsDashboard");
return (
const roleId = getCookiesDecrypt("urie");
return Number(roleId) == 2 || Number(roleId) == 11 || Number(roleId) == 12 ? (
<div>
<div className="my-3">
<DashboardVisualization />
</div>
</div>
) : (
<div>
<div className="my-3">
<Tabs defaultValue="routine-task" className="w-full">

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/Footer";
import Navbar from "@/components/landing-page/Navbar";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/Navbar";
import Footer from "@/components/landing-page/Footer";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/Footer";
import Navbar from "@/components/landing-page/Navbar";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/Navbar";
import Footer from "@/components/landing-page/Footer";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/Navbar";
import Footer from "@/components/landing-page/Footer";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/Footer";
import Navbar from "@/components/landing-page/Navbar";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/Footer";
import Navbar from "@/components/landing-page/Navbar";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/Footer";
import Navbar from "@/components/landing-page/Navbar";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -6,8 +6,8 @@ import ThemeCustomize from "@/components/partials/customizer";
import DashCodeHeader from "@/components/partials/header";
import { auth } from "@/lib/auth";
import { redirect } from "@/components/navigation";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/navbar";
import Footer from "@/components/landing-page/Footer";
import Navbar from "@/components/landing-page/Navbar";
const layout = async ({ children }: { children: React.ReactNode }) => {
return (

View File

@ -5,10 +5,10 @@ import NewContent from "@/components/landing-page/new-content";
import PopularContent from "@/components/landing-page/popular-content";
import ContentCategory from "@/components/landing-page/content-category";
import Coverage from "@/components/landing-page/coverage";
import Hero from "@/components/landing-page/hero";
import Footer from "@/components/landing-page/footer";
import Hero from "@/components/landing-page/Hero";
import Footer from "@/components/landing-page/Footer";
import Division from "@/components/landing-page/division";
import Navbar from "@/components/landing-page/navbar";
import Navbar from "@/components/landing-page/Navbar";
const Home = ({ params: { locale } }: { params: { locale: string } }) => {
return (

View File

@ -1,8 +1,8 @@
"use client";
import React from "react";
import React, { useEffect } from "react";
import DateRangePicker from "@/components/date-range-picker";
import { usePathname } from "@/components/navigation";
import { cn } from "@/lib/utils";
import { cn, getCookiesDecrypt } from "@/lib/utils";
const PageTitle = ({
title,
@ -13,8 +13,14 @@ const PageTitle = ({
}) => {
const pathname = usePathname();
const name = pathname?.split("/").slice(1).join(" ");
const roleId = getCookiesDecrypt("urie");
return (
useEffect(() => {
console.log("role", roleId);
}, [roleId]);
return Number(roleId) == 2 || Number(roleId) == 11 || Number(roleId) == 12 ? (
""
) : (
<div
className={cn(
"flex flex-wrap gap-4 items-center justify-between",

View File

@ -1,76 +1,65 @@
import React from 'react'
import FooterContent from './footer-content'
import { Link } from "@/components/navigation"
import Image from 'next/image'
import React from "react";
import FooterContent from "./footer-content";
import { Link } from "@/components/navigation";
import Image from "next/image";
import { Icon } from "@/components/ui/icon";
import { auth } from '@/lib/auth'
import { auth } from "@/lib/auth";
import Cookies from "js-cookie";
const DashCodeFooter = async () => {
const session = await auth()
return (
<FooterContent>
<div className=' md:flex justify-between text-default-600 hidden'>
<div className="text-center ltr:md:text-start rtl:md:text-right text-sm">
</div>
<div className="ltr:md:text-right rtl:md:text-end text-center text-sm">
COPYRIGHT &copy; {new Date().getFullYear()} Media Hub, All rights Reserved
</div>
</div>
<div className='flex md:hidden justify-around items-center'>
<Link href="/app/chat" className="text-default-600">
<div>
<span
className="relative cursor-pointer rounded-full text-[20px] flex flex-col items-center justify-center mb-1"
>
<Icon icon="heroicons-outline:mail" />
<span className="absolute right-[5px] lg:top-0 -top-2 h-4 w-4 bg-red-500 text-[8px] font-semibold flex flex-col items-center justify-center rounded-full text-white z-[99]">
10
</span>
</span>
<span
className="block text-xs text-default-600"
>
Messages
</span>
</div>
</Link>
<Link
href="profile"
className="relative bg-card bg-no-repeat backdrop-filter backdrop-blur-[40px] rounded-full footer-bg dark:bg-default-300 h-[65px] w-[65px] z-[-1] -mt-[40px] flex justify-center items-center"
>
<div className="h-[50px] w-[50px] rounded-full relative left-[0px] top-[0px] custom-dropshadow">
<Image
src={session?.user?.image as string}
alt={session?.user?.name?.charAt(0) as string}
width={50}
height={50}
className="w-full h-full rounded-full border-2"
const DashCodeFooter = () => {
const username = Cookies.get("state");
const picture = Cookies.get("profile_picture");
return (
<FooterContent>
<div className=" md:flex justify-between text-default-600 hidden">
<div className="text-center ltr:md:text-start rtl:md:text-right text-sm"></div>
<div className="ltr:md:text-right rtl:md:text-end text-center text-sm">
COPYRIGHT &copy; {new Date().getFullYear()} Media Hub, All rights
Reserved
</div>
</div>
<div className="flex md:hidden justify-around items-center">
<Link href="/app/chat" className="text-default-600">
<div>
<span className="relative cursor-pointer rounded-full text-[20px] flex flex-col items-center justify-center mb-1">
<Icon icon="heroicons-outline:mail" />
<span className="absolute right-[5px] lg:top-0 -top-2 h-4 w-4 bg-red-500 text-[8px] font-semibold flex flex-col items-center justify-center rounded-full text-white z-[99]">
10
</span>
</span>
<span className="block text-xs text-default-600">Messages</span>
</div>
</Link>
<Link
href="profile"
className="relative bg-card bg-no-repeat backdrop-filter backdrop-blur-[40px] rounded-full footer-bg dark:bg-default-300 h-[65px] w-[65px] z-[-1] -mt-[40px] flex justify-center items-center"
>
<div className="h-[50px] w-[50px] rounded-full relative left-[0px] top-[0px] custom-dropshadow">
<Image
src={picture as string}
alt={username as string}
width={50}
height={50}
className="w-full h-full rounded-full border-2"
/>
</div>
</Link>
<Link href="notifications">
<div>
<span className="relative cursor-pointer rounded-full text-[20px] flex flex-col items-center justify-center mb-1">
<Icon icon="heroicons-outline:bell" />
<span className="absolute right-[17px] lg:top-0 -top-2 h-4 w-4 bg-red-500 text-[8px] font-semibold flex flex-col items-center justify-center rounded-full text-white z-[99]">
2
</span>
</span>
<span className="block text-xs text-default-600">
Notifications
</span>
</div>
</Link>
</div>
</FooterContent>
);
};
/>
</div>
</Link>
<Link href="notifications">
<div>
<span
className="relative cursor-pointer rounded-full text-[20px] flex flex-col items-center justify-center mb-1"
>
<Icon icon="heroicons-outline:bell" />
<span className="absolute right-[17px] lg:top-0 -top-2 h-4 w-4 bg-red-500 text-[8px] font-semibold flex flex-col items-center justify-center rounded-full text-white z-[99]">
2
</span>
</span>
<span
className="block text-xs text-default-600"
>
Notifications
</span>
</div>
</Link>
</div>
</FooterContent>
)
}
export default DashCodeFooter
export default DashCodeFooter;

View File

@ -12,7 +12,7 @@ import HorizontalMenu from "./horizontal-menu";
import LocalSwitcher from "./locale-switcher";
import HeaderLogo from "./header-logo";
const DashCodeHeader = async () => {
const DashCodeHeader = () => {
return (
<>
<HeaderContent>

View File

@ -1,3 +1,4 @@
"use client";
import {
DropdownMenu,
DropdownMenuContent,
@ -16,9 +17,15 @@ import { signOut, auth } from "@/lib/auth";
import Image from "next/image";
import { Link } from "@/i18n/routing";
import { Button } from "@/components/ui/button";
import Cookies from "js-cookie";
import { useEffect } from "react";
const ProfileInfo = async () => {
const session = await auth();
const ProfileInfo = () => {
const username = Cookies.get("state");
const picture = Cookies.get("profile_picture");
useEffect(() => {
console.log("us", username);
}, [username]);
return (
<div className="md:block hidden">
@ -26,15 +33,15 @@ const ProfileInfo = async () => {
<DropdownMenuTrigger asChild className=" cursor-pointer">
<div className=" flex items-center gap-3 text-default-800 ">
<Image
src={session?.user?.image as string}
alt={session?.user?.name?.charAt(0) as string}
src={"/images/avatar/icon-avatar-1.png"}
alt={username as string}
width={36}
height={36}
className="rounded-full"
/>
<div className="text-sm font-medium capitalize lg:block hidden ">
{session?.user?.name}
{username}
</div>
<span className="text-base me-2.5 lg:inline-block hidden">
<Icon icon="heroicons-outline:chevron-down"></Icon>
@ -44,8 +51,8 @@ const ProfileInfo = async () => {
<DropdownMenuContent className="w-56 p-0" align="end">
<DropdownMenuLabel className="flex gap-2 items-center mb-1 p-3">
<Image
src={session?.user?.image as string}
alt={session?.user?.name?.charAt(0) as string}
src={"/images/avatar/icon-avatar-1.png"}
alt={username as string}
width={36}
height={36}
className="rounded-full"
@ -53,13 +60,13 @@ const ProfileInfo = async () => {
<div>
<div className="text-sm font-medium text-default-800 capitalize ">
{session?.user?.name}
{username}
</div>
<Link
href="/dashboard"
className="text-xs text-default-600 hover:text-primary"
>
{session?.user?.email}
{username}
</Link>
</div>
</DropdownMenuLabel>

View File

@ -0,0 +1,245 @@
import Cookies from "js-cookie";
import { useEffect, useState } from "react";
import { getCookiesDecrypt } from "@/lib/utils";
import { generateTicket } from "@/service/tableau/tableau-service";
import { Button } from "../ui/button";
export default function DashboardVisualization() {
const levelName = getCookiesDecrypt("ulnae");
const poldaState = Cookies.get("state");
const [ticket1, setTicket1] = useState("");
const [ticket2, setTicket2] = useState("");
const [ticket3, setTicket3] = useState("");
const [isInternational, setIsInternational] = useState([false, false, false]);
const baseUrl = "https://analytic.sitani.info/";
const url = "https://analytic.sitani.info/trusted/";
const view1 =
levelName == "MABES POLRI"
? isInternational[0]
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-content-monitor?"
: "views/2023_09_MediaHUB-Viz-POLDA-content-monitor_Rev100/db-content-monitor?"
: `views/2023_09_MediaHUB-Viz-ADMIN-POLDA-content-monitor_Rev100/db-content-monitor?provinsi-polda=${poldaState}&`;
const view2 =
levelName == "MABES POLRI"
? isInternational[1]
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-content-interaction-konten?"
: "views/2023_04_MediaHUB-Viz-POLDA_Rev201/db-content-interaction-konten?"
: `views/2023_04_MediaHUB-Viz-POLDA_Rev201/db-content-interaction-konten-polda?provinsi-polda=${poldaState}&`;
const view3 =
levelName == "MABES POLRI"
? isInternational[2]
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-penugasan?"
: "views/2023_09_db-penugasan_rev100/db-penugasan?"
: `views/2023_04_MediaHUB-Viz-POLDA_Rev201/db-penugasan-polda?provinsi-polda=${poldaState}&`;
const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true";
useEffect(() => {
async function initState() {
const response1 = await generateTicket();
setTicket1(response1.data?.data);
console.log("response", response1);
const response2 = await generateTicket();
setTicket2(response2.data?.data);
const response3 = await generateTicket();
setTicket3(response3.data?.data);
}
initState();
}, [isInternational]);
const handleInternational = (index: number, val: boolean) => {
const updatedIsInternational = [...isInternational];
updatedIsInternational[index] = val;
setIsInternational(updatedIsInternational);
};
useEffect(() => {
async function fetchUrl() {
console.log("Fetch tableau");
const urlView = `${url + ticket1}/${view1}${param}`;
console.log("Fetch tableau ", urlView);
const urlRender = await fetch(urlView)
.then((response) => {
console.log("Tableau res : ", response);
})
.catch((error) => {
console.log("Tableau error: ", error);
});
}
fetchUrl();
}, [ticket1]);
return (
<div className="flex flex-col gap-2 bg-white rounded-lg p-3">
<p className="text-lg">
<b>
{isInternational[0]
? "COMMULATION OF USERS, CONTENTS AND INTERACTIONS"
: "KUMULASI PENGGUNA, KONTEN, DAN INTERAKSI"}
</b>
</p>
{levelName === "MABES POLRI" ? (
<div className="flex flex-col gap-1">
<p>Pilih Kategory</p>
<div className="flex flex-row gap-1 border-2 w-fit">
<Button
onClick={() => handleInternational(0, false)}
className={` hover:text-white rounded-none
${
isInternational[0]
? "bg-white text-black "
: "bg-black text-white "
}`}
>
Indonesia
</Button>
<Button
onClick={() => handleInternational(0, true)}
className={`hover:text-white rounded-none ${
isInternational[0]
? "bg-black text-white "
: "bg-white text-black "
}
`}
>
Internasional
</Button>
</div>
</div>
) : (
""
)}
<div className="my-5">
{ticket1 == "" ? (
<iframe
src={`${baseUrl + view1 + param}`}
width="100%"
height="750"
frameBorder="0"
/>
) : (
<iframe
src={`${`${url + ticket1}/${view1}${param}`}`}
width="100%"
height="750"
frameBorder="0"
/>
)}
</div>
<p className="text-lg">
<b>
{isInternational[1]
? "ADDITION OF CONTENT AND INTERACTION"
: "PENAMBAHAN KONTEN DAN INTERAKSI"}
</b>
</p>
{levelName === "MABES POLRI" ? (
<div className="flex flex-col gap-1">
<p>Pilih Kategory</p>
<div className="flex flex-row gap-1 border-2 w-fit">
<Button
onClick={() => handleInternational(1, false)}
className={` hover:text-white rounded-none
${
isInternational[1]
? "bg-white text-black "
: "bg-black text-white "
}`}
>
Indonesia
</Button>
<Button
onClick={() => handleInternational(1, true)}
className={`hover:text-white rounded-none ${
isInternational[1]
? "bg-black text-white "
: "bg-white text-black "
}
`}
>
Internasional
</Button>
</div>
</div>
) : (
""
)}
<div className="my-5">
{ticket2 == "" ? (
<iframe
src={`${baseUrl + view2 + param}`}
width="100%"
height="750"
frameBorder="0"
/>
) : (
<iframe
src={`${`${url + ticket2}/${view2}${param}`}`}
width="100%"
height="750"
frameBorder="0"
/>
)}
</div>
<p className="text-lg">
<b>{isInternational[2] ? "ASSIGNMENT" : "PENUGASAN"}</b>
</p>
{levelName === "MABES POLRI" ? (
<div className="flex flex-col gap-1">
<p>Pilih Kategory</p>
<div className="flex flex-row gap-1 border-2 w-fit">
<Button
onClick={() => handleInternational(2, false)}
className={` hover:text-white rounded-none
${
isInternational[2]
? "bg-white text-black "
: "bg-black text-white "
}`}
>
Indonesia
</Button>
<Button
onClick={() => handleInternational(2, true)}
className={`hover:text-white rounded-none ${
isInternational[1]
? "bg-black text-white "
: "bg-white text-black "
}
`}
>
Internasional
</Button>
</div>
</div>
) : (
""
)}
<div className="my-5">
{ticket3 == "" ? (
<iframe
src={`${baseUrl + view3 + param}`}
width="100%"
height="750"
frameBorder="0"
/>
) : (
<iframe
src={`${`${url + ticket3}/${view3}${param}`}`}
width="100%"
height="750"
frameBorder="0"
/>
)}
</div>
</div>
);
}

View File

@ -38,6 +38,7 @@ const nextConfig = {
protocol: "https",
hostname: "i.pravatar.cc",
},
{ protocol: "https", hostname: "netidhub.com" },
],
},
};

View File

@ -0,0 +1,50 @@
"use client";
import axios from "axios";
import Cookies from "js-cookie";
import qs from "qs";
import { data } from "@/app/[locale]/(protected)/charts/rechart/charts-rechart-bar/data";
import { url } from "inspector";
const baseURL = "https://netidhub.com/api/";
const tokenAuth = Cookies.get("access_token")
? Cookies.get("access_token")
: null;
import { getAPIInterceptor } from "@/config/api";
import axiosInterceptor from "@/config/axiosInterceptor";
export async function postAPIInterceptorTableau(url: string, data?: any) {
const response = await axiosInterceptor
.post(url, data)
.catch((error) => error.response);
if (response?.status === 401) {
Object.keys(Cookies.get()).forEach((cookieName) => {
Cookies.remove(cookieName);
});
window.location.href = "/";
} else if (response?.status > 300 && response?.status !== 401) {
return {
error: true,
message: response?.data?.message,
data: null,
};
} else if (response?.data?.success) {
return {
error: false,
message: "success",
data: response?.data,
};
}
return {
error: true,
message: response?.data?.message,
data: null,
};
}
export async function generateTicket() {
const url = "/admin/tableau-ticket";
return postAPIInterceptorTableau(url);
}