on progress realtime menggunakan reverb dan pake npm run dev

This commit is contained in:
JokoPrasetio 2025-09-02 07:46:11 +07:00
parent d157808dba
commit 2ba0935880
17 changed files with 3683 additions and 14 deletions

View File

@ -0,0 +1,28 @@
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcast
{
use SerializesModels;
public $message;
public function __construct($message)
{
$this->message = $message;
}
public function broadcastOn()
{
return new Channel('test');
}
public function broadcastAs()
{
return 'MessageSent';
}
}

View File

@ -8,6 +8,7 @@ return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
channels: __DIR__.'/../routes/channels.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {

View File

@ -10,6 +10,7 @@
"barryvdh/laravel-dompdf": "^3.1",
"barryvdh/laravel-snappy": "^1.0",
"laravel/framework": "^12.0",
"laravel/reverb": "^1.5",
"laravel/tinker": "^2.10.1",
"phpoffice/phpspreadsheet": "^4.5"
},

1002
composer.lock generated

File diff suppressed because it is too large Load Diff

82
config/broadcasting.php Normal file
View File

@ -0,0 +1,82 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "reverb", "pusher", "ably", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_CONNECTION', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over WebSockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'reverb' => [
'driver' => 'reverb',
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
'app_id' => env('REVERB_APP_ID'),
'options' => [
'host' => env('REVERB_HOST'),
'port' => env('REVERB_PORT', 443),
'scheme' => env('REVERB_SCHEME', 'https'),
'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'ably' => [
'driver' => 'ably',
'key' => env('ABLY_KEY'),
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];

94
config/reverb.php Normal file
View File

@ -0,0 +1,94 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Reverb Server
|--------------------------------------------------------------------------
|
| This option controls the default server used by Reverb to handle
| incoming messages as well as broadcasting message to all your
| connected clients. At this time only "reverb" is supported.
|
*/
'default' => env('REVERB_SERVER', 'reverb'),
/*
|--------------------------------------------------------------------------
| Reverb Servers
|--------------------------------------------------------------------------
|
| Here you may define details for each of the supported Reverb servers.
| Each server has its own configuration options that are defined in
| the array below. You should ensure all the options are present.
|
*/
'servers' => [
'reverb' => [
'host' => env('REVERB_SERVER_HOST', '0.0.0.0'),
'port' => env('REVERB_SERVER_PORT', 8080),
'path' => env('REVERB_SERVER_PATH', ''),
'hostname' => env('REVERB_HOST'),
'options' => [
'tls' => [],
],
'max_request_size' => env('REVERB_MAX_REQUEST_SIZE', 10_000),
'scaling' => [
'enabled' => env('REVERB_SCALING_ENABLED', false),
'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
'server' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'database' => env('REDIS_DB', '0'),
'timeout' => env('REDIS_TIMEOUT', 60),
],
],
'pulse_ingest_interval' => env('REVERB_PULSE_INGEST_INTERVAL', 15),
'telescope_ingest_interval' => env('REVERB_TELESCOPE_INGEST_INTERVAL', 15),
],
],
/*
|--------------------------------------------------------------------------
| Reverb Applications
|--------------------------------------------------------------------------
|
| Here you may define how Reverb applications are managed. If you choose
| to use the "config" provider, you may define an array of apps which
| your server will support, including their connection credentials.
|
*/
'apps' => [
'provider' => 'config',
'apps' => [
[
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
'app_id' => env('REVERB_APP_ID'),
'options' => [
'host' => env('REVERB_HOST'),
'port' => env('REVERB_PORT', 443),
'scheme' => env('REVERB_SCHEME', 'https'),
'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
],
'allowed_origins' => ['*'],
'ping_interval' => env('REVERB_APP_PING_INTERVAL', 60),
'activity_timeout' => env('REVERB_APP_ACTIVITY_TIMEOUT', 30),
'max_message_size' => env('REVERB_APP_MAX_MESSAGE_SIZE', 10_000),
],
],
],
];

2413
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,9 @@
"@tailwindcss/vite": "^4.0.0",
"axios": "^1.8.2",
"concurrently": "^9.0.1",
"laravel-echo": "^2.2.0",
"laravel-vite-plugin": "^1.2.0",
"pusher-js": "^8.4.0",
"tailwindcss": "^4.0.0",
"vite": "^6.2.4"
}

View File

@ -743,7 +743,6 @@ function validateCartBeforeSubmit() {
cart.forEach((item, index) => {
const pesananList = item.pesanan || [];
pesananList.forEach((pesanan, i) => {
console.log(!pesanan.karbohidrat_id, !item?.apakah_someday);
if (!pesanan.tgl) {
isValid = false;
@ -881,7 +880,6 @@ function increment(itemId, index) {
function decrement(itemId, index) {
const input = document.getElementById(`jumlah-${itemId}-${index}`);
let current = parseInt(input.value || "0");
console.log(current);
if (current > 1) {
input.value = current - 1;
@ -957,7 +955,6 @@ document.getElementById('submitNote').addEventListener('click', function(e){
const noted = $("#note_order").val()
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const item =cart.find(item => item.id === id)
console.log(id, index, item);
if(item && item.pesanan && item.pesanan[index]){
item.pesanan[index].catatan = noted

View File

@ -32,7 +32,6 @@
<i class="fa-solid fa-pencil"></i>
</button>
`
console.log(row);
buttons += `
<button class="btn btn-sm btn-danger me-2" onclick="deleteMasterMcu(this)"

View File

@ -178,7 +178,6 @@
if(filter.jenis_menu === "konsultasi"){
const jk = res.data|| [];
console.log(jk);
$("#tanggal-filter").addClass('d-none');
let html = `

View File

@ -7,7 +7,6 @@ function detailOrder(id){
document.getElementById('pesanan_container').innerHTML = '';
document.getElementById('confirm_nama_pesanan').textContent = data?.order?.nama_pemesan;
let html = '';
console.log(data);
html += `
<div class="col-md-12 mb-3">
@ -102,7 +101,7 @@ document.getElementById('formActionApproveOrder').addEventListener('submit', fun
backdrop: true,
});
datatablePekerjaan.bootstrapTable('refresh');
modalActionOrder.removeEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
getReminderVerifikasiMakanan()
};

View File

@ -1 +1,5 @@
import './bootstrap';
window.Echo.channel('test')
.listen('.MessageSent', (e) => {
console.log("Pesan diterima:", e.message);
});

View File

@ -2,3 +2,26 @@ import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allow your team to quickly build robust real-time web applications.
*/
import './echo';
import Echo from "laravel-echo";
import Pusher from "pusher-js";
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY ?? "app-key",
wsHost: '127.0.0.1',
wsPort: 8080,
forceTLS: false,
enabledTransports: ['ws'],
});

14
resources/js/echo.js Normal file
View File

@ -0,0 +1,14 @@
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});

7
routes/channels.php Normal file
View File

@ -0,0 +1,7 @@
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});

View File

@ -1,5 +1,6 @@
<?php
use App\Events\MessageSent;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\CustomerController;
use App\Http\Controllers\DashboardController;
@ -107,11 +108,16 @@ Route::get('/unit-instalasi', [CustomerController::class, 'unitInstalasi']);
// Mail::to('skyjok14@gmail.com')->queue(new NotifikasiCustomer('Test'));
// });
Route::get('/dumy', function(){
return view('guest.layout_mail');
});
Route::get('/label', function(){
$pdf = Pdf::loadView('dashboard.label.index');
return $pdf->stream('label_.pdf');
// Route::get('/dumy', function(){
// return view('guest.layout_mail');
// });
// Route::get('/label', function(){
// $pdf = Pdf::loadView('dashboard.label.index');
// return $pdf->stream('label_.pdf');
// });
Route::get('/send-test', function(){
broadcast(new MessageSent('HALO INI DARI SERVER'));
return 'event terkirim';
});