upd: webpush

Deskripsi:
- database push notification
- update package
- memasang webpush

NO Issues
This commit is contained in:
amel
2024-11-18 17:12:58 +08:00
parent bc5ce5b48c
commit d847c97bec
30 changed files with 1267 additions and 282 deletions

View File

@@ -0,0 +1,28 @@
import { Button } from "@mantine/core";
import { useState } from "react";
export function ButtonKirim() {
const [loading, setLoading] = useState(false)
async function onKirim() {
setLoading(true)
try {
const res = await fetch('/makuro/api/kirim', {
method: 'POST',
})
const dataText = await res.text()
if (!res.ok) {
alert(dataText)
throw new Error(dataText)
}
const dataJson = JSON.parse(dataText)
console.log(dataJson)
alert("berhasil kirim")
} catch (error) {
console.error(error);
} finally {
setLoading(false)
}
}
return <Button loading={loading} onClick={() => onKirim()} >Kirim</Button>
}

View File

@@ -0,0 +1,32 @@
import { Button } from "@mantine/core";
import { useState } from "react";
export function ButtonSubscribe({ user, subscription }: { user: string, subscription?: PushSubscription | null }) {
const [loading, setLoading] = useState(false)
async function subscribe() {
if(!subscription) return alert("no subscription")
try {
setLoading(true)
const res = await fetch('/makuro/api/sub', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user, subscription })
})
const dataText = await res.text()
if (!res.ok) {
alert(dataText)
throw new Error(dataText)
}
console.log(dataText)
alert("berhasil subscribe")
} catch (error) {
console.error(error);
} finally {
setLoading(false)
}
}
return <Button disabled={!subscription} onClick={() => subscribe()} loading={loading} variant="outline" radius={"xl"} size={"lg"}>Subscribe</Button>
}

View File

@@ -0,0 +1,5 @@
import { WibuPermissionProvider, WibuPushNotificationHandler } from "wibu-pkg";
export function MakuroProvider() {
return null
}

View File

@@ -0,0 +1,7 @@
import { PushSubscription } from 'web-push';
export class UserSub {
public static subscription: PushSubscription | null;
public static setSub(subscription: PushSubscription) {
this.subscription = subscription
}
}

View File

@@ -0,0 +1,3 @@
import { hookstate } from "@hookstate/core";
export const subState = hookstate<PushSubscription | null>(null)

View File

@@ -0,0 +1,25 @@
import { prisma } from "@/module/_global";
import { WibuServerPush } from 'wibu-pkg'
WibuServerPush.init({
NEXT_PUBLIC_VAPID_PUBLIC_KEY: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
VAPID_PRIVATE_KEY: process.env.VAPID_PRIVATE_KEY!,
})
export async function POST(req: Request) {
const sub = await prisma.subscribe.findMany()
const subs: PushSubscription[] = sub.map((v) => JSON.parse(v.subscription)) as PushSubscription[]
const kirim = await WibuServerPush.sendMany({
subscriptions: subs as any,
data: {
body: "ini test ",
title: "test notif",
link: "/",
variant: "notification"
}
})
return new Response(JSON.stringify(kirim))
}

View File

@@ -0,0 +1,21 @@
import { prisma } from "@/module/_global"
export async function POST(req: Request) {
const { user, subscription } = await req.json()
console.log(user, subscription)
const upsert = await prisma.subscribe.upsert({
where: {
idUser: user
},
create: {
idUser: user,
subscription: JSON.stringify(subscription)
},
update: {
subscription: JSON.stringify(subscription)
}
})
return new Response(JSON.stringify(upsert))
}

View File

@@ -0,0 +1,22 @@
'use client'
import { useHookstate } from "@hookstate/core";
import { Card, Stack, Text, Title } from "@mantine/core";
import { subState } from "../_lib/state";
import { ButtonSubscribe } from "../_lib/ButtonSubscribe";
import { useSearchParams } from "next/navigation";
export default function Page() {
const user = useSearchParams().get("user")
const { value: sub } = useHookstate(subState)
if (!sub) return <Text>loading ...</Text>
if (!user) return <Text>masukkan user</Text>
return <Stack p={"md"} gap={"lg"}>
<Title>Kirim</Title>
<Card>
<Text>
{JSON.stringify(sub)}
</Text>
</Card>
<ButtonSubscribe user={user} subscription={sub} />
</Stack>;
}

17
src/app/makuro/layout.tsx Normal file
View File

@@ -0,0 +1,17 @@
'use client'
import { useHookstate } from "@hookstate/core"
import { WibuPermissionProvider, WibuPushNotificationHandler } from "wibu-pkg"
import { subState } from "./_lib/state"
export default function Layout({ children }: { children: React.ReactNode }) {
const { set: setSubcribe } = useHookstate(subState)
return <WibuPermissionProvider requiredPermissions={["notifications"]}>
<WibuPushNotificationHandler
NEXT_PUBLIC_VAPID_PUBLIC_KEY={process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!}
onSubscribe={(sub) => {
setSubcribe(sub)
}} />
{children}
</WibuPermissionProvider>
}

View File

@@ -0,0 +1,24 @@
'use client'
import { useHookstate } from "@hookstate/core";
import { Card, Stack, Text, Title } from "@mantine/core";
import { subState } from "../_lib/state";
import { ButtonSubscribe } from "../_lib/ButtonSubscribe";
import { useSearchParams } from "next/navigation";
import { ButtonKirim } from "../_lib/ButtonKirim";
export default function Page() {
const user = useSearchParams().get("user")
const { value: sub } = useHookstate(subState)
if (!sub) return <Text>loading ...</Text>
if (!user) return <Text>masukkan user</Text>
return <Stack p={"md"} gap={"lg"}>
<Title>terima</Title>
<Card>
<Text>
{JSON.stringify(sub)}
</Text>
</Card>
<ButtonSubscribe user={user} subscription={sub} />
<ButtonKirim />
</Stack>;
}