diff --git a/package.json b/package.json index 2516225..3211513 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@tiptap/react": "^2.4.0", "@tiptap/starter-kit": "^2.4.0", "@types/lodash": "^4.17.6", + "@types/web-push": "^3.6.3", "dayjs": "^1.11.11", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -41,6 +42,7 @@ "iron-session": "^8.0.2", "lodash": "^4.17.21", "moment": "^2.30.1", + "mqtt": "^5.10.1", "next": "14.2.4", "pdfjs-dist": "^4.6.82", "prettier": "^3.3.2", @@ -52,6 +54,7 @@ "readdirp": "^3.6.0", "recharts": "2", "rrule": "^2.8.1", + "web-push": "^3.6.7", "yargs": "^17.7.2" }, "devDependencies": { diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 9a14f90..b8a6ce8 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -121,6 +121,8 @@ model User { DivisionDocumentFolderFile DivisionDocumentFolderFile[] DivisionCalendar DivisionCalendar[] DivisionCalendarMember DivisionCalendarMember[] + Notifications Notifications[] @relation("UserToUser") + Notifications2 Notifications[] @relation("UserFromUser") } model UserLog { @@ -478,3 +480,24 @@ model ColorTheme { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } + +model Subscription { + id String @id @default(cuid()) + data Json +} + +model Notifications { + id String @id @default(cuid()) + User1 User @relation("UserToUser", fields: [idUserTo], references: [id], map: "UserToUserMap") + idUserTo String + User2 User @relation("UserFromUser", fields: [idUserFrom], references: [id], map: "UserFromUserMap") + idUserFrom String + category String + idContent String + title String + desc String + isRead Boolean @default(false) + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/public/icon-192x192.png b/public/icon-192x192.png new file mode 100644 index 0000000..807489a Binary files /dev/null and b/public/icon-192x192.png differ diff --git a/public/wibu_worker.js b/public/wibu_worker.js new file mode 100644 index 0000000..f345a61 --- /dev/null +++ b/public/wibu_worker.js @@ -0,0 +1,77 @@ + +self.addEventListener('install', (event) => { + event.waitUntil(self.skipWaiting()); + console.log('Service worker installing...'); +}); + +self.addEventListener('activate', (event) => { + event.waitUntil(self.clients.claim()); + console.log('Service worker activating...'); +}); + +self.addEventListener('push', function (event) { + console.log('Push event received:', event); + + + let title = "Sistem Desa Mandiri"; + let options = { + body: "Default notification body", + icon: '/icon-192x192.png', + badge: '/icon-192x192.png', + image: '/icon-192x192.png', + vibrate: [100, 50, 100], + data: { + dateOfArrival: Date.now(), + primaryKey: '2', + }, + }; + + if (event.data) { + try { + const data = event.data.json(); + title = data.title || title; + options.body = data.body || options.body; + options.icon = data.icon || options.icon; + options.badge = data.badge || options.badge; + options.image = data.image || options.image; + options.data = { + ...options.data, + ...data.data, // Merging additional data from the event + }; + + } catch (e) { + console.error("Error parsing push event data:", e); + } + } else { + console.warn("Push event has no data."); + } + + event.waitUntil( + self.registration.showNotification(title, options) + .then(() => console.log('Notification shown.', JSON.stringify(options, null, 2))) + .catch(err => { + console.error("Error showing notification:", err); + }) + ); +}); + +self.addEventListener('notificationclick', function (event) { + console.log('Notification click received.'); + + event.notification.close(); // Close the notification + + event.waitUntil( + clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => { + for (const client of clientList) { + if (client.url.includes('http://localhost:3005') && 'focus' in client) { + return client.focus(); + } + } + if (clients.openWindow) { + return clients.openWindow('http://localhost:3005'); + } + }).catch(err => { + console.error("Error handling notification click:", err); + }) + ); +}); diff --git a/src/app/(application)/layout.tsx b/src/app/(application)/layout.tsx index 95d0deb..8eb45f9 100644 --- a/src/app/(application)/layout.tsx +++ b/src/app/(application)/layout.tsx @@ -10,7 +10,7 @@ export default async function Layout({ children }: { children: React.ReactNode } const user = await funGetUserByCookies() return ( <> - + {children} diff --git a/src/app/(application)/web-push/page.tsx b/src/app/(application)/web-push/page.tsx new file mode 100644 index 0000000..24e988c --- /dev/null +++ b/src/app/(application)/web-push/page.tsx @@ -0,0 +1,17 @@ +import { NotificationManager } from "@/module/_global/components/notification_manager"; + +const publicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!; + +console.log( + process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY, + process.env.VAPID_PRIVATE_KEY +); + +export default function Page() { + return ( +
+ {/* */} + +
+ ); +} \ No newline at end of file diff --git a/src/app/api/announcement/route.ts b/src/app/api/announcement/route.ts index ece3879..75442f0 100644 --- a/src/app/api/announcement/route.ts +++ b/src/app/api/announcement/route.ts @@ -5,6 +5,7 @@ import moment from "moment"; import "moment/locale/id"; import { NextResponse } from "next/server"; import { createLogUser } from '@/module/user'; +import mtqq_client from "../../../module/_global/bin/mqtt_client"; export const dynamic = 'force-dynamic' @@ -127,22 +128,72 @@ export async function POST(request: Request) { let memberDivision = [] - for (var i = 0, l = groups.length; i < l; i++) { - var obj = groups[i].Division; - for (let index = 0; index < obj.length; index++) { - const element = obj[index]; - const fix = { - idAnnouncement: data.id, - idGroup: groups[i].id, - idDivision: element.id + // for (var i = 0, l = groups.length; i < l; i++) { + // var obj = groups[i].Division; + // for (let index = 0; index < obj.length; index++) { + // const element = obj[index]; + // const fix = { + // idAnnouncement: data.id, + // idGroup: groups[i].id, + // idDivision: element.id + // } + // memberDivision.push(fix) + // } + // } + + // const announcementMember = await prisma.announcementMember.createMany({ + // data: memberDivision, + // }); + + const memberNotif = await prisma.divisionMember.findMany({ + where: { + Division: { + AnnouncementMember: { + some: { + idAnnouncement: data.id + } + } } - memberDivision.push(fix) + }, + select: { + idUser: true } + }) + + + + const dataNotif = memberNotif.map((v: any) => ({ + ..._.omit(v, ["idUser"]), + idUserTo: v.idUser, + idUserFrom: userId, + category: 'announcement', + idContent: data.id, + title: 'Pengumuman Baru', + desc: 'Anda memiliki pengumuman baru. Silahkan periksa detailnya.' + })) + + + + + // const insertNotif = await prisma.notifications.createMany({ + // data: dataNotif + // }) + + for (let index = 0; index < dataNotif.length; index++) { + + const user = dataNotif[index].idUserTo + const title = dataNotif[index].title + const desc = dataNotif[index].desc + + + mtqq_client.publish("app_SDM", JSON.stringify({ + "user": "clzm6swhg000tfgbhm3bau9ti", + "title": title, + "category": "announcement", + "description": desc + })) } - const announcementMember = await prisma.announcementMember.createMany({ - data: memberDivision, - }); // create log user const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data pengumuman baru', table: 'announcement', data: data.id }) diff --git a/src/app/api/get-subscribe/route.ts b/src/app/api/get-subscribe/route.ts new file mode 100644 index 0000000..ee53507 --- /dev/null +++ b/src/app/api/get-subscribe/route.ts @@ -0,0 +1,6 @@ +import prisma from "@/lib/prisma"; + +export async function GET() { + const sub = await prisma.subscription.findMany(); + return new Response(JSON.stringify({ data: sub })); +} diff --git a/src/app/api/send-notification/route.ts b/src/app/api/send-notification/route.ts new file mode 100644 index 0000000..81fc90e --- /dev/null +++ b/src/app/api/send-notification/route.ts @@ -0,0 +1,70 @@ +import webpush from "web-push"; +import prisma from "@/lib/prisma"; + +// Set VAPID details for web-push +webpush.setVapidDetails( + "mailto:bip.production.js@gmail.com", + process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!, + process.env.VAPID_PRIVATE_KEY! +); + +export async function POST() { + try { + // Fetch all subscriptions from your database + const subscriptions = await prisma.subscription.findMany(); + + if (!subscriptions || subscriptions.length === 0) { + console.error("No subscriptions available to send notification"); + return new Response("No subscriptions available", { status: 400 }); + } + + // Notification payload + const notificationPayload = JSON.stringify({ + title: "Test Notification", + body: "This is a test notification | makuro", + icon: "/icon-192x192.png", + badge: "/icon-192x192.png", + image: "/icon-192x192.png", + }); + + let successCount = 0; + let failureCount = 0; + + // Loop through all subscriptions and send notifications + for (const sub of subscriptions) { + try { + const subscriptionData = sub.data as any; + + await webpush.sendNotification(subscriptionData, notificationPayload); + console.log( + `Notification sent successfully to ${subscriptionData.endpoint}` + ); + successCount++; + } catch (error: any) { + console.error( + `Error sending push notification to subscription ${sub.id}:`, + error + ); + failureCount++; + } + } + + // Return a success or failure response + return new Response( + JSON.stringify({ + message: `Notifications sent: ${successCount}, Failed: ${failureCount}`, + success: failureCount === 0 + }), + { status: 200 } + ); + } catch (error: any) { + console.error("Error during notification process:", error); + return new Response( + JSON.stringify({ + success: false, + error: error.message || "Failed to process notifications" + }), + { status: 500 } + ); + } +} diff --git a/src/app/api/set-subscribe/route.ts b/src/app/api/set-subscribe/route.ts new file mode 100644 index 0000000..2557f87 --- /dev/null +++ b/src/app/api/set-subscribe/route.ts @@ -0,0 +1,25 @@ +import webpush from "web-push"; +import prisma from "@/lib/prisma"; +webpush.setVapidDetails( + "mailto:bip.production.js@gmail.com", + process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!, + process.env.VAPID_PRIVATE_KEY! +); + +export async function POST(req: Request) { + const { sub } = await req.json(); + console.log(sub); + if (!sub || !sub.endpoint) { + console.error("Invalid subscription object"); + return new Response("Invalid subscription object", { status: 400 }); + } + + const data = await prisma.subscription.create({ + data: { + id: sub.keys.auth, + data: sub + } + }); + + return new Response(JSON.stringify({ data })); +} diff --git a/src/app/api/unsubscribe/route.ts b/src/app/api/unsubscribe/route.ts new file mode 100644 index 0000000..7b166fb --- /dev/null +++ b/src/app/api/unsubscribe/route.ts @@ -0,0 +1,11 @@ +import prisma from "@/lib/prisma"; + +export async function POST(req: Request) { + const { sub } = await req.json(); + const data = await prisma.subscription.delete({ + where: { + id: sub.keys.auth + } + }); + return new Response(JSON.stringify({ data })); +} diff --git a/src/app/manifest.ts b/src/app/manifest.ts new file mode 100644 index 0000000..4024303 --- /dev/null +++ b/src/app/manifest.ts @@ -0,0 +1,29 @@ +import type { MetadataRoute } from "next"; + +export default function manifest(): MetadataRoute.Manifest { + return { + name: "Sistem Desa Mandiri", + short_name: "SDM", + description: "Sistem Desa Mandiri", + start_url: "/", + display: "standalone", + background_color: "#ffffff", + theme_color: "#000000", + icons: [ + { + src: "/icon-192x192.png", + sizes: "192x192", + type: "image/png" + }, + { + src: "/icon-512x512.png", + sizes: "512x512", + type: "image/png" + } + ], + serviceworker: { + src: "/wibu_worker.js" + }, + + }; +} diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts new file mode 100644 index 0000000..7ddc22a --- /dev/null +++ b/src/lib/prisma.ts @@ -0,0 +1,15 @@ +import { PrismaClient } from '@prisma/client' + +const prismaClientSingleton = () => { + return new PrismaClient() +} + +declare const globalThis: { + prismaGlobal: ReturnType; +} & typeof global; + +const prisma = globalThis.prismaGlobal ?? prismaClientSingleton() + +export default prisma + +if (process.env.NODE_ENV !== 'production') globalThis.prismaGlobal = prisma \ No newline at end of file diff --git a/src/lib/urlB64ToUint8Array.ts b/src/lib/urlB64ToUint8Array.ts new file mode 100644 index 0000000..94035bc --- /dev/null +++ b/src/lib/urlB64ToUint8Array.ts @@ -0,0 +1,13 @@ +export const urlB64ToUint8Array = (base64String: string) => { + const padding = "=".repeat((4 - (base64String.length % 4)) % 4); + const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/"); + + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; + }; + \ No newline at end of file diff --git a/src/lib/usePWAInstall.ts b/src/lib/usePWAInstall.ts new file mode 100644 index 0000000..b1bc6e9 --- /dev/null +++ b/src/lib/usePWAInstall.ts @@ -0,0 +1,46 @@ +import { useState, useEffect } from "react"; + +export function usePWAInstall() { + const [deferredPrompt, setDeferredPrompt] = useState(null); + const [isAppInstalled, setIsAppInstalled] = useState(false); + + useEffect(() => { + const beforeInstallHandler = (e: any) => { + e.preventDefault(); + setDeferredPrompt(e); + }; + + + const appInstalledHandler = () => { + setIsAppInstalled(true); + }; + + window.addEventListener("beforeinstallprompt", beforeInstallHandler); + window.addEventListener("appinstalled", appInstalledHandler); + + return () => { + window.removeEventListener("beforeinstallprompt", beforeInstallHandler); + window.removeEventListener("appinstalled", appInstalledHandler); + }; + }, []); + + const handleInstallClick = () => { + if (deferredPrompt) { + deferredPrompt.prompt(); + deferredPrompt.userChoice.then((choiceResult: any) => { + if (choiceResult.outcome === "accepted") { + console.log("User accepted the install prompt"); + } else { + console.log("User dismissed the install prompt"); + } + setDeferredPrompt(null); + }); + } + }; + + return { + deferredPrompt, + isAppInstalled, + handleInstallClick, + }; +} diff --git a/src/lib/usePushNotifications.ts b/src/lib/usePushNotifications.ts new file mode 100644 index 0000000..3578c37 --- /dev/null +++ b/src/lib/usePushNotifications.ts @@ -0,0 +1,75 @@ +import { useState, useEffect } from "react"; +import { urlB64ToUint8Array } from "./urlB64ToUint8Array"; + +export function usePushNotifications(publicKey: string) { + const [isSupported, setIsSupported] = useState(false); + const [subscription, setSubscription] = useState( + null + ); + + useEffect(() => { + if ("serviceWorker" in navigator && "PushManager" in window) { + setIsSupported(true); + registerServiceWorker(); + } + }, []); + + const registerServiceWorker = async () => { + try { + const registration = await navigator.serviceWorker.register( + "/wibu_worker.js", + { + scope: "/", + updateViaCache: "none" + } + ); + const sub = await registration.pushManager.getSubscription(); + if (sub) { + setSubscription(sub); + } + } catch (error) { + console.error("Service Worker registration failed:", error); + } + }; + + const subscribeToPush = async () => { + try { + const registration = await navigator.serviceWorker.ready; + const sub = await registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlB64ToUint8Array(publicKey) + }); + + const res = await fetch("/api/set-subscribe", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ sub: sub.toJSON() }) + }); + + if (res.ok) { + setSubscription(sub); + } + } catch (error) { + console.error("Subscription error:", error); + } + }; + + const unsubscribeFromPush = async () => { + if (subscription) { + await subscription.unsubscribe(); + setSubscription(null); + await fetch("/api/unsubscribe", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ sub: subscription.toJSON() }) + }); + } + }; + + return { + isSupported, + subscription, + subscribeToPush, + unsubscribeFromPush + }; +} diff --git a/src/module/_global/bin/mqtt_client.ts b/src/module/_global/bin/mqtt_client.ts new file mode 100644 index 0000000..aef2428 --- /dev/null +++ b/src/module/_global/bin/mqtt_client.ts @@ -0,0 +1,9 @@ +import mtqq from 'mqtt' + +declare global { + var mtqq_client: mtqq.MqttClient +} + +const mtqq_client = globalThis.mtqq_client ?? mtqq.connect("wss://io.wibudev.com") + +export default mtqq_client \ No newline at end of file diff --git a/src/module/_global/bin/mqtt_load.tsx b/src/module/_global/bin/mqtt_load.tsx new file mode 100644 index 0000000..387f175 --- /dev/null +++ b/src/module/_global/bin/mqtt_load.tsx @@ -0,0 +1,18 @@ +'use client' +import { useEffect } from "react" +import mtqq_client from "./mqtt_client" + +export default function MqttLoad() { + useEffect(() => { + mtqq_client.on("connect", () => { + mtqq_client.subscribe("app_SDM") + }) + + mtqq_client.on("message", (topic, message) => { + const data = JSON.parse(message.toString()) + }) + }, []) + return <> + + +} \ No newline at end of file diff --git a/src/module/_global/bin/val_global.ts b/src/module/_global/bin/val_global.ts index c1905ce..7813d32 100644 --- a/src/module/_global/bin/val_global.ts +++ b/src/module/_global/bin/val_global.ts @@ -19,4 +19,9 @@ export const TEMA = hookstate({ bgFiturHome: "#FCAA4B", bgFiturDivision: "#FCAA4B", bgTotalKegiatan: "#DCEED8" +}) + +export const globalNotifPage = hookstate({ + load: false, + category: '' }) \ No newline at end of file diff --git a/src/module/_global/components/notification_manager.tsx b/src/module/_global/components/notification_manager.tsx new file mode 100644 index 0000000..9a8c470 --- /dev/null +++ b/src/module/_global/components/notification_manager.tsx @@ -0,0 +1,83 @@ +"use client"; +import { usePushNotifications } from "@/lib/usePushNotifications"; +import { usePWAInstall } from "@/lib/usePWAInstall"; +import { useState } from "react"; + +// test v1 + +export function NotificationManager({ publicKey }: { publicKey: string }) { + const { + isSupported, + subscription, + subscribeToPush, + unsubscribeFromPush + } = usePushNotifications(publicKey); + const { deferredPrompt, isAppInstalled, handleInstallClick } = + usePWAInstall(); + const [message, setMessage] = useState("halo apa kabar"); + + + const sendTestNotification = async () => { + if (!subscription) return; + + try { + const res = await fetch("/api/send-notification", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ sub: subscription.toJSON(), message }) + }); + + if (!res.ok) { + console.error("Failed to send notification:", res.statusText); + } + } catch (error) { + console.error("Notification error:", error); + } + }; + + if (!isSupported) { + return

Push notifications are not supported in this browser.

; + } + + return ( +
+

Push Notifications & PWA Install

+ {subscription ? ( + <> +

You are subscribed to push notifications.

+
+
+ +
+ setMessage(e.target.value)} + /> +
+ +
+
+ + ) : ( + <> +

You are not subscribed to push notifications.

+ + + )} +
+ {!isAppInstalled && deferredPrompt && ( + + )} +
+ ); +} \ No newline at end of file diff --git a/src/module/_global/components/wrap_layout.tsx b/src/module/_global/components/wrap_layout.tsx index d50f1e3..144516f 100644 --- a/src/module/_global/components/wrap_layout.tsx +++ b/src/module/_global/components/wrap_layout.tsx @@ -1,18 +1,42 @@ 'use client' import { useHookstate } from "@hookstate/core"; -import { globalRole, TEMA } from "../bin/val_global"; +import { globalNotifPage, globalRole, TEMA } from "../bin/val_global"; import { useShallowEffect } from "@mantine/hooks"; import { useEffect } from "react"; +import mtqq_client from "../bin/mqtt_client"; -export default function WrapLayout({ children, role, theme }: { children: React.ReactNode, role: any, theme:any }) { +export default function WrapLayout({ children, role, theme, user }: { children: React.ReactNode, role: any, theme: any, user: any }) { const roleLogin = useHookstate(globalRole) const tema = useHookstate(TEMA) + const notifLoadPage = useHookstate(globalNotifPage) useEffect(() => { roleLogin.set(role) tema.set(theme) - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [role, theme]) + + + useEffect(() => { + mtqq_client.on("connect", () => { + console.log('connect layout') + mtqq_client.subscribe("app_SDM") + }) + + mtqq_client.on("message", (topic, message) => { + const data = JSON.parse(message.toString()) + + console.log('notif mtqq',data) + + // console.log('notif mtqq==',data) + // if (data.user == user) { + // notifLoadPage.set({ + // load: !notifLoadPage.get(), + // category: data.category + // }) + // } + }) + }) return ( <> {children} diff --git a/src/module/_global/index.ts b/src/module/_global/index.ts index 81cab87..0e47ef8 100644 --- a/src/module/_global/index.ts +++ b/src/module/_global/index.ts @@ -1,5 +1,6 @@ +import MqttLoad from "./bin/mqtt_load"; import prisma from "./bin/prisma"; -import { DIR, globalRole, pwd_key_config, TEMA } from "./bin/val_global"; +import { DIR, globalNotifPage, globalRole, pwd_key_config, TEMA } from "./bin/val_global"; import SkeletonAvatar from "./components/skeleton_avatar"; import SkeletonDetailDiscussionComment from "./components/skeleton_detail_discussion_comment"; import SkeletonDetailDiscussionMember from "./components/skeleton_detail_discussion_member"; @@ -21,6 +22,7 @@ import LayoutNavbarNew from "./layout/layout_navbar_new"; import NoZoom from "./layout/no_zoom"; import ReloadButtonTop from "./components/reload_button_top"; import ViewFilter from "./view/view_filter"; +import mtqq_client from "./bin/mqtt_client" import NotificationCustome from "./components/notification_custome"; export { WARNA }; @@ -47,6 +49,9 @@ export { funDeleteFile } export { DIR } export { TEMA } export { funCopyFile } +export { MqttLoad } +export { mtqq_client } +export { globalNotifPage } export { SkeletonAvatar } export { ReloadButtonTop } -export { NotificationCustome } \ No newline at end of file +export { NotificationCustome } diff --git a/src/module/announcement/ui/list_announcement.tsx b/src/module/announcement/ui/list_announcement.tsx index a60ed6d..dd7cb21 100644 --- a/src/module/announcement/ui/list_announcement.tsx +++ b/src/module/announcement/ui/list_announcement.tsx @@ -1,5 +1,5 @@ 'use client' -import { SkeletonSingle, TEMA, WARNA } from '@/module/_global'; +import { globalNotifPage, SkeletonSingle, TEMA, WARNA } from '@/module/_global'; import { ActionIcon, Box, Center, Divider, Grid, Group, Spoiler, Stack, Text, TextInput } from '@mantine/core'; import React, { useState } from 'react'; import { TfiAnnouncement } from "react-icons/tfi"; @@ -19,6 +19,7 @@ export default function ListAnnouncement() { const router = useRouter() const [loading, setLoading] = useState(true); const tema = useHookstate(TEMA) + const load = useHookstate(globalNotifPage) const fetchData = async () => { try { @@ -32,7 +33,7 @@ export default function ListAnnouncement() { } setLoading(false); } catch (error) { - toast.error("Gagal mendapatkan announcement, coba lagi nanti"); + toast.error("Gagal mendapatkan pengumuman, coba lagi nanti"); console.error(error); } finally { setLoading(false); @@ -41,7 +42,14 @@ export default function ListAnnouncement() { useShallowEffect(() => { fetchData() - }, [searchQuery]) + }, [searchQuery, load.get().load]) + + useShallowEffect(() => { + if (load.get().category == "announcement") { + console.log('masuk sinii', load.get().load) + fetchData() + } + }, [load.get().load]) return ( diff --git a/yarn.lock b/yarn.lock index 7b66708..5d28ae2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,6 +14,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.23.8", "@babel/runtime@^7.24.5": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" + integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== + dependencies: + regenerator-runtime "^0.14.0" + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -673,6 +680,13 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.6.tgz#193ced6a40c8006cfc1ca3f4553444fb38f0e543" integrity sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA== +"@types/node@*": + version "22.5.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44" + integrity sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA== + dependencies: + undici-types "~6.19.2" + "@types/node@^20.14.9": version "20.14.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.10.tgz#a1a218290f1b6428682e3af044785e5874db469a" @@ -700,6 +714,28 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/readable-stream@^4.0.0", "@types/readable-stream@^4.0.5": + version "4.0.15" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-4.0.15.tgz#e6ec26fe5b02f578c60baf1fa9452e90957d2bfb" + integrity sha512-oAZ3kw+kJFkEqyh7xORZOku1YAKvsFTogRY8kVl4vHpEKiDkfnSA/My8haRE7fvmix5Zyy+1pwzOi7yycGLBJw== + dependencies: + "@types/node" "*" + safe-buffer "~5.1.1" + +"@types/web-push@^3.6.3": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@types/web-push/-/web-push-3.6.3.tgz#7698cdeeabd70d1129a6e02bd58af1e985cdfa03" + integrity sha512-v3oT4mMJsHeJ/rraliZ+7TbZtr5bQQuxcgD7C3/1q/zkAj29c8RE0F9lVZVu3hiQe5Z9fYcBreV7TLnfKR+4mg== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.9": + version "8.5.12" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.12.tgz#619475fe98f35ccca2a2f6c137702d85ec247b7e" + integrity sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ== + dependencies: + "@types/node" "*" + "@typescript-eslint/parser@^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.2.0.tgz#44356312aea8852a3a82deebdacd52ba614ec07a" @@ -756,6 +792,13 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -780,6 +823,13 @@ agent-base@6: dependencies: debug "4" +agent-base@^7.0.2: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== + dependencies: + debug "^4.3.4" + ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -964,6 +1014,16 @@ arraybuffer.prototype.slice@^1.0.3: is-array-buffer "^3.0.4" is-shared-array-buffer "^1.0.2" +asn1.js@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + ast-types-flow@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" @@ -993,11 +1053,31 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== +bl@^6.0.8: + version "6.0.15" + resolved "https://registry.yarnpkg.com/bl/-/bl-6.0.15.tgz#eeee4af50c6f16eb08fc5ddbca6f2d9f2ff12d78" + integrity sha512-RGhjD1XCPS7ZdAH6cEJVaR3gLV4KJP2hvkQ49AH5kwScjiyd0jBM8RsP4oHKzcx+kNCON9752zPeRnuv0HHwzw== + dependencies: + "@types/readable-stream" "^4.0.0" + buffer "^6.0.3" + inherits "^2.0.4" + readable-stream "^4.2.0" + +bn.js@^4.0.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1020,6 +1100,24 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + busboy@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -1131,11 +1229,26 @@ commander@^4.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commist@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/commist/-/commist-3.2.0.tgz#da9c8e5f245ac21510badc4b10c46b5bcc9b56cd" + integrity sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +concat-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" + integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.0.2" + typedarray "^0.0.6" + console-control-strings@^1.0.0, console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -1422,6 +1535,13 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + echarts-for-react@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/echarts-for-react/-/echarts-for-react-3.0.2.tgz#ac5859157048a1066d4553e34b328abb24f2b7c1" @@ -1822,11 +1942,21 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + eventemitter3@^4.0.1: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1858,6 +1988,14 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-unique-numbers@^8.0.13: + version "8.0.13" + resolved "https://registry.yarnpkg.com/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz#3c87232061ff5f408a216e1f0121232f76f695d7" + integrity sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g== + dependencies: + "@babel/runtime" "^7.23.8" + tslib "^2.6.2" + fastq@^1.6.0: version "1.17.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" @@ -2149,11 +2287,21 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: dependencies: function-bind "^1.1.2" +help-me@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/help-me/-/help-me-5.0.0.tgz#b1ebe63b967b74060027c2ac61f9be12d354a6f6" + integrity sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg== + highlight.js@^11.9.0: version "11.10.0" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.10.0.tgz#6e3600dc4b33d6dc23d5bd94fbf72405f5892b92" integrity sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ== +http_ece@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http_ece/-/http_ece-1.2.0.tgz#84d5885f052eae8c9b075eee4d2eb5105f114479" + integrity sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA== + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -2162,6 +2310,19 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.0: + version "7.0.5" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz#9e8b5013873299e11fab6fd548405da2d6c602b2" + integrity sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw== + dependencies: + agent-base "^7.0.2" + debug "4" + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^5.2.0: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" @@ -2188,7 +2349,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2462,6 +2623,11 @@ jiti@^1.21.0: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== +js-sdsl@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" + integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== + "js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2506,6 +2672,23 @@ json5@^1.0.2: object.assign "^4.1.4" object.values "^1.1.6" +jwa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" + integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + dependencies: + jwa "^2.0.0" + safe-buffer "^5.0.1" + keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -2582,6 +2765,11 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^10.0.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^10.2.0: version "10.4.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.0.tgz#cb29b4b2dd55b22e4a729cdb096093d7f85df02d" @@ -2617,6 +2805,11 @@ mimic-response@^2.0.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + minimatch@9.0.3: version "9.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" @@ -2638,7 +2831,7 @@ minimatch@^9.0.1, minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -2678,6 +2871,37 @@ moment@^2.30.1: resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== +mqtt-packet@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/mqtt-packet/-/mqtt-packet-9.0.0.tgz#fd841854d8c0f1f5211b00de388c4ced45b59216" + integrity sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w== + dependencies: + bl "^6.0.8" + debug "^4.3.4" + process-nextick-args "^2.0.1" + +mqtt@^5.10.1: + version "5.10.1" + resolved "https://registry.yarnpkg.com/mqtt/-/mqtt-5.10.1.tgz#d4f45ffdd825bad331c18f08796a744dabbe16de" + integrity sha512-hXCOki8sANoQ7w+2OzJzg6qMBxTtrH9RlnVNV8panLZgnl+Gh0J/t4k6r8Az8+C7y3KAcyXtn0mmLixyUom8Sw== + dependencies: + "@types/readable-stream" "^4.0.5" + "@types/ws" "^8.5.9" + commist "^3.2.0" + concat-stream "^2.0.0" + debug "^4.3.4" + help-me "^5.0.0" + lru-cache "^10.0.1" + minimist "^1.2.8" + mqtt-packet "^9.0.0" + number-allocator "^1.0.14" + readable-stream "^4.4.2" + reinterval "^1.1.0" + rfdc "^1.3.0" + split2 "^4.2.0" + worker-timers "^7.1.4" + ws "^8.17.1" + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -2764,6 +2988,14 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" +number-allocator@^1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/number-allocator/-/number-allocator-1.0.14.tgz#1f2e32855498a7740dcc8c78bed54592d930ee4d" + integrity sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA== + dependencies: + debug "^4.3.1" + js-sdsl "4.3.0" + object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -3066,6 +3298,16 @@ prisma@^5.16.1: dependencies: "@prisma/engines" "5.16.1" +process-nextick-args@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" @@ -3199,7 +3441,7 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^3.6.0: +readable-stream@^3.0.2, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -3208,6 +3450,17 @@ readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^4.2.0, readable-stream@^4.4.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + readdirp@^3.6.0, readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -3264,6 +3517,11 @@ regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.2: es-errors "^1.3.0" set-function-name "^2.0.1" +reinterval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/reinterval/-/reinterval-1.1.0.tgz#3361ecfa3ca6c18283380dd0bb9546f390f5ece7" + integrity sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ== + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -3302,6 +3560,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -3333,11 +3596,16 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-regex-test@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" @@ -3347,6 +3615,11 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" +safer-buffer@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + scheduler@^0.23.2: version "0.23.2" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" @@ -3457,6 +3730,11 @@ source-map-js@^1.0.2, source-map-js@^1.2.0: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== +split2@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" @@ -3541,7 +3819,7 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.1.1: +string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -3751,6 +4029,11 @@ tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== +tslib@^2.6.2: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -3812,6 +4095,11 @@ typed-array-length@^1.0.6: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + typescript@^5.5.3: version "5.5.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.3.tgz#e1b0a3c394190838a0b168e771b0ad56a0af0faa" @@ -3837,6 +4125,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -3906,6 +4199,17 @@ victory-vendor@^36.6.8: d3-time "^3.0.0" d3-timer "^3.0.1" +web-push@^3.6.7: + version "3.6.7" + resolved "https://registry.yarnpkg.com/web-push/-/web-push-3.6.7.tgz#5f5e645951153e37ef90a6ddea5c150ea0f709e1" + integrity sha512-OpiIUe8cuGjrj3mMBFWY+e4MMIkW3SVT+7vEIjvD9kejGUypv8GPDf84JdPWskK8zMRIJ6xYGm+Kxr8YkPyA0A== + dependencies: + asn1.js "^5.3.0" + http_ece "1.2.0" + https-proxy-agent "^7.0.0" + jws "^4.0.0" + minimist "^1.2.5" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -3988,6 +4292,34 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== +worker-timers-broker@^6.1.8: + version "6.1.8" + resolved "https://registry.yarnpkg.com/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz#08f64e5931b77fadc55f0c7388c077a7dd17e4c7" + integrity sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ== + dependencies: + "@babel/runtime" "^7.24.5" + fast-unique-numbers "^8.0.13" + tslib "^2.6.2" + worker-timers-worker "^7.0.71" + +worker-timers-worker@^7.0.71: + version "7.0.71" + resolved "https://registry.yarnpkg.com/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz#f96138bafbcfaabea116603ce23956e05e76db6a" + integrity sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ== + dependencies: + "@babel/runtime" "^7.24.5" + tslib "^2.6.2" + +worker-timers@^7.1.4: + version "7.1.8" + resolved "https://registry.yarnpkg.com/worker-timers/-/worker-timers-7.1.8.tgz#f53072c396ac4264fd3027914f4ab793c92d90be" + integrity sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw== + dependencies: + "@babel/runtime" "^7.24.5" + tslib "^2.6.2" + worker-timers-broker "^6.1.8" + worker-timers-worker "^7.0.71" + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -4011,6 +4343,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +ws@^8.17.1: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"