@extends('layouts.app') @push('style') @endpush @section('content') @php $settingsTabs = [ ['key' => 'ip-settings', 'label' => 'IP Settings', 'icon' => 'network'], ['key' => 'sip-nat', 'label' => 'SIP / NAT', 'icon' => 'shield'], ['key' => 'rtp-media', 'label' => 'RTP / Media', 'icon' => 'radio'], ['key' => 'webrtc', 'label' => 'WebRTC', 'icon' => 'headphones'], ['key' => 'ssl-tls', 'label' => 'SSL / TLS', 'icon' => 'lock'], ['key' => 'pbx-defaults', 'label' => 'PBX Defaults', 'icon' => 'sliders-horizontal'], ['key' => 'modules', 'label' => 'Modules', 'icon' => 'puzzle'], ['key' => 'backups', 'label' => 'Backups', 'icon' => 'hard-drive-download'], ['key' => 'system-actions', 'label' => 'System Actions', 'icon' => 'settings-2'], ['key' => 'version', 'label' => 'Version', 'icon' => 'info'], ]; $ipSettings = $settings['ip_settings'] ?? []; @endphp {{-- Page header --}}

System Settings

Manage network, SIP, RTP, backups, and system operations.
Reload
{{-- Tab navigation --}}
@foreach ($settingsTabs as $tab) {{ $tab['label'] }} @endforeach
{{-- Alerts --}} @foreach(['success','status'] as $_fk) @if(session($_fk)) @endif @endforeach @if(session('error')) @endif @if ($errors->any()) @endif {{-- ═══════════════════════ IP SETTINGS ═══════════════════════ --}} @if ($activeTab === 'ip-settings')
Hostname
{{ $networkInfo['hostname'] ?: 'Unknown' }}
Current system hostname
Interface
{{ $networkInfo['interface'] ?: 'Unknown' }}
Primary default-route interface
IP Address
{{ $networkInfo['address'] ?: 'Unknown' }}
First detected host IP
IP Configuration
@csrf
Apply Configuration
Apply saved settings to the OS network stack via NetworkManager.
@csrf
Current routes
{{ $networkInfo['routes'] ?: 'No route information detected.' }}
@endif {{-- ═══════════════════════ SIP / NAT ═══════════════════════ --}} @if ($activeTab === 'sip-nat')
SIP / NAT Settings
@csrf
@error('external_signaling_address')
{{ $message }}
@enderror
Used in SIP Contact and Via headers sent to external endpoints.
@error('external_media_address')
{{ $message }}
@enderror
Written into SDP c= line so phones know where to send RTP audio.
@error('local_nets')
{{ $message }}
@enderror
NAT rewrite is skipped for hosts in these ranges.
Current Transport Status
Bind Address0.0.0.0:5060 (UDP)
External Signalling{{ $sipNat['external_signaling_address'] ?: '—' }}
External Media{{ $sipNat['external_media_address'] ?: '—' }}
Local Networks{{ $sipNat['local_nets'] ?: '—' }}
Per-extension NAT settings are automatically applied to all SIP phone extensions on save.
@endif {{-- ═══════════════════════ RTP / MEDIA ═══════════════════════ --}} @if ($activeTab === 'rtp-media')
RTP / Media Settings
@csrf
@error('strict_rtp')
{{ $message }}
@enderror
Controls whether Asterisk drops RTP from unexpected sources. Disable if recordings break up or calls have one-way audio.
@error('rtp_symmetric')
{{ $message }}
@enderror
Send RTP back to the same address/port it was received from. Required for most NAT scenarios and when recording is active.
@error('force_rport')
{{ $message }}
@enderror
Forces responses to be sent back to the port from which the request was received.
@error('use_ptime')
{{ $message }}
@enderror
Honour the ptime value negotiated in SDP. Enable when trunks use non-standard packetisation times (e.g. G.729 at 60 ms).
Current RTP Status
Strict RTP{{ $rtpMedia['strict_rtp'] }}
RTP Symmetric{{ $rtpMedia['rtp_symmetric'] }}
Force RPORT{{ $rtpMedia['force_rport'] }}
Use ptime{{ $rtpMedia['use_ptime'] }}
Applies to all trunks. Individual extension RTP settings are managed per-extension.
@endif {{-- ═══════════════════════ WebRTC / ICE ═══════════════════════ --}} @if ($activeTab === 'webrtc')
WebRTC / ICE Settings

Configure STUN/TURN servers for the webphone. These settings control how WebRTC calls establish media connections for both internal and remote users.

@csrf
Helps remote users discover their public IP. Google's free STUN works well for most cases. Leave empty to disable.
Required for users behind strict firewalls (hotels, corporate, LTE). Relays media when direct UDP is blocked.
Maximum time to wait for STUN/TURN responses before sending the call. Default 500ms. Increase if remote users have slow connections.
How WebRTC Calling Works

Internal users (office LAN): Calls connect directly using the browser's local IP. No STUN/TURN needed. Setup time: <100ms.

Remote users (home/mobile): STUN discovers the user's public IP for NAT traversal. Setup time: <300ms.

Strict firewalls (hotel/corporate): TURN relays media through the server when direct UDP is blocked. Setup time: <500ms.


Smart ICE Gathering:

The webphone uses a timeout-based approach. It waits up to the configured timeout for STUN/TURN responses. If they arrive quickly, they're included in the call. If not, the call proceeds with whatever candidates are available.

The server's external IP is configured in SIP / NAT tab. WebRTC uses the same settings automatically.

Current Status
@php $sipNatCurrent = $sipNat ?? []; $extIp = $sipNatCurrent['external_media_address'] ?? 'Not configured'; $localNet = $sipNatCurrent['local_nets'] ?? 'Not configured'; @endphp
External Media IP {{ $extIp }}
Local Networks {{ str_replace("\n", ', ', $localNet) }}
STUN {{ !empty($webrtc['stun_server']) ? 'Configured' : 'Disabled' }}
TURN {{ !empty($webrtc['turn_server']) ? 'Configured' : 'Not configured' }}
ICE Timeout {{ $webrtc['ice_gathering_timeout'] ?? 500 }}ms
@endif {{-- ═══════════════════════ SSL / TLS ═══════════════════════ --}} @if ($activeTab === 'ssl-tls') @php $ssl = $sslInfo; @endphp {{-- Status cards --}}
Certificate
{{ $ssl['has_cert'] ? ($ssl['is_expired'] ? 'Expired' : 'Valid') : 'None' }}
{{ $ssl['subject'] ?: 'No certificate loaded' }}
Issuer
{{ $ssl['issuer'] ?: 'Unknown' }}
{{ $ssl['is_self_signed'] ? 'Self-signed (WebPhone will NOT work)' : 'Trusted CA' }}
Expires
{{ $ssl['has_cert'] ? $ssl['days_left'] . ' days' : 'N/A' }}
{{ $ssl['valid_to'] ?: 'No certificate' }}
WebPhone Ready
{{ ($ssl['wss_enabled'] && $ssl['ice_enabled'] && !$ssl['is_self_signed']) ? 'Yes' : 'No' }}
WSS: {{ $ssl['wss_enabled'] ? 'On' : 'Off' }} · ICE: {{ $ssl['ice_enabled'] ? 'On' : 'Off' }}
{{-- Let's Encrypt --}}
Issue Let's Encrypt Certificate Recommended
Automatically obtains a free, trusted SSL certificate from Let's Encrypt. This will also configure Apache for WebSocket proxying and enable ICE for WebRTC (required for the WebPhone). Your domain must already point to this server's IP address.
@csrf
@error('domain')
{{ $message }}
@enderror
Must resolve to this server's IP via DNS (A record).
@error('email')
{{ $message }}
@enderror
For Let's Encrypt renewal notices.
{{-- Manual cert --}}
Manual Certificate
Use your own certificate files (e.g. purchased from a CA or generated elsewhere). Files must already exist on the server filesystem.
@csrf
@error('cert_path')
{{ $message }}
@enderror
@error('key_path')
{{ $message }}
@enderror
{{-- Current cert info --}}
Current Certificate Details
@if ($ssl['has_cert'])
Subject{{ $ssl['subject'] }}
Issuer{{ $ssl['issuer'] }}
Valid From{{ $ssl['valid_from'] }}
Valid To {{ $ssl['valid_to'] }} @if (!$ssl['is_expired']) ({{ $ssl['days_left'] }} days left) @else EXPIRED @endif
Type @if ($ssl['is_self_signed']) Self-Signed @else Trusted CA @endif
Cert File{{ $ssl['cert_path'] }}
Key File{{ $ssl['key_path'] }}
@else
No certificate detected
@endif
WebPhone Requirements
Trusted SSL Certificate (not self-signed)
WebSocket Proxy (WSS on port 443)
ICE Support in RTP (for WebRTC audio)
Domain Name Configured{{ $ssl['domain'] ? ': ' . $ssl['domain'] : '' }}
@if (!$ssl['is_self_signed'] && $ssl['wss_enabled'] && $ssl['ice_enabled'] && $ssl['domain'])
All checks passed. WebPhone is ready to use at https://{{ $ssl['domain'] }}/webphone
@else
WebPhone will not work until all requirements above are met. Issue a Let's Encrypt certificate to fix all issues automatically.
@endif
@endif {{-- ═══════════════════════ PBX DEFAULTS ═══════════════════════ --}} @if ($activeTab === 'pbx-defaults')
Default Call Behaviour

These defaults apply to every extension that doesn't have its own override set. Override an individual extension on its Edit Extension → Call Features tab.

@csrf
Used in scheduled report emails and PDF headers. Falls back to the system hostname if blank.
seconds (5–120)
How long an extension's phones ring before going to voicemail or no-answer forwarding. Most platforms use 15–30 seconds.
transferRecallEnabled()) ? 'checked' : '' }}>
When a transferred call goes unanswered, label it "Recall <ext>: <caller>" so the CFNA destination knows it's a bounce-back. Works for blind and attended transfers.
sec
If a transferred call goes unanswered and the extension has no CFNA configured, ring the call back to the person who transferred it. Only fires for actual transfers (blind or attended) — never on direct calls.
System-wide default for no-answer call forwarding. "External calls only" means unanswered internal extension-to-extension calls are not forwarded. Individual extensions can override this on their Call Features tab (Inherit follows this default).
@endif {{-- ═══════════════════════ BACKUPS ═══════════════════════ --}} @if ($activeTab === 'backups')
Create Backup
Download configuration snapshot
Creates a timestamped archive of the PBX application's key folders and downloads it immediately.
@csrf
Existing Backups
@forelse ($backups as $backup) @empty @endforelse
Filename Modified Size
{{ $backup['name'] }} {{ $backup['modified_at'] }} {{ number_format(($backup['size'] ?? 0) / 1024, 2) }} KB
No backups have been created yet.
@endif {{-- ═══════════════════════ SYSTEM ACTIONS ═══════════════════════ --}} @if ($activeTab === 'system-actions')
Restart Services
Restarts the PBX and web services without requesting a full OS reboot.
@csrf
Reboot System
Schedules a host reboot if the current OS user is allowed to request it.
@csrf
@endif {{-- ═══════════════════════ MODULES ═══════════════════════ --}} @if ($activeTab === 'modules')
Optional Modules

Enable or disable optional platform features for this PBX. Disabled modules are hidden from the menu and cannot be accessed. Turning a module on does not start any activity on its own.

{{-- Automatic Calling (Outbound Campaign Dialler) --}}
Automatic Calling
Outbound campaign calling: phone customer lists, connect answered calls to a call centre team, schedule callbacks, and report on results. Disabled by default.
@if($modules['dialer'] ?? false) Enabled Open module settings @else Disabled @endif
@csrf
@if(!($modules['dialer'] ?? false)) @endif
{{-- Reports & Analytics --}}
Reports & Analytics
Call analytics dashboards — volume, answer rate, busiest hours, direction split and top extensions. Disabled by default.
@if($modules['reports'] ?? false) Enabled Open reports @else Disabled @endif
@csrf
{{-- Call Center Wallboard --}}
Call Center Wallboard
Fullscreen live wallboard for an office TV — queue waits, agent status, live call activity and daily stats. Disabled by default.
@if($modules['wallboard'] ?? false) Enabled Open wallboard @else Disabled @endif
@csrf
{{-- Scheduled Reports --}}
Scheduled Reports
Automated email reports with PDF/Excel attachments — management summary, call analytics, missed calls. Daily, weekly, or monthly.
@if($modules['scheduled_reports'] ?? false) Enabled Manage schedules @else Disabled @endif
@csrf
{{-- Shared activation prompt for password-protected modules --}}
@endif {{-- ═══════════════════════ VERSION ═══════════════════════ --}} @if ($activeTab === 'version')
System Version
Current Version
{{ $version }}
VConnect PBX Administration Panel
Version Information
Release Notes
Version 4.0 includes enhanced audit logging, improved UI with light mode, and support for inbound/outbound routes, IVRs, and call center queues.
System Status
All systems operational {{ now()->format('Y-m-d H:i:s') }}
@endif @endsection @push('scripts') @endpush