last fix notification , semoga cair

dev
Aji Kamaludin 1 year ago
parent 401a242822
commit 2b6c397d91
No known key found for this signature in database
GPG Key ID: 19058F67F0083AD3

@ -49,7 +49,7 @@ class CartController extends Controller
$operator = $request->param ?? 'add'; //delete, sub, add $operator = $request->param ?? 'add'; //delete, sub, add
$customer = $request->user('customer'); $customer = $request->user('customer');
if (! $customer->allow_transaction) { if (!$customer->allow_transaction) {
$customer->carts()->delete(); $customer->carts()->delete();
return redirect()->back() return redirect()->back()

@ -45,6 +45,8 @@ class HandleInertiaRequests extends Middleware
'count_unread_notifications' => $notifications->where('is_read', Notification::UNREAD)->count(), 'count_unread_notifications' => $notifications->where('is_read', Notification::UNREAD)->count(),
'deposit_notifications' => $notifications->where('type', Notification::TYPE_DEPOSIT) 'deposit_notifications' => $notifications->where('type', Notification::TYPE_DEPOSIT)
->where('is_read', Notification::UNREAD)->limit(10)->get(), ->where('is_read', Notification::UNREAD)->limit(10)->get(),
'stock_notifications' => $notifications->where('type', Notification::TYPE_VOUCHER_STOCK)
->where('is_read', Notification::UNREAD)->limit(10)->get(),
]); ]);
} }
} }

@ -9,6 +9,8 @@ class Notification extends Model
{ {
const TYPE_DEPOSIT = 'deposit'; const TYPE_DEPOSIT = 'deposit';
const TYPE_VOUCHER_STOCK = 'voucher_stock';
const UNREAD = 0; const UNREAD = 0;
const READ = 1; const READ = 1;

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Events\NotificationEvent;
use App\Services\GeneralService; use App\Services\GeneralService;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
@ -173,9 +174,24 @@ class Voucher extends Model
$treshold = $this->locationProfile->min_stock; $treshold = $this->locationProfile->min_stock;
if ($count <= $treshold) { if ($count <= $treshold) {
Notification::create([ $notification = Notification::create([
'entity_type' => User::class, 'entity_type' => User::class,
'description' => 'stok voucher '.$this->locationProfile->name.'tersisa : '.$count, 'description' => 'stok voucher ' . $this->locationProfile->name . ' tersisa : ' . $count,
'url' => route('voucher.profile', $this->locationProfile->location_id),
'type' => Notification::TYPE_VOUCHER_STOCK,
]);
NotificationEvent::dispatch([
'id' => $notification->id,
'description' => $notification->description,
'url' => $notification->url,
'type' => Notification::TYPE_VOUCHER_STOCK,
'format_created_at' => now()->translatedFormat('d F Y H:i:s'),
'stock_notifications' => Notification::where('entity_type', User::class)
->where('type', Notification::TYPE_VOUCHER_STOCK)
->where('is_read', Notification::UNREAD)->limit(10)
->orderBy('created_at', 'desc')
->get(),
]); ]);
} }
} }

Binary file not shown.

@ -10,6 +10,7 @@ import Dropdown from '@/Components/Defaults/Dropdown'
import SidebarNav from './Partials/SidebarNav' import SidebarNav from './Partials/SidebarNav'
import NotificationContent from './Partials/NotificationContent' import NotificationContent from './Partials/NotificationContent'
import NotificationDeposit from './Partials/NotificationDeposit' import NotificationDeposit from './Partials/NotificationDeposit'
import NotificationStock from './Partials/NotificationStock'
const customTheme = { const customTheme = {
button: { button: {
@ -63,6 +64,9 @@ export default function Authenticated({
</div> </div>
<div className="hidden sm:flex sm:items-center sm:ml-6"> <div className="hidden sm:flex sm:items-center sm:ml-6">
<div className="ml-3 relative">
<NotificationStock />
</div>
<div className="ml-3 relative"> <div className="ml-3 relative">
<NotificationDeposit /> <NotificationDeposit />
</div> </div>

@ -3,6 +3,7 @@ import { router, usePage } from '@inertiajs/react'
import { HiOutlineBell } from 'react-icons/hi2' import { HiOutlineBell } from 'react-icons/hi2'
import Dropdown from '@/Components/Defaults/Dropdown' import Dropdown from '@/Components/Defaults/Dropdown'
import { isEmpty } from 'lodash'
export default function NotificationContent() { export default function NotificationContent() {
const { const {
@ -10,6 +11,10 @@ export default function NotificationContent() {
} = usePage() } = usePage()
const handleNotification = (notif) => { const handleNotification = (notif) => {
fetch(route('api.notification.update', notif)) fetch(route('api.notification.update', notif))
if (isEmpty(notif.url) === false) {
router.visit(notif.url)
return
}
router.get(route(route().current())) router.get(route(route().current()))
} }

@ -0,0 +1,132 @@
import React, { useState, useEffect, useRef } from 'react'
import { router, usePage } from '@inertiajs/react'
import { isEmpty } from 'lodash'
import { HiOutlineTicket } from 'react-icons/hi2'
import audioSrc from '@/../assets/warning.mp3'
import Dropdown from '@/Components/Defaults/Dropdown'
import { browserNotification } from './helpers'
export default function NotificationStock() {
const {
props: { stock_notifications },
} = usePage()
const [bounce, setBounce] = useState(false)
const [notif, setNotif] = useState(stock_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.stock_notifications)
handleAudioPlay()
browserNotification(
'Notifikasi Stok Voucher',
e.message.description,
e.message.url
)
}
useEffect(() => {
window.Echo.channel('notification')
.listen('NotificationEvent', (e) => {
if (e.message.type === 'voucher_stock') {
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()}
>
<HiOutlineTicket className="h-6 w-6" />
<div>
<div className="bg-yellow-300 text-yelbg-yellow-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…
Cancel
Save