fix notification
parent
286e0636b6
commit
401a242822
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class NotificationEvent implements ShouldBroadcast
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(public string|array $message)
|
||||
{
|
||||
info(self::class, ['message' => $message, 'info' => 'triggered']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new Channel('notification');
|
||||
}
|
||||
}
|
Binary file not shown.
@ -0,0 +1,67 @@
|
||||
import React from 'react'
|
||||
import { router, usePage } from '@inertiajs/react'
|
||||
import { HiOutlineBell } from 'react-icons/hi2'
|
||||
|
||||
import Dropdown from '@/Components/Defaults/Dropdown'
|
||||
|
||||
export default function NotificationContent() {
|
||||
const {
|
||||
props: { notifications, count_unread_notifications },
|
||||
} = usePage()
|
||||
const handleNotification = (notif) => {
|
||||
fetch(route('api.notification.update', notif))
|
||||
router.get(route(route().current()))
|
||||
}
|
||||
|
||||
return (
|
||||
<Dropdown>
|
||||
<Dropdown.Trigger>
|
||||
<div className="flex flex-row">
|
||||
<HiOutlineBell className="h-6 w-6" />
|
||||
<div>
|
||||
<div className="bg-blue-300 text-blue-600 rounded-lg px-1 text-xs -ml-2">
|
||||
{count_unread_notifications}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown.Trigger>
|
||||
<Dropdown.Content width="64">
|
||||
{notifications.map((notif) => (
|
||||
<div
|
||||
className={`px-4 py-2 hover:bg-gray-100 border-b`}
|
||||
onClick={() => handleNotification(notif)}
|
||||
key={notif.id}
|
||||
>
|
||||
<div
|
||||
className={`${+notif.is_read === 0 && 'font-bold'}`}
|
||||
>
|
||||
{notif.description}
|
||||
</div>
|
||||
<div className="text-xs">{notif.format_created_at}</div>
|
||||
</div>
|
||||
))}
|
||||
{notifications.length > 0 && (
|
||||
<div className="w-full flex flex-row justify-between px-3">
|
||||
<div
|
||||
className="text-xs hover:text-blue-500 hover:underline"
|
||||
onClick={() =>
|
||||
router.get(route('notifications.index'))
|
||||
}
|
||||
>
|
||||
lihat semua
|
||||
</div>
|
||||
<div
|
||||
className="text-xs hover:text-blue-500 hover:underline"
|
||||
onClick={() => handleNotification()}
|
||||
>
|
||||
tandai semua dibaca
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{notifications.length === 0 && (
|
||||
<div className="px-4 py-2 ">Tidak ada notifikasi</div>
|
||||
)}
|
||||
</Dropdown.Content>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
import React, { useState, useEffect, useRef } from 'react'
|
||||
import { router, usePage } from '@inertiajs/react'
|
||||
import { HiOutlineCash } from 'react-icons/hi'
|
||||
|
||||
import audioSrc from '@/../assets/notif.mp3'
|
||||
|
||||
import Dropdown from '@/Components/Defaults/Dropdown'
|
||||
import { browserNotification } from './helpers'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
export default function NotificationDeposit() {
|
||||
const {
|
||||
props: { deposit_notifications },
|
||||
} = usePage()
|
||||
const [bounce, setBounce] = useState(false)
|
||||
const [notif, setNotif] = useState(deposit_notifications)
|
||||
const audioRef = useRef()
|
||||
|
||||
const handleNotification = (notif) => {
|
||||
if (isEmpty(notif) === false) {
|
||||
fetch(route('api.notification.update', notif))
|
||||
router.get(notif.url)
|
||||
return
|
||||
}
|
||||
fetch(route('api.notification.update'))
|
||||
router.get(route('dashboard'))
|
||||
}
|
||||
|
||||
const handleAudioStop = () => {
|
||||
if (isEmpty(audioRef.current) === false) {
|
||||
audioRef.current.pause()
|
||||
audioRef.current.currentTime = 0
|
||||
}
|
||||
setBounce(false)
|
||||
}
|
||||
|
||||
const handleAudioPlay = () => {
|
||||
if (audioRef.current.currentTime !== 0) {
|
||||
handleAudioStop()
|
||||
}
|
||||
|
||||
try {
|
||||
audioRef.current.play()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
setBounce(true)
|
||||
setTimeout(() => setBounce(false), 22000)
|
||||
}
|
||||
|
||||
const handleUpdate = async (e) => {
|
||||
setNotif(e.message.deposit_notifications)
|
||||
handleAudioPlay()
|
||||
browserNotification(
|
||||
'Notifikasi Deposit',
|
||||
e.message.description,
|
||||
e.message.url
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.Echo.channel('notification')
|
||||
.listen('NotificationEvent', (e) => {
|
||||
if (e.message.type === 'deposit') {
|
||||
handleUpdate(e)
|
||||
}
|
||||
})
|
||||
.error((error) => {
|
||||
console.error(error)
|
||||
})
|
||||
return () => {
|
||||
window.Echo.leave('notification')
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Dropdown>
|
||||
<audio id="audio" loop={false} autoPlay={false} ref={audioRef}>
|
||||
<source src={audioSrc} type="audio/mpeg" />
|
||||
</audio>
|
||||
<Dropdown.Trigger>
|
||||
<div
|
||||
className={`flex flex-row ${
|
||||
bounce && 'motion-safe:animate-bounce'
|
||||
}`}
|
||||
onClick={() => handleAudioStop()}
|
||||
>
|
||||
<HiOutlineCash className="h-6 w-6" />
|
||||
<div>
|
||||
<div className="bg-red-300 text-red-600 rounded-lg px-1 text-xs -ml-2">
|
||||
{notif.length}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown.Trigger>
|
||||
<Dropdown.Content width="64">
|
||||
{notif.map((notif) => (
|
||||
<div
|
||||
className={`px-4 py-2 hover:bg-gray-100 border-b`}
|
||||
onClick={() => handleNotification(notif)}
|
||||
key={notif.format_created_at}
|
||||
>
|
||||
<div className="font-bold">{notif.description}</div>
|
||||
<div className="text-xs">{notif.format_created_at}</div>
|
||||
</div>
|
||||
))}
|
||||
{notif.length > 0 && (
|
||||
<div className="w-full flex flex-row justify-between px-3">
|
||||
<div
|
||||
className="text-xs hover:text-blue-500 hover:underline"
|
||||
onClick={() =>
|
||||
router.get(route('notifications.index'))
|
||||
}
|
||||
>
|
||||
lihat semua
|
||||
</div>
|
||||
<div
|
||||
className="text-xs hover:text-blue-500 hover:underline"
|
||||
onClick={() => handleNotification()}
|
||||
>
|
||||
tandai semua dibaca
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{notif.length === 0 && (
|
||||
<div className="px-4 py-2 ">Tidak ada notifikasi</div>
|
||||
)}
|
||||
</Dropdown.Content>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue