Files
servicedesk/src/routes/web.php
Kacper ab90abcaa3 v1.1.3
- Triggers (Admin > Wyzwalacze): event-driven rules that fire immediately on
  a ticket lifecycle event (created/updated/status/priority/assignee/team/
  category changed, new reply), with AND-conditions and ordered actions
  (set status/priority/team/assignee, send e-mail). Ships its own dedicated,
  freely add/edit/delete-able e-mail templates, kept separate from the fixed
  system templates.
- Ticket watching: operators can star/"Obserwuj" any ticket to follow it
  regardless of assignment/team.
- Real-time notification bell (private per-user broadcast channel, 30s
  fallback poll) with an opt-in in-tab browser push notification.
- Per-user notification preferences (/settings/notifications): scope
  (mine/unassigned/watched/all) and e-mail toggle per event category.
- Admin > Integracje: new tab for LDAP/AD + BookStack config, split out of
  Konfiguracja.
- Operator queue: Podkategoria/Zespół/Utworzono columns (off by default).
- Obserwuj button moved next to the auto-refresh countdown; trigger
  condition builder shows subcategory/zgłaszający as name dropdowns instead
  of raw IDs; /settings/notifications got a back link, full-width push
  card, and a bordered table container; admin panel tab and operator queue
  view now persist across a plain page refresh.
- Docs: README/ARCHITECTURE/wiki updated for all of the above.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 23:43:01 +02:00

81 lines
3.6 KiB
PHP

<?php
use App\Livewire\Admin\Panel as AdminPanel;
use App\Livewire\Auth\Login;
use App\Livewire\Client\Dashboard as ClientDashboard;
use App\Livewire\Client\NewTicket as ClientNewTicket;
use App\Livewire\Client\TicketShow as ClientTicketShow;
use App\Livewire\Landing;
use App\Livewire\Operator\NewTicket as OperatorNewTicket;
use App\Livewire\Operator\Queue as OperatorQueue;
use App\Livewire\Operator\Stats as OperatorStats;
use App\Livewire\Operator\TicketShow as OperatorTicketShow;
use App\Livewire\Settings\NotificationPreferences;
use App\Models\Ticket;
use App\Support\Settings;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
Route::get('/', Landing::class)->name('landing');
Route::get('/manifest.webmanifest', function () {
return response()->json([
'name' => Settings::get('company_name'),
'short_name' => Settings::get('company_name'),
'start_url' => '/',
'scope' => '/',
'display' => 'standalone',
'background_color' => '#f3f5fe',
'theme_color' => Settings::accentColor(),
'lang' => 'pl',
'icons' => [
['src' => asset('pwa-icons/icon-192.png'), 'sizes' => '192x192', 'type' => 'image/png', 'purpose' => 'any'],
['src' => asset('pwa-icons/icon-512.png'), 'sizes' => '512x512', 'type' => 'image/png', 'purpose' => 'any'],
['src' => asset('pwa-icons/icon-192-maskable.png'), 'sizes' => '192x192', 'type' => 'image/png', 'purpose' => 'maskable'],
['src' => asset('pwa-icons/icon-512-maskable.png'), 'sizes' => '512x512', 'type' => 'image/png', 'purpose' => 'maskable'],
],
])->header('Content-Type', 'application/manifest+json');
})->name('manifest');
Route::get('/login', Login::class)->middleware('guest')->name('login');
Route::post('/logout', function () {
Auth::logout();
request()->session()->invalidate();
request()->session()->regenerateToken();
return redirect('/');
})->middleware('auth')->name('logout');
Route::middleware(['auth', 'role:client'])->prefix('client')->name('client.')->group(function () {
Route::get('/', ClientDashboard::class)->name('dashboard');
Route::get('/new', ClientNewTicket::class)->name('new');
Route::get('/tickets/{ticket}', ClientTicketShow::class)->name('ticket');
});
Route::middleware(['auth', 'role:operator'])->prefix('operator')->name('operator.')->group(function () {
Route::get('/', OperatorQueue::class)->name('queue');
Route::get('/new', OperatorNewTicket::class)->name('new');
Route::get('/stats', OperatorStats::class)->name('stats');
Route::get('/tickets/{ticket}', OperatorTicketShow::class)->name('ticket');
// Fired via navigator.sendBeacon on tab/browser close (see the
// MONITOR CZASU PRACY widget in ticket-show.blade.php) — a plain
// Livewire call can't be relied on to complete once the page is
// actually unloading, and sendBeacon needs a normal endpoint to hit.
// Excluded from CSRF verification in bootstrap/app.php since a beacon
// request can't carry the token header.
Route::post('/tickets/{ticket}/stop-timer', function (Ticket $ticket) {
$ticket->stopTimer();
return response()->noContent();
})->name('ticket.stop-timer');
});
Route::middleware(['auth', 'role:admin'])->prefix('admin')->name('admin.')->group(function () {
Route::get('/', AdminPanel::class)->name('panel');
});
Route::middleware(['auth', 'role:operator,admin'])->prefix('settings')->name('settings.')->group(function () {
Route::get('/notifications', NotificationPreferences::class)->name('notifications');
});