feat:update modal survey,fix ui
This commit is contained in:
parent
da8fde5499
commit
fea54bf883
|
|
@ -581,7 +581,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => {
|
|||
{roleId == 3 || roleId == 11 || roleId == 2 || roleId == 12 ? (
|
||||
<Button
|
||||
onClick={handleDateClick}
|
||||
className="dark:bg-background dark:text-foreground w-[250px]"
|
||||
className="dark:bg-background dark:text-foreground w-full"
|
||||
>
|
||||
<Plus className="w-4 h-4 me-1" />
|
||||
{t("addEvent")}
|
||||
|
|
@ -593,7 +593,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => {
|
|||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
{roleId === 3 && userLevelId === 216 ? (
|
||||
<Button className="dark:bg-background dark:text-foreground w-[250px]">
|
||||
<Button className="dark:bg-background dark:text-foreground w-full">
|
||||
<Book className="w-4 h-4" />
|
||||
{t("bag-pa-monitoring-results")}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -775,7 +775,7 @@ const EventModal = ({
|
|||
checked={wilayahPublish.semua}
|
||||
onCheckedChange={() => toggleWilayah("semua")}
|
||||
/>
|
||||
<label htmlFor="semua" className="ml-2">
|
||||
<label htmlFor="semua" className="ml-2 text-sm">
|
||||
Semua
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -785,7 +785,7 @@ const EventModal = ({
|
|||
checked={wilayahPublish.nasional}
|
||||
onCheckedChange={() => toggleWilayah("nasional")}
|
||||
/>
|
||||
<label htmlFor="nasional" className="ml-2">
|
||||
<label htmlFor="nasional" className="ml-2 text-sm mr-2">
|
||||
Nasional
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -795,7 +795,7 @@ const EventModal = ({
|
|||
checked={wilayahPublish.polda}
|
||||
onCheckedChange={() => toggleWilayah("polda")}
|
||||
/>
|
||||
<label htmlFor="polda" className="mx-2">
|
||||
<label htmlFor="polda" className="mx-2 text-sm mr-2">
|
||||
Polda
|
||||
</label>
|
||||
{wilayahPublish.polda && (
|
||||
|
|
@ -814,7 +814,7 @@ const EventModal = ({
|
|||
checked={wilayahPublish.polres}
|
||||
onCheckedChange={() => toggleWilayah("polres")}
|
||||
/>
|
||||
<label htmlFor="polres" className="ml-2">
|
||||
<label htmlFor="polres" className="ml-2 text-sm mr-2">
|
||||
Polres
|
||||
</label>
|
||||
{wilayahPublish.polres && (
|
||||
|
|
@ -833,7 +833,7 @@ const EventModal = ({
|
|||
checked={wilayahPublish.satker}
|
||||
onCheckedChange={() => toggleWilayah("satker")}
|
||||
/>
|
||||
<label htmlFor="satker" className="mx-2">
|
||||
<label htmlFor="satker" className="mx-2 text-sm mr-2">
|
||||
Satker
|
||||
</label>
|
||||
{wilayahPublish.satker && (
|
||||
|
|
@ -852,7 +852,10 @@ const EventModal = ({
|
|||
checked={wilayahPublish.international}
|
||||
onCheckedChange={() => toggleWilayah("international")}
|
||||
/>
|
||||
<label htmlFor="international" className="ml-2">
|
||||
<label
|
||||
htmlFor="international"
|
||||
className="ml-2 text-sm mr-2"
|
||||
>
|
||||
Internasional
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ const TableAudio = () => {
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="md" variant="outline">
|
||||
1 - {showData} Data
|
||||
{showData} Data
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56 text-sm">
|
||||
|
|
@ -272,16 +272,16 @@ const TableAudio = () => {
|
|||
onValueChange={setShowData}
|
||||
>
|
||||
<DropdownMenuRadioItem value="10">
|
||||
1 - 10 Data
|
||||
10 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="50">
|
||||
1 - 50 Data
|
||||
50 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="100">
|
||||
1 - 100 Data
|
||||
100 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="250">
|
||||
1 - 250 Data
|
||||
250 Data
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ const TableImage = () => {
|
|||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({});
|
||||
const [rowSelection, setRowSelection] = React.useState({});
|
||||
const [showData, setShowData] = React.useState("50");
|
||||
const [showData, setShowData] = React.useState("10");
|
||||
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
pageSize: Number(showData),
|
||||
|
|
@ -268,7 +268,7 @@ const TableImage = () => {
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="md" variant="outline">
|
||||
1 - {showData} Data
|
||||
{showData} Data
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56 text-sm">
|
||||
|
|
@ -277,16 +277,16 @@ const TableImage = () => {
|
|||
onValueChange={setShowData}
|
||||
>
|
||||
<DropdownMenuRadioItem value="10">
|
||||
1 - 10 Data
|
||||
10 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="50">
|
||||
1 - 50 Data
|
||||
50 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="100">
|
||||
1 - 100 Data
|
||||
100 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="250">
|
||||
1 - 250 Data
|
||||
250 Data
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ const TableTeks = () => {
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="md" variant="outline">
|
||||
1 - {showData} Data
|
||||
{showData} Data
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56 text-sm">
|
||||
|
|
@ -271,16 +271,16 @@ const TableTeks = () => {
|
|||
onValueChange={setShowData}
|
||||
>
|
||||
<DropdownMenuRadioItem value="10">
|
||||
1 - 10 Data
|
||||
10 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="50">
|
||||
1 - 50 Data
|
||||
50 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="100">
|
||||
1 - 100 Data
|
||||
100 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="250">
|
||||
1 - 250 Data
|
||||
250 Data
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ const TableVideo = () => {
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="md" variant="outline">
|
||||
1 - {showData} Data
|
||||
{showData} Data
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56 text-sm">
|
||||
|
|
@ -273,16 +273,16 @@ const TableVideo = () => {
|
|||
onValueChange={setShowData}
|
||||
>
|
||||
<DropdownMenuRadioItem value="10">
|
||||
1 - 10 Data
|
||||
10 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="50">
|
||||
1 - 50 Data
|
||||
50 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="100">
|
||||
1 - 100 Data
|
||||
100 Data
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="250">
|
||||
1 - 250 Data
|
||||
250 Data
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
|
|
|
|||
|
|
@ -266,7 +266,6 @@ const PressReleaseTable = () => {
|
|||
totalPage={totalPage}
|
||||
/>
|
||||
</div>
|
||||
\{" "}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ const DashboardPage = () => {
|
|||
<Card>
|
||||
<CardHeader className="flex flex-row items-center">
|
||||
<CardTitle className="flex-1">{t("tabel")}</CardTitle>
|
||||
<DashboardDropdown />
|
||||
{/* <DashboardDropdown /> */}
|
||||
</CardHeader>
|
||||
<CardContent className="p-0">
|
||||
<ContentTable />
|
||||
|
|
|
|||
|
|
@ -626,15 +626,15 @@ const DetailInfo = () => {
|
|||
onClick={() => doBookmark()}
|
||||
className="flex flex-col mb-3 items-center justify-center cursor-pointer"
|
||||
>
|
||||
<Icon icon="material-symbols:bookmark-outline" width={40} />
|
||||
<p className="text-base lg:text-lg">{t("save")}</p>
|
||||
<Icon icon="material-symbols:bookmark-outline" width={25} />
|
||||
<p className="text-base lg:text-sm">{t("save")}</p>
|
||||
</a>
|
||||
)}
|
||||
|
||||
{/* garis */}
|
||||
<div className="border-t border-black my-4"></div>
|
||||
<div className="flex flex-col justify-center items-center gap-3">
|
||||
<div className="w-auto">
|
||||
<div className="w-auto mb-3">
|
||||
<Link
|
||||
href={`/all/filter?title=polda&category=${detailDataImage?.category.id}`}
|
||||
className="bg-red-600 text-white text-xs font-bold px-3 py-3 my-3 rounded w-auto"
|
||||
|
|
@ -648,7 +648,7 @@ const DetailInfo = () => {
|
|||
<a
|
||||
onClick={() => router.push(`/all/filter?tag=${tag}`)}
|
||||
key={tag}
|
||||
className="bg-gray-200 text-gray-700 text-xs px-3 py-1 rounded-full cursor-pointer hover:bg-gray-500"
|
||||
className="bg-gray-200 text-gray-700 text-xs px-3 py-3 font-semibold rounded-full cursor-pointer hover:bg-gray-500"
|
||||
>
|
||||
{tag}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,22 @@
|
|||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||
import {
|
||||
Carousel,
|
||||
CarouselContent,
|
||||
CarouselItem,
|
||||
CarouselNext,
|
||||
CarouselPrevious,
|
||||
} from "@/components/ui/carousel";
|
||||
import { Link, useRouter } from "@/i18n/routing";
|
||||
import { deleteBlogComments, getBlogComments, getDetailIndeks, getPublicSuggestionList, postBlogComments, publicDetailBlog } from "@/service/landing/landing";
|
||||
import {
|
||||
deleteBlogComments,
|
||||
getBlogComments,
|
||||
getDetailIndeks,
|
||||
getPublicSuggestionList,
|
||||
postBlogComments,
|
||||
publicDetailBlog,
|
||||
} from "@/service/landing/landing";
|
||||
import { formatDateToIndonesian } from "@/utils/globals";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
|
|
@ -94,7 +107,9 @@ const IndeksDetail = () => {
|
|||
// }
|
||||
|
||||
async function sendCommentChild(parentId: any) {
|
||||
const inputMsg = document.querySelector(`#input-comment-${parentId}`) as HTMLInputElement;
|
||||
const inputMsg = document.querySelector(
|
||||
`#input-comment-${parentId}`
|
||||
) as HTMLInputElement;
|
||||
|
||||
if (inputMsg && inputMsg.value.length > 3) {
|
||||
loading();
|
||||
|
|
@ -166,32 +181,54 @@ const IndeksDetail = () => {
|
|||
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
|
||||
</svg>`;
|
||||
|
||||
const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str));
|
||||
const toBase64 = (str: string) =>
|
||||
typeof window === "undefined"
|
||||
? Buffer.from(str).toString("base64")
|
||||
: window.btoa(str);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="p-4 lg:px-60 lg:p-12">
|
||||
<div className="p-4 lg:px-28 lg:p-12">
|
||||
{/* Judul */}
|
||||
<div className="flex flex-col mb-5">
|
||||
<h1 className="text-base lg:text-lg mb-2">Index / Detail</h1>
|
||||
<h1 className="flex flex-row font-bold text-center text-lg lg:text-2xl">{indeksData?.title}</h1>
|
||||
<h1 className="flex flex-row font-bold text-center text-lg lg:text-2xl">
|
||||
{indeksData?.title}
|
||||
</h1>
|
||||
</div>
|
||||
{/* Gambar Utama */}
|
||||
<div className="flex items-center justify-center">
|
||||
<Image placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`} width={2560} height={1440} src={indeksData?.thumbnailLink} alt="Main" className="h-fit lg:h-[550px] w-full rounded-lg" />
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
width={2560}
|
||||
height={1440}
|
||||
src={indeksData?.thumbnailLink}
|
||||
alt="Main"
|
||||
className="w-full max-h-[550px] object-contain rounded-xl "
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Footer Informasi */}
|
||||
<div className="text-gray-500 flex border-t mt-4">
|
||||
<div className="flex mt-2">
|
||||
<p className="text-xs lg:text-sm mb-2 ">
|
||||
{t("by")} <span className="font-semibold text-gray-500">{indeksData?.uploaderName}</span> | {t("updatedOn")} {indeksData?.createdAt} WIB
|
||||
{t("by")}
|
||||
<span className="font-semibold text-gray-500">
|
||||
{indeksData?.uploaderName}
|
||||
</span>
|
||||
| {t("updatedOn")} {indeksData?.createdAt} WIB
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Keterangan */}
|
||||
<div className="w-auto">
|
||||
<p className="font-light text-base lg:text-lg text-justify" dangerouslySetInnerHTML={{ __html: indeksData?.description }} />
|
||||
<p
|
||||
className="font-light text-base lg:text-lg text-justify"
|
||||
dangerouslySetInnerHTML={{ __html: indeksData?.description }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -199,9 +236,19 @@ const IndeksDetail = () => {
|
|||
<div className="w-full">
|
||||
<div className="flex flex-col py-5 p-0 lg:p-10 bg-[#f7f7f7] dark:bg-slate-600">
|
||||
<div className="gap-5 flex flex-col px-4 lg:px-16">
|
||||
<p className="flex items-start text-bases lg:text-lg">{t("comment")}</p>
|
||||
<Textarea placeholder="Type your comments here." className="flex w-full" onChange={getInputValue} value={message} />
|
||||
<button className="flex items-start bg-[#bb3523] text-white rounded-lg text-sm lg:text-base w-fit px-3 lg:px-4 py-1" onClick={() => postData()}>
|
||||
<p className="flex items-start text-bases lg:text-lg">
|
||||
{t("comment")}
|
||||
</p>
|
||||
<Textarea
|
||||
placeholder="Type your comments here."
|
||||
className="flex w-full"
|
||||
onChange={getInputValue}
|
||||
value={message}
|
||||
/>
|
||||
<button
|
||||
className="flex items-start bg-[#bb3523] text-white rounded-lg text-sm lg:text-base w-fit px-3 lg:px-4 py-1"
|
||||
onClick={() => postData()}
|
||||
>
|
||||
{t("send")}
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -212,15 +259,40 @@ const IndeksDetail = () => {
|
|||
{listComments?.map((data: any) => (
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-row mt-2 px-4 lg:px-14">
|
||||
<Image placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`} width={512} height={512} className="h-10 lg:h-20 w-10 lg:w-20" src="/assets/img/user-avatar-yellow.svg" alt="#" />
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
width={512}
|
||||
height={512}
|
||||
className="h-10 lg:h-20 w-10 lg:w-20"
|
||||
src="/assets/img/user-avatar-yellow.svg"
|
||||
alt="#"
|
||||
/>
|
||||
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||
<p className="flex justify-between text-sm text-slate-500 lg:text-base border-b-2 border-slate-200 mb-2">
|
||||
<b>{Number(data.commentFrom?.roleId) == 2 || Number(data.commentFrom?.roleId) == 3 || Number(data.commentFrom?.roleId) == 4 ? "HUMAS POLRI" : data.commentFrom?.fullname}</b>
|
||||
{`${new Date(data.createdAt).getDate()}/${new Date(data.createdAt).getMonth() + 1}/${new Date(data.createdAt).getFullYear()} ${new Date(data.createdAt).getHours()}:${new Date(data.createdAt).getMinutes()}`}
|
||||
<b>
|
||||
{Number(data.commentFrom?.roleId) == 2 ||
|
||||
Number(data.commentFrom?.roleId) == 3 ||
|
||||
Number(data.commentFrom?.roleId) == 4
|
||||
? "HUMAS POLRI"
|
||||
: data.commentFrom?.fullname}
|
||||
</b>
|
||||
{`${new Date(data.createdAt).getDate()}/${
|
||||
new Date(data.createdAt).getMonth() + 1
|
||||
}/${new Date(data.createdAt).getFullYear()} ${new Date(
|
||||
data.createdAt
|
||||
).getHours()}:${new Date(data.createdAt).getMinutes()}`}
|
||||
</p>
|
||||
<p className="text-slate-500 text-sm lg:text-base mb-4">
|
||||
{data.message}
|
||||
</p>
|
||||
<p className="text-slate-500 text-sm lg:text-base mb-4">{data.message}</p>
|
||||
<div className="gap-3">
|
||||
<a href="javascript:void(0)" className="text-xs lg:text-sm mr-2 bg-blue-500 text-white py-1 px-2 hover:bg-blue-300 hover:text-black rounded-md" onClick={() => showInput(`comment-id-${data.id}`)}>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="text-xs lg:text-sm mr-2 bg-blue-500 text-white py-1 px-2 hover:bg-blue-300 hover:text-black rounded-md"
|
||||
onClick={() => showInput(`comment-id-${data.id}`)}
|
||||
>
|
||||
{t("reply")}
|
||||
</a>
|
||||
<a
|
||||
|
|
@ -240,9 +312,21 @@ const IndeksDetail = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row px-4 pl-[55px] lg:px-14 lg:pl-[135px] mt-2" id={`comment-id-${data.id}`}>
|
||||
<Input type="text" id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder={t("enterReply")} />
|
||||
<a href="javascript:void(0)" className="flex py-1 px-2 rounded-md items-center ml-2 bg-[#f7b357] text-white text-sm lg:text-base" onClick={() => postDataChild(data.id)}>
|
||||
<div
|
||||
className="flex flex-row px-4 pl-[55px] lg:px-14 lg:pl-[135px] mt-2"
|
||||
id={`comment-id-${data.id}`}
|
||||
>
|
||||
<Input
|
||||
type="text"
|
||||
id={`input-comment-${data.id}`}
|
||||
className="p-4 focus:outline-none focus:border-sky-500"
|
||||
placeholder={t("enterReply")}
|
||||
/>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="flex py-1 px-2 rounded-md items-center ml-2 bg-[#f7b357] text-white text-sm lg:text-base"
|
||||
onClick={() => postDataChild(data.id)}
|
||||
>
|
||||
{t("send")}
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -250,24 +334,54 @@ const IndeksDetail = () => {
|
|||
? data.children?.map((child1: any) => (
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-row mt-2 px-4 lg:pr-14 pl-12 lg:pl-32">
|
||||
<Image placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`} width={512} height={512} className="h-10 lg:h-20 w-10 lg:w-20" src="/assets/img/user-avatar-yellow.svg" alt="#" />
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
width={512}
|
||||
height={512}
|
||||
className="h-10 lg:h-20 w-10 lg:w-20"
|
||||
src="/assets/img/user-avatar-yellow.svg"
|
||||
alt="#"
|
||||
/>
|
||||
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||
<p className="flex justify-between text-slate-500 text-sm lg:text-base border-b-2 border-slate-200 mb-2">
|
||||
<b>{Number(child1.commentFrom?.roleId) == 2 || Number(child1.commentFrom?.roleId) == 3 || Number(child1.commentFrom?.roleId) == 4 ? "HUMAS POLRI" : child1.commentFrom?.fullname}</b>
|
||||
{`${new Date(child1.createdAt).getDate()}/${new Date(child1.createdAt).getMonth() + 1}/${new Date(child1.createdAt).getFullYear()} ${new Date(child1.createdAt).getHours()}:${new Date(
|
||||
<b>
|
||||
{Number(child1.commentFrom?.roleId) == 2 ||
|
||||
Number(child1.commentFrom?.roleId) == 3 ||
|
||||
Number(child1.commentFrom?.roleId) == 4
|
||||
? "HUMAS POLRI"
|
||||
: child1.commentFrom?.fullname}
|
||||
</b>
|
||||
{`${new Date(child1.createdAt).getDate()}/${
|
||||
new Date(child1.createdAt).getMonth() + 1
|
||||
}/${new Date(
|
||||
child1.createdAt
|
||||
).getFullYear()} ${new Date(
|
||||
child1.createdAt
|
||||
).getHours()}:${new Date(
|
||||
child1.createdAt
|
||||
).getMinutes()}`}
|
||||
</p>
|
||||
<p className="text-slate-500 text-sm mb-4">{child1.message}</p>
|
||||
<p className="text-slate-500 text-sm mb-4">
|
||||
{child1.message}
|
||||
</p>
|
||||
<div className="gap-3">
|
||||
<a href="javascript:void(0)" className="mr-2 text-xs lg:text-sm bg-blue-500 text-white py-1 px-2 hover:bg-blue-300 hover:text-black rounded-md" onClick={() => showInput(`comment-id-${child1.id}`)}>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="mr-2 text-xs lg:text-sm bg-blue-500 text-white py-1 px-2 hover:bg-blue-300 hover:text-black rounded-md"
|
||||
onClick={() =>
|
||||
showInput(`comment-id-${child1.id}`)
|
||||
}
|
||||
>
|
||||
{t("reply")}
|
||||
</a>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="text-xs lg:text-sm bg-red-500 text-white py-1 px-2 hover:bg-red-300 hover:text-black rounded-md"
|
||||
style={
|
||||
Number(child1.commentFrom?.id) == Number(userId)
|
||||
Number(child1.commentFrom?.id) ==
|
||||
Number(userId)
|
||||
? {}
|
||||
: {
|
||||
display: "none",
|
||||
|
|
@ -280,9 +394,21 @@ const IndeksDetail = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row justify-center px-4 pl-[87px] lg:px-14 lg:pl-[205px] mt-2" id={`comment-id-${child1.id}`}>
|
||||
<Input type="text" id={`input-comment-${child1.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder={t("enterReply")} />
|
||||
<a href="javascript:void(0)" className="flex text-sm lg:text-base py-1 px-2 rounded-md items-center ml-2 bg-[#f7b357] text-white" onClick={() => postDataChild(child1.id)}>
|
||||
<div
|
||||
className="flex flex-row justify-center px-4 pl-[87px] lg:px-14 lg:pl-[205px] mt-2"
|
||||
id={`comment-id-${child1.id}`}
|
||||
>
|
||||
<Input
|
||||
type="text"
|
||||
id={`input-comment-${child1.id}`}
|
||||
className="p-4 focus:outline-none focus:border-sky-500"
|
||||
placeholder={t("enterReply")}
|
||||
/>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="flex text-sm lg:text-base py-1 px-2 rounded-md items-center ml-2 bg-[#f7b357] text-white"
|
||||
onClick={() => postDataChild(child1.id)}
|
||||
>
|
||||
{t("send")}
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -290,24 +416,59 @@ const IndeksDetail = () => {
|
|||
? child1.children?.map((child2: any) => (
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-row mt-2 px-4 lg:pr-14 pl-20 lg:pl-48">
|
||||
<Image placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`} width={512} height={512} className="h-10 lg:h-20 w-10 lg:w-20" src="/assets/img/user-avatar-yellow.svg" alt="#" />
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
width={512}
|
||||
height={512}
|
||||
className="h-10 lg:h-20 w-10 lg:w-20"
|
||||
src="/assets/img/user-avatar-yellow.svg"
|
||||
alt="#"
|
||||
/>
|
||||
<div className="border border-slate-300 w-full p-4 bg-white gap-2">
|
||||
<p className="flex justify-between text-slate-500 text-xs lg:text-base border-b-2 border-slate-200 mb-2">
|
||||
<b>{Number(child2.commentFrom?.roleId) == 2 || Number(child2.commentFrom?.roleId) == 3 || Number(child2.commentFrom?.roleId) == 4 ? "HUMAS POLRI" : child2.commentFrom?.fullname}</b>
|
||||
{`${new Date(child2.createdAt).getDate()}/${new Date(child2.createdAt).getMonth() + 1}/${new Date(child2.createdAt).getFullYear()} ${new Date(child2.createdAt).getHours()}:${new Date(
|
||||
<b>
|
||||
{Number(child2.commentFrom?.roleId) ==
|
||||
2 ||
|
||||
Number(child2.commentFrom?.roleId) ==
|
||||
3 ||
|
||||
Number(child2.commentFrom?.roleId) == 4
|
||||
? "HUMAS POLRI"
|
||||
: child2.commentFrom?.fullname}
|
||||
</b>
|
||||
{`${new Date(
|
||||
child2.createdAt
|
||||
).getDate()}/${
|
||||
new Date(child2.createdAt).getMonth() +
|
||||
1
|
||||
}/${new Date(
|
||||
child2.createdAt
|
||||
).getFullYear()} ${new Date(
|
||||
child2.createdAt
|
||||
).getHours()}:${new Date(
|
||||
child2.createdAt
|
||||
).getMinutes()}`}
|
||||
</p>
|
||||
<p className="text-slate-500 text-sm mb-4">{child2.message}</p>
|
||||
<p className="text-slate-500 text-sm mb-4">
|
||||
{child2.message}
|
||||
</p>
|
||||
<div>
|
||||
<a href="javascript:void(0)" className="mr-2 text-xs lg:text-sm bg-blue-500 text-white py-1 px-2 hover:bg-blue-300 hover:text-black rounded-md" onClick={() => showInput("comment-id-" + child2.id)}>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="mr-2 text-xs lg:text-sm bg-blue-500 text-white py-1 px-2 hover:bg-blue-300 hover:text-black rounded-md"
|
||||
onClick={() =>
|
||||
showInput("comment-id-" + child2.id)
|
||||
}
|
||||
>
|
||||
{t("reply")}
|
||||
</a>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="text-xs lg:text-sm bg-red-500 text-white py-1 px-2 hover:bg-red-300 hover:text-black rounded-md"
|
||||
style={
|
||||
Number(child2.commentFrom?.id) == Number(userId)
|
||||
Number(child2.commentFrom?.id) ==
|
||||
Number(userId)
|
||||
? {}
|
||||
: {
|
||||
display: "none",
|
||||
|
|
@ -320,9 +481,21 @@ const IndeksDetail = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row px-4 pl-[120px] lg:px-14 lg:pl-[270px] mt-2" id={`comment-id-${child2.id}`}>
|
||||
<Input type="text" id={`comment-id-${child2.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder={t("enterReply")} />
|
||||
<a href="javascript:void(0)" className="flex text-sm lg:text-base py-1 px-2 rounded-md items-center ml-2 bg-[#f7b357] text-white" onClick={() => postDataChild(child1.id)}>
|
||||
<div
|
||||
className="flex flex-row px-4 pl-[120px] lg:px-14 lg:pl-[270px] mt-2"
|
||||
id={`comment-id-${child2.id}`}
|
||||
>
|
||||
<Input
|
||||
type="text"
|
||||
id={`comment-id-${child2.id}`}
|
||||
className="p-4 focus:outline-none focus:border-sky-500"
|
||||
placeholder={t("enterReply")}
|
||||
/>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="flex text-sm lg:text-base py-1 px-2 rounded-md items-center ml-2 bg-[#f7b357] text-white"
|
||||
onClick={() => postDataChild(child1.id)}
|
||||
>
|
||||
{t("send")}
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -339,14 +512,25 @@ const IndeksDetail = () => {
|
|||
|
||||
{/* Konten Serupa */}
|
||||
<div className="space-x-5 flex flex-col px-4 lg:px-16 py-16 gap-5">
|
||||
<h1 className="font-bold text-base lg:text-xl px-4 lg:px-8"> {t("relatedPosts")}</h1>
|
||||
<h1 className="font-bold text-base lg:text-xl px-4 lg:px-8">
|
||||
{" "}
|
||||
{t("relatedPosts")}
|
||||
</h1>
|
||||
<Carousel>
|
||||
<CarouselContent className="w-full max-w-7xl">
|
||||
{indexData?.map((relate: any) => (
|
||||
<CarouselItem key={relate?.id} className="md:basis-1/2 lg:basis-1/3">
|
||||
<Link href={`/indeks/detail/${relate?.slug}`} className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
||||
<CarouselItem
|
||||
key={relate?.id}
|
||||
className="md:basis-1/2 lg:basis-1/3"
|
||||
>
|
||||
<Link
|
||||
href={`/indeks/detail/${relate?.slug}`}
|
||||
className="relative group overflow-hidden shadow-md hover:shadow-lg"
|
||||
>
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
alt=""
|
||||
width={2560}
|
||||
height={1440}
|
||||
|
|
@ -354,10 +538,17 @@ const IndeksDetail = () => {
|
|||
className="w-full rounded-lg h-40 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300"
|
||||
/>
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-gray-600 border-l-4 border-[#bb3523] rounded-lg backdrop-blur-sm text-white p-2">
|
||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-sm px-4 py-1">{relate?.categoryName}</span>
|
||||
<h1 className="text-sm lg:text-lg mb-2 font-semibold h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{relate?.title}</h1>
|
||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-sm px-4 py-1">
|
||||
{relate?.categoryName}
|
||||
</span>
|
||||
<h1 className="text-sm lg:text-lg mb-2 font-semibold h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">
|
||||
{relate?.title}
|
||||
</h1>
|
||||
<p className="flex flex-row items-center text-[10px] gap-2">
|
||||
{formatDateToIndonesian(new Date(relate?.createdAt))} {relate?.timezone ? relate?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {relate.clickCount}{" "}
|
||||
{formatDateToIndonesian(new Date(relate?.createdAt))}{" "}
|
||||
{relate?.timezone ? relate?.timezone : "WIB"} |{" "}
|
||||
<Icon icon="formkit:eye" width="15" height="15" />{" "}
|
||||
{relate.clickCount}{" "}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import { getIndeksData } from "@/service/landing/landing";
|
||||
import { formatDateToIndonesian } from "@/utils/globals";
|
||||
import { formatDateToIndonesian, htmlToString } from "@/utils/globals";
|
||||
import Image from "next/image";
|
||||
import { usePathname } from "next/navigation";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
|
@ -54,8 +54,10 @@ const Indeks: React.FC = () => {
|
|||
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
|
||||
</svg>`;
|
||||
|
||||
const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str));
|
||||
|
||||
const toBase64 = (str: string) =>
|
||||
typeof window === "undefined"
|
||||
? Buffer.from(str).toString("base64")
|
||||
: window.btoa(str);
|
||||
|
||||
return (
|
||||
<div className="px-4 lg:px-14">
|
||||
|
|
@ -70,22 +72,44 @@ const Indeks: React.FC = () => {
|
|||
{indeksData?.map(
|
||||
(indeks: any, index: number) =>
|
||||
index == count && (
|
||||
<div key={indeks?.id} className="relative h-[310px] lg:h-[435px]">
|
||||
<Image placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`} width={2560} height={1440} src={indeks?.thumbnailLink} alt="image" className="w-full h-[310px] lg:h-[435px] rounded-lg object-cover" />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm text-white p-4 rounded-b-lg">
|
||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-xs px-2 py-1">{indeks?.categoryName}</span>
|
||||
<div
|
||||
key={indeks?.id}
|
||||
className="relative h-[310px] lg:h-[435px]"
|
||||
>
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
width={2560}
|
||||
height={1440}
|
||||
src={indeks?.thumbnailLink}
|
||||
alt="image"
|
||||
className="w-full h-[310px] lg:h-[435px] rounded-lg object-cover"
|
||||
/>
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-black/15 backdrop-brightness-50 text-white p-4 rounded-b-lg">
|
||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-xs px-2 py-1">
|
||||
{indeks?.categoryName}
|
||||
</span>
|
||||
<Link href={`/indeks/detail/${indeks?.slug}`}>
|
||||
<h2 className="text-2xl font-bold mt-2">{indeks?.title}</h2>
|
||||
<h2 className="text-2xl font-bold mt-2">
|
||||
{indeks?.title}
|
||||
</h2>
|
||||
</Link>
|
||||
<p className="text-xs flex flex-row items-center gap-1 mt-1">
|
||||
{formatDateToIndonesian(new Date(indeks?.createdAt))} {indeks?.timezone ? indeks?.timezone : "WIB"} |{" "}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
||||
{formatDateToIndonesian(new Date(indeks?.createdAt))}{" "}
|
||||
{indeks?.timezone ? indeks?.timezone : "WIB"} |{" "}
|
||||
{/* <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1.2em"
|
||||
height="1.2em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M11.5 18c4 0 7.46-2.22 9.24-5.5C18.96 9.22 15.5 7 11.5 7s-7.46 2.22-9.24 5.5C4.04 15.78 7.5 18 11.5 18m0-12c4.56 0 8.5 2.65 10.36 6.5C20 16.35 16.06 19 11.5 19S3 16.35 1.14 12.5C3 8.65 6.94 6 11.5 6m0 2C14 8 16 10 16 12.5S14 17 11.5 17S7 15 7 12.5S9 8 11.5 8m0 1A3.5 3.5 0 0 0 8 12.5a3.5 3.5 0 0 0 3.5 3.5a3.5 3.5 0 0 0 3.5-3.5A3.5 3.5 0 0 0 11.5 9"
|
||||
/>
|
||||
</svg>{" "}
|
||||
{indeks?.clickCount}
|
||||
</svg>{" "} */}
|
||||
{/* {indeks?.clickCount} */}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -108,22 +132,49 @@ const Indeks: React.FC = () => {
|
|||
{indeksData?.map(
|
||||
(indeksRight: any, index: number) =>
|
||||
(index == count + 1 || index == count + 2) && (
|
||||
<div key={indeksRight?.id} className="relative h-[310px] lg:h-[215px]">
|
||||
<Image placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`} width={1920} height={1080} src={indeksRight?.thumbnailLink} alt="image" className="w-full h-[310px] lg:h-[215px] rounded-lg " />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm text-white p-4 rounded-b-lg">
|
||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-xs px-2 py-1">{indeksRight?.categoryName}</span>
|
||||
<div
|
||||
key={indeksRight?.id}
|
||||
className="relative h-[310px] lg:h-[215px]"
|
||||
>
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
width={1920}
|
||||
height={1080}
|
||||
src={indeksRight?.thumbnailLink}
|
||||
alt="image"
|
||||
className="w-full h-[310px] lg:h-[215px] rounded-lg "
|
||||
/>
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-black/15 backdrop-brightness-50 text-white p-4 rounded-b-lg">
|
||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-xs px-2 py-1">
|
||||
{indeksRight?.categoryName}
|
||||
</span>
|
||||
<Link href={`/indeks/detail/${indeksRight?.slug}`}>
|
||||
<h2 className="text-xl font-bold mt-2">{indeksRight?.title}</h2>
|
||||
<h2 className="text-xl font-bold mt-2">
|
||||
{indeksRight?.title}
|
||||
</h2>
|
||||
</Link>
|
||||
<p className="text-xs flex flex-row items-center gap-1 mt-1 ml-2">
|
||||
{formatDateToIndonesian(new Date(indeksRight?.createdAt))} {indeksRight?.timezone ? indeksRight?.timezone : "WIB"}|{" "}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
||||
{formatDateToIndonesian(
|
||||
new Date(indeksRight?.createdAt)
|
||||
)}{" "}
|
||||
{indeksRight?.timezone
|
||||
? indeksRight?.timezone
|
||||
: "WIB"}
|
||||
|{" "}
|
||||
{/* <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1.2em"
|
||||
height="1.2em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M11.5 18c4 0 7.46-2.22 9.24-5.5C18.96 9.22 15.5 7 11.5 7s-7.46 2.22-9.24 5.5C4.04 15.78 7.5 18 11.5 18m0-12c4.56 0 8.5 2.65 10.36 6.5C20 16.35 16.06 19 11.5 19S3 16.35 1.14 12.5C3 8.65 6.94 6 11.5 6m0 2C14 8 16 10 16 12.5S14 17 11.5 17S7 15 7 12.5S9 8 11.5 8m0 1A3.5 3.5 0 0 0 8 12.5a3.5 3.5 0 0 0 3.5 3.5a3.5 3.5 0 0 0 3.5-3.5A3.5 3.5 0 0 0 11.5 9"
|
||||
/>
|
||||
</svg>{" "}
|
||||
{indeksRight?.clickCount}
|
||||
{indeksRight?.clickCount} */}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -165,14 +216,31 @@ const Indeks: React.FC = () => {
|
|||
{indeksData?.map(
|
||||
(indeksBottom: any, index: number) =>
|
||||
index < 3 && (
|
||||
<div key={indeksBottom?.id} className="flex flex-col md:flex-row items-start p-4 gap-4">
|
||||
<Image placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`} width={2560} height={1440} src={indeksBottom?.thumbnailLink} alt="" className="h-40 object-cover rounded-lg w-full lg:w-full lg:h-[300px]" />
|
||||
<div
|
||||
key={indeksBottom?.id}
|
||||
className="flex flex-col md:flex-row items-start p-4 gap-4"
|
||||
>
|
||||
<Image
|
||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||
shimmer(700, 475)
|
||||
)}`}
|
||||
width={500}
|
||||
height={250}
|
||||
src={indeksBottom?.thumbnailLink}
|
||||
alt=""
|
||||
className="h-40 object-cover rounded-lg w-full lg:w-[550px] lg:h-[200px]"
|
||||
/>
|
||||
<div className="flex flex-col justify-between w-full">
|
||||
<p className="text-sm">{indeksBottom?.date}</p>
|
||||
<Link href={`/indeks/detail/${indeksBottom?.slug}`} className="text-2xl font-semibold text-gray-800 dark:text-white">
|
||||
<Link
|
||||
href={`/indeks/detail/${indeksBottom?.slug}`}
|
||||
className="text-2xl font-semibold text-gray-800 dark:text-white"
|
||||
>
|
||||
{indeksBottom?.title}
|
||||
</Link>
|
||||
<p className="text-sm text-gray-600 dark:text-white mt-2">{indeksBottom?.description}</p>
|
||||
<p className="text-sm text-gray-600 dark:text-white mt-2">
|
||||
{htmlToString(indeksBottom?.description)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,50 @@
|
|||
"use client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||
import { Popover, PopoverArrow, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
Popover,
|
||||
PopoverArrow,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { CalendarIcon } from "lucide-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { format } from "date-fns";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { detailSchedule, listSchedule, listScheduleNextPublic, listSchedulePrevPublic, listScheduleTodayPublic, searchSchedules } from "@/service/schedule/schedule";
|
||||
import {
|
||||
detailSchedule,
|
||||
listSchedule,
|
||||
listScheduleNextPublic,
|
||||
listSchedulePrevPublic,
|
||||
listScheduleTodayPublic,
|
||||
searchSchedules,
|
||||
} from "@/service/schedule/schedule";
|
||||
import { usePathname, useRouter } from "@/i18n/routing";
|
||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { close, loading } from "@/config/swal";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
|
@ -292,13 +324,21 @@ const Schedule = (props: any) => {
|
|||
|
||||
function getLastWeek(today: Date | undefined) {
|
||||
if (today) {
|
||||
return new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7);
|
||||
return new Date(
|
||||
today.getFullYear(),
|
||||
today.getMonth(),
|
||||
today.getDate() - 7
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getNextWeek(today: Date | undefined) {
|
||||
if (today) {
|
||||
return new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);
|
||||
return new Date(
|
||||
today.getFullYear(),
|
||||
today.getMonth(),
|
||||
today.getDate() + 7
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -423,13 +463,22 @@ const Schedule = (props: any) => {
|
|||
};
|
||||
|
||||
function setItemSchedule(id: string, date: string) {
|
||||
const itemFound: any = schedules?.filter((s: any) => s.dateInRange.includes(date) && s.timeIndex.split(",").includes(id));
|
||||
const itemFound: any = schedules?.filter(
|
||||
(s: any) =>
|
||||
s.dateInRange.includes(date) && s.timeIndex.split(",").includes(id)
|
||||
);
|
||||
|
||||
if (itemFound?.length > 0) {
|
||||
if (itemFound?.length == 1) {
|
||||
return (
|
||||
<a
|
||||
className={`cursor-pointer text-center ${Number(itemFound[0]?.uploaderLevelNumber) == 1 ? "bg-yellow-300" : Number(itemFound[0]?.uploaderLevelNumber) == 2 ? "bg-blue-400" : "bg-gray-500"}`}
|
||||
className={`cursor-pointer text-center ${
|
||||
Number(itemFound[0]?.uploaderLevelNumber) == 1
|
||||
? "bg-yellow-300"
|
||||
: Number(itemFound[0]?.uploaderLevelNumber) == 2
|
||||
? "bg-blue-400"
|
||||
: "bg-gray-500"
|
||||
}`}
|
||||
onClick={() => {
|
||||
getItem(itemFound[0]);
|
||||
}}
|
||||
|
|
@ -452,7 +501,9 @@ const Schedule = (props: any) => {
|
|||
<b>{`${itemFound?.length} Jadwal Bersamaan`}</b>
|
||||
</p>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger className="font-bold text-blue-300">Lihat Jadwal</DropdownMenuTrigger>
|
||||
<DropdownMenuTrigger className="font-bold text-blue-300">
|
||||
Lihat Jadwal
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{itemFound?.map((list: any) => (
|
||||
<DropdownMenuItem
|
||||
|
|
@ -471,7 +522,10 @@ const Schedule = (props: any) => {
|
|||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<div className="border-0 dropdown-menu schedule-list" aria-labelledby="view-schedule"></div>
|
||||
<div
|
||||
className="border-0 dropdown-menu schedule-list"
|
||||
aria-labelledby="view-schedule"
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -480,73 +534,121 @@ const Schedule = (props: any) => {
|
|||
return (
|
||||
<>
|
||||
{/* Awal Komponen Kiri */}
|
||||
<div className="relative px-4 lg:px-10 lg:py-10 py-4 bg-[#f7f7f7] dark:bg-slate-800">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant={"outline"} className={cn("w-[240px] py-4 justify-start text-left font-normal", !startDate && "text-muted-foreground")}>
|
||||
<CalendarIcon />
|
||||
{startDate ? format(startDate, "MMM yyyy") : <span>Pick a date</span>}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={startDate}
|
||||
onSelect={(e) => {
|
||||
handleChangeDate(e);
|
||||
}}
|
||||
initialFocus
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
<div className="container relative py-4">
|
||||
<div className="relative pl-4 lg:px-8 lg:py-10 py-4 bg-[#f7f7f7] dark:bg-slate-800">
|
||||
<div className="flex flex-row items-center">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<a className="text-black dark:text-white flex flex-row w-fit gap-2 py-4 items-center cursor-pointer">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M20 3H4a1 1 0 0 0-1 1v2.227l.008.223a3 3 0 0 0 .772 1.795L8 12.886V21a1 1 0 0 0 1.316.949l6-2l.108-.043A1 1 0 0 0 16 19v-6.586l4.121-4.12A3 3 0 0 0 21 6.171V4a1 1 0 0 0-1-1" />
|
||||
</svg>
|
||||
Filter
|
||||
<svg className="flex items-center justify-center" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" fill-rule="evenodd" d="m6 7l6 6l6-6l2 2l-8 8l-8-8z" />
|
||||
</svg>
|
||||
</a>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[240px] py-3 justify-start text-left font-normal",
|
||||
!startDate && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
<CalendarIcon />
|
||||
{startDate ? (
|
||||
format(startDate, "MMM yyyy")
|
||||
) : (
|
||||
<span>Pick a date</span>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="start" className="flex p-0 rounded-md w-fit">
|
||||
<div className="flex flex-col items-center justify-between gap-1.5 p-2 border-b text-default-600 rounded-none">
|
||||
<div className="gap-6 flex flex-row justify-end">
|
||||
<p className="font-semibold">Filter</p>
|
||||
<button className="text-blue-400" onClick={doFilter}>
|
||||
{t("save")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="border w-full border-t border-slate-500"></div>
|
||||
<div className="overflow-y-auto flex flex-col gap-2 h-[200px] ">
|
||||
<p className="text-center font-semibold">Region Filter</p>
|
||||
{city?.map((list) => (
|
||||
<div className="mt-2 gap-2 flex flex-row">
|
||||
{" "}
|
||||
<input type="checkbox" className="" id={`filterCategory-${list.key}`} value={list.id} checked={regionFilter?.includes(list.id)} onChange={handleRegionFilter} />
|
||||
<p>{list?.name}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={startDate}
|
||||
onSelect={(e) => {
|
||||
handleChangeDate(e);
|
||||
}}
|
||||
initialFocus
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<div className="flex flex-col lg:flex-row gap-3">
|
||||
{regionName?.map((list: any) => (
|
||||
<div className="text-left">
|
||||
<button onClick={() => deleteFilterhandler(list.id)} key={list.key} id={list.id} className="text-black bg-yellow-300 w-fit p-3 flex justify-center items-center rounded-lg">
|
||||
{list.name}
|
||||
<Icon icon="icon-park-outline:delete-two" className="items-center" />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className="container relative py-4 flex flex-row items-center gap-4">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<a className="text-black dark:text-white flex flex-row w-fit gap-3 py-2 px-3 items-center cursor-pointer border border-black rounded-md ">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M20 3H4a1 1 0 0 0-1 1v2.227l.008.223a3 3 0 0 0 .772 1.795L8 12.886V21a1 1 0 0 0 1.316.949l6-2l.108-.043A1 1 0 0 0 16 19v-6.586l4.121-4.12A3 3 0 0 0 21 6.171V4a1 1 0 0 0-1-1"
|
||||
/>
|
||||
</svg>
|
||||
Filter
|
||||
<svg
|
||||
className="flex items-center justify-center"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
d="m6 7l6 6l6-6l2 2l-8 8l-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
align="start"
|
||||
className="flex p-0 rounded-md w-fit"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-between gap-1.5 p-2 border-b text-default-600 rounded-none">
|
||||
<div className="gap-6 flex flex-row justify-end">
|
||||
<p className="font-semibold">Filter</p>
|
||||
<button className="text-blue-400" onClick={doFilter}>
|
||||
{t("save")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="border w-full border-t border-slate-500"></div>
|
||||
<div className="overflow-y-auto flex flex-col gap-2 h-[200px] ">
|
||||
<p className="text-center font-semibold">Region Filter</p>
|
||||
{city?.map((list) => (
|
||||
<div className="mt-2 gap-2 flex flex-row">
|
||||
{" "}
|
||||
<input
|
||||
type="checkbox"
|
||||
className=""
|
||||
id={`filterCategory-${list.key}`}
|
||||
value={list.id}
|
||||
checked={regionFilter?.includes(list.id)}
|
||||
onChange={handleRegionFilter}
|
||||
/>
|
||||
<p>{list?.name}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<div className="flex flex-col lg:flex-row gap-3">
|
||||
{regionName?.map((list: any) => (
|
||||
<div className="text-left">
|
||||
<button
|
||||
onClick={() => deleteFilterhandler(list.id)}
|
||||
key={list.key}
|
||||
id={list.id}
|
||||
className="text-black bg-yellow-300 w-fit p-3 flex justify-center items-center rounded-lg"
|
||||
>
|
||||
{list.name}
|
||||
<Icon
|
||||
icon="icon-park-outline:delete-two"
|
||||
className="items-center"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col lg:flex-row gap-6">
|
||||
<div className="flex flex-col lg:flex-row gap-1">
|
||||
<div className="h-[500px] overflow-y-auto md:overflow-y-auto w-full lg:w-3/4 ">
|
||||
<div className="container-fluid relative">
|
||||
<div className="grid grid-cols-1 mt-8">
|
||||
|
|
@ -554,53 +656,125 @@ const Schedule = (props: any) => {
|
|||
<table className="w-full text-sm text-start">
|
||||
<thead className="text-md">
|
||||
<tr className="h-full">
|
||||
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[120px]">{t("timeTable")}</th>
|
||||
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[210px]">
|
||||
{t("timeTable")}
|
||||
</th>
|
||||
<th className="text-center border border-r-0 border-gray-100 dark:border-gray-700 py-6 w-[20px]">
|
||||
<a onClick={() => changePrevWeek()} className="cursor-pointer h-fit self-center bottom-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M12.29 8.71L9.7 11.3a.996.996 0 0 0 0 1.41l2.59 2.59c.63.63 1.71.18 1.71-.71V9.41c0-.89-1.08-1.33-1.71-.7" />
|
||||
<a
|
||||
onClick={() => changePrevWeek()}
|
||||
className="cursor-pointer h-fit self-center bottom-0"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="40px"
|
||||
height="40px"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12.29 8.71L9.7 11.3a.996.996 0 0 0 0 1.41l2.59 2.59c.63.63 1.71.18 1.71-.71V9.41c0-.89-1.08-1.33-1.71-.7"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</th>
|
||||
<th className={`text-center cursor-pointer border border-l-0 h-full border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${new Date().toISOString().slice(0, 10) == dateAWeek[0] ? "bg-red-600 text-white" : ""}`}>
|
||||
<th
|
||||
className={`text-center cursor-pointer border border-l-0 h-full border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${
|
||||
new Date().toISOString().slice(0, 10) ==
|
||||
dateAWeek[0]
|
||||
? "bg-red-600 text-white"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{/* <a className="cursor-pointer h-fit self-center bottom-0" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M12.29 8.71L9.7 11.3a.996.996 0 0 0 0 1.41l2.59 2.59c.63.63 1.71.18 1.71-.71V9.41c0-.89-1.08-1.33-1.71-.7" />
|
||||
</svg>
|
||||
</a>{" "} */}
|
||||
<div className="flex flex-col ">
|
||||
<p className="text-2xl">{dateAWeek[0]?.split("-")[2]}</p>
|
||||
<p className="text-2xl">
|
||||
{dateAWeek[0]?.split("-")[2]}
|
||||
</p>
|
||||
<p>{t("monday")}</p>
|
||||
</div>
|
||||
</th>
|
||||
<th className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${new Date().toISOString().slice(0, 10) == dateAWeek[1] ? "bg-[#BE0106] text-white rounded-lg" : ""}`}>
|
||||
<div className="text-2xl">{dateAWeek[1]?.split("-")[2]}</div>
|
||||
<th
|
||||
className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${
|
||||
new Date().toISOString().slice(0, 10) ==
|
||||
dateAWeek[1]
|
||||
? "bg-[#BE0106] text-white rounded-lg"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="text-2xl">
|
||||
{dateAWeek[1]?.split("-")[2]}
|
||||
</div>
|
||||
{t("tuesday")}
|
||||
</th>
|
||||
<th className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${new Date().toISOString().slice(0, 10) == dateAWeek[2] ? "bg-[#BE0106] text-white rounded-lg" : ""}`}>
|
||||
<div className="text-2xl">{dateAWeek[2]?.split("-")[2]}</div>
|
||||
<th
|
||||
className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${
|
||||
new Date().toISOString().slice(0, 10) ==
|
||||
dateAWeek[2]
|
||||
? "bg-[#BE0106] text-white rounded-lg"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="text-2xl">
|
||||
{dateAWeek[2]?.split("-")[2]}
|
||||
</div>
|
||||
{t("wednesday")}
|
||||
</th>
|
||||
<th className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${new Date().toISOString().slice(0, 10) == dateAWeek[3] ? "bg-[#BE0106] text-white rounded-lg" : ""}`}>
|
||||
<div className="text-2xl">{dateAWeek[3]?.split("-")[2]}</div>
|
||||
<th
|
||||
className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${
|
||||
new Date().toISOString().slice(0, 10) ==
|
||||
dateAWeek[3]
|
||||
? "bg-[#BE0106] text-white rounded-lg"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="text-2xl">
|
||||
{dateAWeek[3]?.split("-")[2]}
|
||||
</div>
|
||||
{t("thursday")}
|
||||
</th>
|
||||
<th className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${new Date().toISOString().slice(0, 10) == dateAWeek[4] ? "bg-[#BE0106] text-white rounded-lg" : ""}`}>
|
||||
<div className="text-2xl">{dateAWeek[4]?.split("-")[2]}</div>
|
||||
<th
|
||||
className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${
|
||||
new Date().toISOString().slice(0, 10) ==
|
||||
dateAWeek[4]
|
||||
? "bg-[#BE0106] text-white rounded-lg"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="text-2xl">
|
||||
{dateAWeek[4]?.split("-")[2]}
|
||||
</div>
|
||||
{t("friday")}
|
||||
</th>
|
||||
<th className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${new Date().toISOString().slice(0, 10) == dateAWeek[5] ? "bg-[#BE0106] text-white rounded-lg" : ""}`}>
|
||||
<div className="text-2xl">{dateAWeek[5]?.split("-")[2]}</div>
|
||||
<th
|
||||
className={`text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${
|
||||
new Date().toISOString().slice(0, 10) ==
|
||||
dateAWeek[5]
|
||||
? "bg-[#BE0106] text-white rounded-lg"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="text-2xl">
|
||||
{dateAWeek[5]?.split("-")[2]}
|
||||
</div>
|
||||
{t("saturday")}
|
||||
</th>
|
||||
<th
|
||||
onClick={() => changeNextWeek()}
|
||||
className={`text-center border cursor-pointer border-r-0 border-gray-100 dark:border-gray-700 py-6 min-w-[100px] ${
|
||||
new Date().toISOString().slice(0, 10) == dateAWeek[6] ? "bg-[#BE0106] text-white rounded-lg" : ""
|
||||
new Date().toISOString().slice(0, 10) ==
|
||||
dateAWeek[6]
|
||||
? "bg-[#BE0106] text-white rounded-lg"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col ">
|
||||
<p className="text-2xl">{dateAWeek[6]?.split("-")[2]}</p>
|
||||
<p className="text-2xl">
|
||||
{dateAWeek[6]?.split("-")[2]}
|
||||
</p>
|
||||
<p>{t("sunday")}</p>
|
||||
</div>
|
||||
{/* <a className="cursor-pointer h-fit p-0 m-0 self-center">
|
||||
|
|
@ -610,9 +784,20 @@ const Schedule = (props: any) => {
|
|||
</a> */}
|
||||
</th>
|
||||
<th className="text-center border-l-0 border border-gray-100 dark:border-gray-700 py-6 w-[20px]">
|
||||
<a onClick={() => changeNextWeek()} className="cursor-pointer">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="m11.71 15.29l2.59-2.59a.996.996 0 0 0 0-1.41L11.71 8.7c-.63-.62-1.71-.18-1.71.71v5.17c0 .9 1.08 1.34 1.71.71" />
|
||||
<a
|
||||
onClick={() => changeNextWeek()}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="40px"
|
||||
height="40px"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="m11.71 15.29l2.59-2.59a.996.996 0 0 0 0-1.41L11.71 8.7c-.63-.62-1.71-.18-1.71.71v5.17c0 .9 1.08 1.34 1.71.71"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</th>
|
||||
|
|
@ -621,16 +806,34 @@ const Schedule = (props: any) => {
|
|||
<tbody>
|
||||
{timeList.map((times) => (
|
||||
<tr key={times.id}>
|
||||
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">{times.time}</th>
|
||||
<td colSpan={2} className="p-3 border border-gray-100 dark:border-gray-700 ">
|
||||
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">
|
||||
{times.time}
|
||||
</th>
|
||||
<td
|
||||
colSpan={2}
|
||||
className="p-3 border border-gray-100 dark:border-gray-700 "
|
||||
>
|
||||
{setItemSchedule(times.id, dateList[0])}
|
||||
</td>
|
||||
<td className="border border-gray-100 dark:border-gray-700">{setItemSchedule(times.id, dateList[1])}</td>
|
||||
<td className="border border-gray-100 dark:border-gray-700">{setItemSchedule(times.id, dateList[2])}</td>
|
||||
<td className="border border-gray-100 dark:border-gray-700">{setItemSchedule(times.id, dateList[3])}</td>
|
||||
<td className="p-3 border border-gray-100 dark:border-gray-700">{setItemSchedule(times.id, dateList[4])}</td>
|
||||
<td className="border border-gray-100 dark:border-gray-700">{setItemSchedule(times.id, dateList[5])}</td>
|
||||
<td colSpan={2} className="border border-gray-100 dark:border-gray-700">
|
||||
<td className="border border-gray-100 dark:border-gray-700">
|
||||
{setItemSchedule(times.id, dateList[1])}
|
||||
</td>
|
||||
<td className="border border-gray-100 dark:border-gray-700">
|
||||
{setItemSchedule(times.id, dateList[2])}
|
||||
</td>
|
||||
<td className="border border-gray-100 dark:border-gray-700">
|
||||
{setItemSchedule(times.id, dateList[3])}
|
||||
</td>
|
||||
<td className="p-3 border border-gray-100 dark:border-gray-700">
|
||||
{setItemSchedule(times.id, dateList[4])}
|
||||
</td>
|
||||
<td className="border border-gray-100 dark:border-gray-700">
|
||||
{setItemSchedule(times.id, dateList[5])}
|
||||
</td>
|
||||
<td
|
||||
colSpan={2}
|
||||
className="border border-gray-100 dark:border-gray-700"
|
||||
>
|
||||
{setItemSchedule(times.id, dateList[6])}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -654,10 +857,18 @@ const Schedule = (props: any) => {
|
|||
className="pl-8 pr-4 py-1 w-full border rounded-full text-sm focus:outline-none"
|
||||
/>
|
||||
<span className="absolute left-2 top-1/2 transform -translate-y-1/2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
<path fill="currentColor" d="M10.5 2a8.5 8.5 0 1 0 5.262 15.176l3.652 3.652a1 1 0 0 0 1.414-1.414l-3.652-3.652A8.5 8.5 0 0 0 10.5 2M4 10.5a6.5 6.5 0 1 1 13 0a6.5 6.5 0 0 1-13 0" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M10.5 2a8.5 8.5 0 1 0 5.262 15.176l3.652 3.652a1 1 0 0 0 1.414-1.414l-3.652-3.652A8.5 8.5 0 0 0 10.5 2M4 10.5a6.5 6.5 0 1 1 13 0a6.5 6.5 0 0 1-13 0"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
|
|
@ -700,8 +911,13 @@ const Schedule = (props: any) => {
|
|||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>{t("todaySchedule")}</AccordionTrigger>
|
||||
{todayList?.map((list: any) => (
|
||||
<AccordionContent key={list?.id} className="flex flex-row gap-3">
|
||||
<div className="border-l-4 border-red-700 pl-1 h-fit font-bold text-lg">{new Date(list.startDate).getDate()}</div>
|
||||
<AccordionContent
|
||||
key={list?.id}
|
||||
className="flex flex-row gap-3"
|
||||
>
|
||||
<div className="border-l-4 border-red-700 pl-1 h-fit font-bold text-lg">
|
||||
{new Date(list.startDate).getDate()}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<h3 className="font-bold">{list?.title}</h3>
|
||||
<p className="flex flex-row items-center gap-2">
|
||||
|
|
@ -725,8 +941,13 @@ const Schedule = (props: any) => {
|
|||
<AccordionItem value="item-2">
|
||||
<AccordionTrigger>{t("previousSchedule")}</AccordionTrigger>
|
||||
{prevdayList?.map((list: any) => (
|
||||
<AccordionContent key={list?.id} className="flex flex-row gap-3">
|
||||
<div className="border-l-4 border-red-700 pl-1 h-fit font-bold text-lg">{new Date(list.startDate).getDate()}</div>
|
||||
<AccordionContent
|
||||
key={list?.id}
|
||||
className="flex flex-row gap-3"
|
||||
>
|
||||
<div className="border-l-4 border-red-700 pl-1 h-fit font-bold text-lg">
|
||||
{new Date(list.startDate).getDate()}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<h3 className="font-bold">{list?.title}</h3>
|
||||
<p className="flex flex-row items-center gap-2">
|
||||
|
|
@ -750,8 +971,13 @@ const Schedule = (props: any) => {
|
|||
<AccordionItem value="item-3">
|
||||
<AccordionTrigger>{t("nextSchedule")}</AccordionTrigger>
|
||||
{nextdayList?.map((list: any) => (
|
||||
<AccordionContent key={list?.id} className="flex flex-row gap-3">
|
||||
<div className="border-l-4 border-red-700 pl-1 h-fit font-bold text-lg">{new Date(list.startDate).getDate()}</div>
|
||||
<AccordionContent
|
||||
key={list?.id}
|
||||
className="flex flex-row gap-3"
|
||||
>
|
||||
<div className="border-l-4 border-red-700 pl-1 h-fit font-bold text-lg">
|
||||
{new Date(list.startDate).getDate()}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<h3 className="font-bold">{list?.title}</h3>
|
||||
<p className="flex flex-row items-center gap-2">
|
||||
|
|
@ -846,13 +1072,17 @@ const Schedule = (props: any) => {
|
|||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
<h1 className="my-4 font-light">JADWAL / {detail?.isYoutube == true ? "LIVE STREAMING" : "DETAIL"}</h1>
|
||||
<h1 className="my-4 font-light">
|
||||
JADWAL /{" "}
|
||||
{detail?.isYoutube == true ? "LIVE STREAMING" : "DETAIL"}
|
||||
</h1>
|
||||
<p className="font-bold">{detail?.title}</p>
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
<p className="flex flex-row items-center gap-2">
|
||||
<Icon icon="iconamoon:clock-thin" />
|
||||
{detail?.date} {detail?.startTime} - {detail?.endTime} {detail?.timezone ? detail.timezone : "WIB"}
|
||||
{detail?.date} {detail?.startTime} - {detail?.endTime}{" "}
|
||||
{detail?.timezone ? detail.timezone : "WIB"}
|
||||
</p>
|
||||
</AlertDialogDescription>
|
||||
<AlertDialogDescription>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,16 @@ import {
|
|||
import { Label } from "../ui/label";
|
||||
import { Input } from "../ui/input";
|
||||
import { Button } from "../ui/button";
|
||||
import { Textarea } from "../ui/textarea";
|
||||
import { Checkbox } from "../ui/checkbox";
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "../ui/dialog";
|
||||
|
||||
const HeroModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const [heroData, setHeroData] = useState<any>();
|
||||
|
|
@ -85,7 +95,7 @@ const HeroModal = ({ onClose }: { onClose: () => void }) => {
|
|||
className="w-full h-[310px] lg:h-[420px] rounded-lg object-cover"
|
||||
/>
|
||||
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-black/30 backdrop-blur-sm text-white pb-4 px-4 pt-8 rounded-bl-2xl rounded-tr-2xl mx-3 mb-2">
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-black/30 backdrop-brightness-50 text-white pb-4 px-4 pt-8 rounded-bl-2xl rounded-tr-2xl mx-3 mb-2">
|
||||
<div className="absolute top-0 left-0 bottom-0 w-2 bg-[#bb3523] rounded-bl-lg"></div>
|
||||
<span className="absolute top-0 left-0 mt-2 mb-3 mx-3 bg-[#bb3523] text-white text-xs font-semibold uppercase px-2 py-1 rounded">
|
||||
{list?.categoryName || "Liputan Kegiatan"}
|
||||
|
|
@ -125,6 +135,223 @@ const HeroModal = ({ onClose }: { onClose: () => void }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const SurveyIntroModal = ({ onNext }: { onNext: () => void }) => {
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
|
||||
<div className="relative bg-white rounded-xl p-6 w-[90%] max-w-md text-center">
|
||||
<button
|
||||
onClick={onNext}
|
||||
className="absolute top-3 right-3 text-gray-500 hover:text-black"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
|
||||
<Image
|
||||
src="/assets/survey.jpg"
|
||||
alt="Survey Illustration"
|
||||
width={300}
|
||||
height={200}
|
||||
className="mx-auto my-4"
|
||||
/>
|
||||
|
||||
<button
|
||||
onClick={onNext}
|
||||
className="mt-4 bg-red-600 hover:bg-red-700 text-white font-semibold py-3 px-6 rounded w-full"
|
||||
>
|
||||
Lihat Selengkapnya
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const options = {
|
||||
q1: [
|
||||
"Setiap hari",
|
||||
"Beberapa kali seminggu",
|
||||
"Beberapa kali dalam sebulan",
|
||||
"Baru pertama kali",
|
||||
],
|
||||
q2a: ["Sangat baik", "Baik", "Cukup", "Kurang", "Buruk"],
|
||||
q2b: ["Sangat mudah", "Mudah", "Cukup", "Sulit", "Sangat sulit"],
|
||||
q2c: ["Sangat cepat", "Cepat", "Cukup", "Lambat", "Sangat lambat"],
|
||||
q3a: ["Sangat puas", "Puas", "Cukup", "Kurang puas", "Tidak puas"],
|
||||
q3b: [
|
||||
"Sangat lengkap",
|
||||
"Lengkap",
|
||||
"Cukup",
|
||||
"Kurang lengkap",
|
||||
"Tidak lengkap",
|
||||
],
|
||||
q4: [
|
||||
"Sangat membantu",
|
||||
"Membantu",
|
||||
"Cukup membantu",
|
||||
"Kurang membantu",
|
||||
"Tidak membantu",
|
||||
],
|
||||
};
|
||||
|
||||
const SurveyFormModal = ({ onClose }: { onClose: () => void }) => {
|
||||
return (
|
||||
<Dialog
|
||||
open
|
||||
onOpenChange={(open) => {
|
||||
if (!open) onClose();
|
||||
}}
|
||||
>
|
||||
<DialogContent className="w-[400px] h-[600px] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-lg font-bold">
|
||||
SURVEI KEPUASAN PENGGUNA MEDIAHUB POLRI
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-sm">
|
||||
Kami menghargai pendapat Anda! Survei ini bertujuan untuk
|
||||
meningkatkan kualitas layanan MediaHub Polri. Mohon luangkan waktu
|
||||
beberapa menit untuk mengisi survei ini.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4 mt-4">
|
||||
{/* 1 */}
|
||||
<div>
|
||||
<p className="font-medium">
|
||||
1. Seberapa sering Anda mengakses MediaHub Polri?
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-2 mt-2">
|
||||
{options.q1.map((item, i) => (
|
||||
<label key={i} className="flex items-center space-x-2">
|
||||
<Checkbox id={`q1-${i}`} />
|
||||
<span>{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 2 */}
|
||||
<div>
|
||||
<p className="font-medium">
|
||||
2. Bagaimana pengalaman Anda dalam mengakses website ini?
|
||||
</p>
|
||||
<div className="mt-2 space-y-3">
|
||||
<div>
|
||||
<p className="text-sm font-medium">
|
||||
a) Tampilan dan desain website
|
||||
</p>
|
||||
<div className="grid grid-cols-3 gap-2 mt-1">
|
||||
{options.q2a.map((item, i) => (
|
||||
<label key={i} className="flex items-center space-x-2">
|
||||
<Checkbox id={`q2a-${i}`} />
|
||||
<span>{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium">
|
||||
b) Kemudahan navigasi (pencarian informasi, menu, dll)
|
||||
</p>
|
||||
<div className="grid grid-cols-3 gap-2 mt-1">
|
||||
{options.q2b.map((item, i) => (
|
||||
<label key={i} className="flex items-center space-x-2">
|
||||
<Checkbox id={`q2b-${i}`} />
|
||||
<span>{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium">
|
||||
c) Kecepatan akses website
|
||||
</p>
|
||||
<div className="grid grid-cols-3 gap-2 mt-1">
|
||||
{options.q2c.map((item, i) => (
|
||||
<label key={i} className="flex items-center space-x-2">
|
||||
<Checkbox id={`q2c-${i}`} />
|
||||
<span>{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 3 */}
|
||||
<div>
|
||||
<p className="font-medium">
|
||||
3. Seberapa puas Anda dengan informasi yang tersedia di MediaHub
|
||||
Polri?
|
||||
</p>
|
||||
<div className="mt-2 space-y-3">
|
||||
<div>
|
||||
<p className="text-sm font-medium">a) Akurat dan terpercaya</p>
|
||||
<div className="grid grid-cols-3 gap-2 mt-1">
|
||||
{options.q3a.map((item, i) => (
|
||||
<label key={i} className="flex items-center space-x-2">
|
||||
<Checkbox id={`q3a-${i}`} />
|
||||
<span>{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium">
|
||||
b) Kelengkapan berita dan informasi
|
||||
</p>
|
||||
<div className="grid grid-cols-3 gap-2 mt-1">
|
||||
{options.q3b.map((item, i) => (
|
||||
<label key={i} className="flex items-center space-x-2">
|
||||
<Checkbox id={`q3b-${i}`} />
|
||||
<span>{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 4 */}
|
||||
<div>
|
||||
<p className="font-medium">
|
||||
5. Apakah Anda merasa website ini membantu dalam mendapatkan
|
||||
informasi terkait Polri?
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-2 mt-2">
|
||||
{options.q4.map((item, i) => (
|
||||
<label key={i} className="flex items-center space-x-2">
|
||||
<Checkbox id={`q4-${i}`} />
|
||||
<span>{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 5 */}
|
||||
<div>
|
||||
<p className="font-medium">
|
||||
6. Apa saran atau masukan Anda untuk meningkatkan layanan MediaHub
|
||||
Polri?
|
||||
</p>
|
||||
<Textarea placeholder="Tulis pesan Anda" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-2 mt-6">
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Batal</Button>
|
||||
</DialogClose>
|
||||
<Button>Kirim</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
const ONE_HOUR = 60 * 60 * 1000;
|
||||
|
||||
const Hero: React.FC = () => {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
|
@ -133,6 +360,8 @@ const Hero: React.FC = () => {
|
|||
const [isLoading, setIsLoading] = useState<any>(true);
|
||||
const [heroData, setHeroData] = useState<any>();
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [showSurveyModal, setShowSurveyModal] = useState(false);
|
||||
const [showFormModal, setShowFormModal] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
|
|
@ -145,11 +374,25 @@ const Hero: React.FC = () => {
|
|||
useEffect(() => {
|
||||
const roleId = Cookies.get("urie");
|
||||
if (!roleId) {
|
||||
setShowModal(true); // hanya munculkan modal jika urie tidak ada
|
||||
setShowModal(true);
|
||||
}
|
||||
initFetch();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const roleId = Cookies.get("urie");
|
||||
const lastShown = Cookies.get("surveyLastShown");
|
||||
|
||||
const now = new Date().getTime();
|
||||
|
||||
if (roleId && (!lastShown || now - parseInt(lastShown) > ONE_HOUR)) {
|
||||
setShowSurveyModal(true);
|
||||
Cookies.set("surveyLastShown", now.toString(), { expires: 1 });
|
||||
}
|
||||
|
||||
initFetch();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchCategories() {
|
||||
const url = "https://netidhub.com/api/csrf";
|
||||
|
|
@ -201,6 +444,18 @@ const Hero: React.FC = () => {
|
|||
<div className="flex flex-col lg:flex-row items-start justify-center gap-8 px-4 lg:px-20 py-4 mx-auto w-auto mt-6">
|
||||
<div className="relative">
|
||||
{showModal && <HeroModal onClose={() => setShowModal(false)} />}
|
||||
{showSurveyModal && !showFormModal && (
|
||||
<SurveyIntroModal
|
||||
onNext={() => {
|
||||
setShowSurveyModal(false);
|
||||
setShowFormModal(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showFormModal && (
|
||||
<SurveyFormModal onClose={() => setShowFormModal(false)} />
|
||||
)}
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<div className="flex flex-col space-y-3 mx-auto w-full lg:w-2/3">
|
||||
|
|
@ -227,7 +482,7 @@ const Hero: React.FC = () => {
|
|||
className="w-full h-[310px] lg:h-[420px] rounded-lg object-cover"
|
||||
/>
|
||||
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-black/30 backdrop-blur-sm text-white pb-4 px-4 pt-8 rounded-bl-2xl rounded-tr-2xl mx-3 mb-2">
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-black/30 backdrop-brightness-50 text-white pb-4 px-4 pt-8 rounded-bl-2xl rounded-tr-2xl mx-3 mb-2">
|
||||
<div className="absolute top-0 left-0 bottom-0 w-2 bg-[#bb3523] rounded-bl-lg"></div>
|
||||
<span className="absolute top-0 left-0 mt-2 mb-3 mx-3 bg-[#bb3523] text-white text-xs font-semibold uppercase px-2 py-1 rounded">
|
||||
{list?.categoryName || "Liputan Kegiatan"}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,13 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||
import { z } from "zod";
|
||||
import { cn, setCookiesEncrypt } from "@/lib/utils";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { getProfile, login, requestOTP } from "@/service/auth";
|
||||
import {
|
||||
getProfile,
|
||||
login,
|
||||
postEmailValidation,
|
||||
postSetupEmail,
|
||||
requestOTP,
|
||||
} from "@/service/auth";
|
||||
import { toast } from "sonner";
|
||||
import { useRouter } from "@/components/navigation";
|
||||
import { warning } from "@/lib/swal";
|
||||
|
|
@ -45,16 +51,28 @@ const LoginForm = () => {
|
|||
const [passwordType, setPasswordType] = React.useState("password");
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
const [isOtpStep, setIsOtpStep] = useState(false);
|
||||
const [step, setStep] = useState<number>(1);
|
||||
const [otpValue, setOtpValue] = useState("");
|
||||
const [userIdentity] = useState();
|
||||
const [email, setEmail] = useState();
|
||||
const [category, setCategory] = useState("5");
|
||||
|
||||
const handleSignInClick = () => {
|
||||
handleSendOTP();
|
||||
setIsOtpStep(true);
|
||||
};
|
||||
// const handleSignInClick = () => {
|
||||
// handleSendOTP();
|
||||
// setIsOtpStep(true);
|
||||
// };
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [oldEmail, setOldEmail] = useState("");
|
||||
const [oldEmailValidate, setOldEmailValidate] = useState("");
|
||||
const [newEmail, setNewEmail] = useState("");
|
||||
const [newEmailValidate, setNewEmailValidate] = useState("");
|
||||
|
||||
// const handleSignInClick = () => {
|
||||
// handleSendOTP();
|
||||
// setIsOtpStep(true);
|
||||
// };
|
||||
|
||||
const [otp1, setOtp1] = useState();
|
||||
const [otp2, setOtp2] = useState();
|
||||
|
|
@ -259,9 +277,57 @@ const LoginForm = () => {
|
|||
// });
|
||||
};
|
||||
|
||||
const handleEmailValidation = async () => {
|
||||
const data = {
|
||||
username: username,
|
||||
password: password,
|
||||
};
|
||||
|
||||
loading();
|
||||
const response = await postEmailValidation(data);
|
||||
close();
|
||||
if (response.error) {
|
||||
error(response.message);
|
||||
return false;
|
||||
}
|
||||
const msg = response.data?.message;
|
||||
if (msg == "Continue to setup email") {
|
||||
setStep(2);
|
||||
} else if (msg == "Email is valid and OTP has been sent") {
|
||||
setStep(3);
|
||||
} else if (msg == "Username & password valid") {
|
||||
onSubmit(data);
|
||||
} else {
|
||||
error("Username / password incorrect");
|
||||
}
|
||||
};
|
||||
|
||||
const handleSetupEmail = async () => {
|
||||
const data = {
|
||||
username: username,
|
||||
password: password,
|
||||
oldEmail: oldEmail,
|
||||
newEmail: newEmail,
|
||||
};
|
||||
|
||||
loading();
|
||||
const response = await postSetupEmail(data);
|
||||
close();
|
||||
if (response.error) {
|
||||
error(response.message);
|
||||
return false;
|
||||
}
|
||||
const msg = response.data?.message;
|
||||
if (msg == "Email is valid and OTP has been sent") {
|
||||
setStep(3);
|
||||
} else if (msg == "The old email is not same") {
|
||||
error("Email is invalid");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="mt-5 2xl:mt-7 space-y-4">
|
||||
{!isOtpStep && (
|
||||
{step === 1 ? (
|
||||
<>
|
||||
<div className="text-left 2xl:mb-10 mb-4 mt-10">
|
||||
<h4 className="font-semibold text-3xl text-left">
|
||||
|
|
@ -324,13 +390,75 @@ const LoginForm = () => {
|
|||
{t("forgotPass")}
|
||||
</Link>
|
||||
</div>
|
||||
<Button fullWidth onClick={handleSignInClick}>
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
onClick={handleEmailValidation}
|
||||
disabled={isPending}
|
||||
>
|
||||
Selanjutnya
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{isOtpStep && (
|
||||
) : step === 2 ? (
|
||||
<>
|
||||
<div className="text-left 2xl:mb-10 mb-4">
|
||||
<h4 className="font-semibold text-3xl text-left">
|
||||
Anda perlu memasukkan email baru untuk bisa Login.
|
||||
</h4>
|
||||
</div>
|
||||
<div className="flex flex-col justify-center mb-6">
|
||||
<div className="space-y-2">
|
||||
<Label
|
||||
htmlFor="username"
|
||||
className="font-medium text-default-600"
|
||||
>
|
||||
Email Lama <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
size="lg"
|
||||
disabled={isPending}
|
||||
onChange={(e) => setOldEmail(e.target.value)}
|
||||
id="oldEmail"
|
||||
type="email"
|
||||
className={cn("", {
|
||||
"border-destructive": errors.username,
|
||||
})}
|
||||
/>
|
||||
{errors.username?.message && (
|
||||
<div className="text-destructive mt-2 text-sm">
|
||||
{errors.username.message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label
|
||||
htmlFor="username"
|
||||
className="font-medium text-default-600"
|
||||
>
|
||||
Email Baru <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
size="lg"
|
||||
disabled={isPending}
|
||||
onChange={(e) => setNewEmail(e.target.value)}
|
||||
id="newEmail"
|
||||
type="email"
|
||||
className={cn("", {
|
||||
"border-destructive": errors.username,
|
||||
})}
|
||||
/>
|
||||
{errors.username?.message && (
|
||||
<div className="text-destructive mt-2 text-sm">
|
||||
{errors.username.message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Button fullWidth className="bg-red-500">
|
||||
Sign in
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="text-left 2xl:mb-10 mb-4 mt-10">
|
||||
<h4 className="font-semibold text-3xl text-left">
|
||||
|
|
|
|||
56
lib/menus.ts
56
lib/menus.ts
|
|
@ -292,34 +292,34 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/settings/feedback",
|
||||
label: "Feedback",
|
||||
active: pathname === "/admin/settings/feedback",
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/settings/faq",
|
||||
label: "FAQ",
|
||||
active: pathname === "/admin/settings/faq",
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "https://nat-mediahub.polri.go.id/",
|
||||
label: "Mediahub 2022",
|
||||
active: pathname === "/admin/settings/mediahub-2022",
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/settings/privacy",
|
||||
label: t("privacy"),
|
||||
active: pathname === "/admin/settings/privacy",
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
// {
|
||||
// href: "/admin/settings/feedback",
|
||||
// label: "Feedback",
|
||||
// active: pathname === "/admin/settings/feedback",
|
||||
// icon: "heroicons:arrow-trending-up",
|
||||
// children: [],
|
||||
// },
|
||||
// {
|
||||
// href: "/admin/settings/faq",
|
||||
// label: "FAQ",
|
||||
// active: pathname === "/admin/settings/faq",
|
||||
// icon: "heroicons:arrow-trending-up",
|
||||
// children: [],
|
||||
// },
|
||||
// {
|
||||
// href: "https://nat-mediahub.polri.go.id/",
|
||||
// label: "Mediahub 2022",
|
||||
// active: pathname === "/admin/settings/mediahub-2022",
|
||||
// icon: "heroicons:arrow-trending-up",
|
||||
// children: [],
|
||||
// },
|
||||
// {
|
||||
// href: "/admin/settings/privacy",
|
||||
// label: t("privacy"),
|
||||
// active: pathname === "/admin/settings/privacy",
|
||||
// icon: "heroicons:arrow-trending-up",
|
||||
// children: [],
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
|
|
@ -1,7 +1,12 @@
|
|||
import qs from "qs";
|
||||
import { getAPIDummy } from "./http-config/axiosCustom";
|
||||
import { httpGet, httpPost } from "./http-config/http-base-service";
|
||||
import { httpGetInterceptor, httpGetInterceptorWithToken, httpPostInterceptor } from "./http-config/http-interceptor-service";
|
||||
import {
|
||||
httpGetInterceptor,
|
||||
httpGetInterceptorWithToken,
|
||||
httpPostInterceptor,
|
||||
postAPIWithJson,
|
||||
} from "./http-config/http-interceptor-service";
|
||||
|
||||
export async function login(data: any) {
|
||||
const pathUrl = "signin";
|
||||
|
|
@ -63,9 +68,19 @@ export async function getProfile(token: any) {
|
|||
return httpGetInterceptorWithToken(url, token);
|
||||
}
|
||||
|
||||
export async function postEmailValidation(data: any) {
|
||||
const url = "public/users/email-validation";
|
||||
return postAPIWithJson(url, data);
|
||||
}
|
||||
|
||||
export async function postSetupEmail(data: any) {
|
||||
const url = "public/users/setup-email";
|
||||
return httpGetInterceptorWithToken({ url, data });
|
||||
}
|
||||
|
||||
export async function getSubjects() {
|
||||
const url = 'inbox/subjects';
|
||||
return httpGetInterceptor( url );
|
||||
const url = "inbox/subjects";
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function getInfoProfile() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import axios from "axios";
|
||||
|
||||
const baseURL = "https://mediahub.polri.go.id/api/";
|
||||
|
||||
const axiosInstanceJson = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
export default axiosInstanceJson;
|
||||
|
|
@ -2,6 +2,8 @@ import { useRouter } from "next/navigation";
|
|||
import axiosInterceptorInstance from "./axios-interceptor-instance";
|
||||
import Cookies from "js-cookie";
|
||||
import { getCsrfToken } from "../auth";
|
||||
import axiosBaseInstance from "./axios-base-instance";
|
||||
import axiosInstanceJson from "./axiosInstanceJson";
|
||||
|
||||
export async function httpGetInterceptor(pathUrl: any) {
|
||||
const pathname = window.location.pathname;
|
||||
|
|
@ -172,3 +174,21 @@ export async function httpGetInterceptorWithToken(pathUrl: any, headers?: any) {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function postAPIWithJson(url: any, data: any, headers?: any) {
|
||||
const response = await axiosInstanceJson
|
||||
.post(url, data, { headers })
|
||||
.catch((error: any) => error.response);
|
||||
if (response?.status > 300) {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue