completed clients and MNO module

This commit is contained in:
Kwesi Banson Jnr
2026-08-12 20:25:43 +00:00
parent cab4591777
commit 65245e5bc9
27 changed files with 1607 additions and 471 deletions

View File

@@ -22,65 +22,56 @@
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h4 class="fw-bold mb-1">Mobile Network Operators (MNO)</h4>
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage telecommunications carrier connections, signaling links, and gateways.</p>
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage MNO details, connections and others</p>
</div>
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenMnoModal">
<i class="bi bi-broadcast-pin me-2"></i> Add MNO Partner
</button>
</div>
<!-- Dynamic Metrics Cards -->
<div class="row g-4 mb-4">
<div class="col-xl-3 col-md-6">
<div class="col-xl-4 col-md-6">
<div class="content-card p-3 h-100 border-start border-4 border-0" style="border-left-color: #5c4df0 !important;">
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">ACTIVE CONNECTIONS</div>
<h3 class="fw-bold mb-0">4 <span class="fs-6 fw-normal text-success"><i class="bi bi-arrow-up"></i> 100% Up</span></h3>
<h3 class="fw-bold mb-0">{{ $totalActive }} <span class="fs-6 fw-normal text-success"><i class="bi bi-arrow-up"></i> Online</span></h3>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="col-xl-4 col-md-6">
<div class="content-card p-3 h-100 border-start border-4 border-0" style="border-left-color: #10b981 !important;">
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">PROVISIONED SHORTCODES</div>
<h3 class="fw-bold mb-0">12</h3>
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">VPN LINKS </div>
<h3 class="fw-bold mb-0">{{ $totalSipLinks }} Links</h3>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="col-xl-4 col-md-6">
<div class="content-card p-3 h-100 border-start border-4 border-0" style="border-left-color: #f59e0b !important;">
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">TOTAL SIP TRUNKS</div>
<h3 class="fw-bold mb-0">6 Links</h3>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="content-card p-3 h-100 border-start border-4 border-0" style="border-left-color: #ef4444 !important;">
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">AGGREGATED DAILY VOL</div>
<h3 class="fw-bold mb-0">142.8k <span class="fs-6 fw-normal text-secondary" style="font-size:0.75rem !important;">hits</span></h3>
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">REGISTERED MNO PARTNERS</div>
<h3 class="fw-bold mb-0">{{ $totalOperators }}</h3>
</div>
</div>
</div>
<div class="content-card">
<div class="p-3 border-bottom bg-light bg-opacity-50">
<div class="row g-3">
<form method="GET" action="{{ route('mnos.index') }}" class="row g-3">
<div class="col-md-6">
<div class="input-group">
<span class="input-group-text bg-white border-end-0 text-secondary"><i class="bi bi-search"></i></span>
<input type="text" class="form-control bg-white border-start-0 ps-0" placeholder="Search gateways, IPs, or partner networks...">
<input type="text" name="search" value="{{ request('search') }}" class="form-control bg-white border-start-0 ps-0" placeholder="Search here...">
</div>
</div>
<div class="col-md-3">
<select class="form-select bg-white">
<option value="">All Regions</option>
<option value="GH">Ghana (GH)</option>
<option value="ZM">Zambia (ZM)</option>
</select>
@include('network_operators.partials.countries')
</div>
<div class="col-md-3">
<select class="form-select bg-white">
<option value="">All Link Types</option>
<option value="vpn">IPsec VPN</option>
<option value="tailscale">IPSec VPN Tunnel</option>
<option value="public">Whitelisted Public IP</option>
<select name="connection_status" class="form-select bg-white" onchange="this.form.submit()">
<option value="">Any Status</option>
<option value="Active" {{ request('link_type') == 'vpn' ? 'selected' : '' }}>Active</option>
<option value="Inactive" {{ request('link_type') == 'direct' ? 'selected' : '' }}>Inactive</option>
<option value="Pending" {{ request('link_type') == 'direct' ? 'selected' : '' }}>Pending</option>
</select>
</div>
</div>
</form>
</div>
<div class="table-responsive">
@@ -89,251 +80,87 @@
<tr>
<th>Operator</th>
<th>Country</th>
<th>Network Codes</th>
<th>Infrastructure Links</th>
<th>Capabilities</th>
<th>Link Status</th>
<th>Connection Type</th>
<th>Services</th>
<th>Status</th>
<th class="text-end">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center">
<div class="avatar-circle bg-warning bg-opacity-10 text-warning me-3">MTN</div>
<div>
<div class="fw-bold text-dark">MTN Ghana</div>
<div class="text-secondary" style="font-size: 0.8rem;">Scancom PLC</div>
@forelse($operators as $operator)
<tr>
<td>
<div class="d-flex align-items-center">
<div class="avatar-circle bg-primary bg-opacity-10 text-primary me-3">
{{ strtoupper(substr($operator->name, 0, 2)) }}
</div>
<div>
<div class="fw-bold text-dark">{{ $operator->name }}</div>
<div class="text-secondary" style="font-size: 0.8rem;">{{ $operator->contact_person ?? 'N/A' }}</div>
</div>
</div>
</div>
</td>
<td><span class="fw-semibold">Ghana (GH)</span></td>
<td>
<span class="tech-badge">MCC: 620</span>
<span class="tech-badge">MNC: 01</span>
</td>
<td>
<div class="text-dark fw-semibold" style="font-size: 0.85rem;"><i class="bi bi-shield-lock me-1 text-primary"></i> IPsec VPN Tunnel</div>
<div class="text-secondary style" style="font-size: 0.75rem;">Gateway: 172.16.42.1</div>
</td>
<td>
<div class="d-flex gap-1 flex-wrap">
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">USSD</span>
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">SMS Gateway</span>
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">SIP Trunk</span>
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">MoMo API</span>
</div>
</td>
<td>
<span class="d-flex align-items-center gap-2">
<span class="status-indicator bg-success"></span>
<span class="fw-semibold text-success" style="font-size: 0.85rem;">Online</span>
</span>
</td>
<td class="text-end">
<button class="btn btn-sm btn-light text-secondary me-1"><i class="bi bi-terminal"></i></button>
<button class="btn btn-sm btn-light text-primary btn-edit-mno"
data-id="1" data-name="MTN Ghana" data-company="Scancom PLC" data-country="GH" data-mcc="620" data-mnc="01" data-link="vpn" data-gateway="172.16.42.1" data-capabilities='["ussd","sms","voice","momo"]' data-status="online">
<i class="bi bi-pencil"></i>
</button>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center">
<div class="avatar-circle bg-danger bg-opacity-10 text-danger me-3">TL</div>
<div>
<div class="fw-bold text-dark">Telecel Ghana</div>
<div class="text-secondary" style="font-size: 0.8rem;">Telecel Group</div>
</td>
<td><span class="fw-semibold">{{ $operator->country }}</span></td>
<td>
<div class="text-dark fw-semibold" style="font-size: 0.85rem;"><i class="bi bi-shield-lock me-1 text-primary"></i> {{ $operator->connection_type ?? 'N/A' }}</div>
</td>
<td>
<div class="d-flex gap-1 flex-wrap">
@if(is_array($operator->services))
@foreach($operator->services as $service)
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">{{ strtoupper($service) }}</span>
@endforeach
@else
<span class="text-muted small">None</span>
@endif
</div>
</div>
</td>
<td><span class="fw-semibold">Ghana (GH)</span></td>
<td>
<span class="tech-badge">MCC: 620</span>
<span class="tech-badge">MNC: 02</span>
</td>
<td>
<div class="text-dark fw-semibold" style="font-size: 0.85rem;"><i class="bi bi-shuffle me-1 text-info"></i> VPN Tunnel</div>
<div class="text-secondary" style="font-size: 0.75rem;">Peer IP: 100.115.2.4</div>
</td>
<td>
<div class="d-flex gap-1 flex-wrap">
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">USSD</span>
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">SMS Gateway</span>
<span class="badge bg-secondary text-dark border bg-light" style="font-size: 0.65rem;">Payment API</span>
</div>
</td>
<td>
<span class="d-flex align-items-center gap-2">
<span class="status-indicator bg-success"></span>
<span class="fw-semibold text-success" style="font-size: 0.85rem;">Online</span>
</span>
</td>
<td class="text-end">
<button class="btn btn-sm btn-light text-secondary me-1"><i class="bi bi-terminal"></i></button>
<button class="btn btn-sm btn-light text-primary btn-edit-mno"
data-id="2" data-name="Telecel Ghana" data-company="Telecel Group" data-country="GH" data-mcc="620" data-mnc="02" data-link="tailscale" data-gateway="100.115.2.4" data-capabilities='["ussd","sms","momo"]' data-status="online">
<i class="bi bi-pencil"></i>
</button>
</td>
</tr>
</td>
<td>
<span class="d-flex align-items-center gap-2">
<span class="status-indicator {{ ($operator->connection_status == 'Active') ? 'bg-success' : 'bg-danger' }}"></span>
<span class="fw-semibold {{ ($operator->connection_status == 'Active') ? 'text-success' : 'text-danger' }}" style="font-size: 0.85rem;">
{{ $operator->connection_status ?? 'N/A' }}
</span>
</span>
</td>
<td class="text-end">
<div class="d-flex gap-1 justify-content-end align-items-center">
<a href="{{ route('mnos.show', $operator->id) }}" class="btn btn-sm btn-light text-secondary me-1" title="View Details">
<i class="bi bi-eye"></i>
</a>
<button class="btn btn-sm btn-light text-primary btn-edit-mno" data-id="{{ $operator->id }}" title="Edit MNO">
<i class="bi bi-pencil"></i>
</button>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center py-4 text-muted">No MNO partners found.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- Pagination Links Footer -->
@if($operators->hasPages())
<div class="p-3 border-top bg-light bg-opacity-50 d-flex justify-content-between align-items-center">
<div class="text-secondary small">
Showing {{ $operators->firstItem() }} to {{ $operators->lastItem() }} of {{ $operators->total() }} MNO partners
</div>
<div>
{{ $operators->links() }}
</div>
</div>
@endif
</div>
</div>
@endsection
@push('modals')
<div class="modal fade" id="mnoModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-light">
<h5 class="modal-title fw-bold" id="mnoModalTitle">Configure MNO Link</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form id="mnoForm">
<div class="modal-body p-4">
<input type="hidden" id="mnoId" name="id">
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Carrier Identity</h6>
<div class="row g-3 mb-4">
<div class="col-md-6">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Brand Name *</label>
<input type="text" class="form-control" id="mnoName" name="name" required placeholder="e.g. MTN Ghana">
</div>
<div class="col-md-6">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Registered Corporate Title</label>
<input type="text" class="form-control" id="mnoCompany" name="corporate_name" placeholder="e.g. Scancom PLC">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Operating Country *</label>
<select class="form-select" id="mnoCountry" name="country_code" required>
<option value="GH">Ghana (GH)</option>
<option value="ZM">Zambia (ZM)</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Mobile Country Code (MCC) *</label>
<input type="text" class="form-control" id="mnoMcc" name="mcc" required placeholder="e.g. 620">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Mobile Network Code (MNC) *</label>
<input type="text" class="form-control" id="mnoMnc" name="mnc" required placeholder="e.g. 01">
</div>
</div>
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Network & Transport Configuration</h6>
<div class="row g-3 mb-4">
<div class="col-md-6">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Interconnect Type</label>
<select class="form-select" id="mnoLinkType" name="link_type">
<option value="vpn">IPsec VPN Tunnel</option>
<option value="tailscale">Tailscale Overlaid Mesh</option>
<option value="public">Whitelisted Public Endpoint</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Remote Gateway IP / Endpoint Address</label>
<input type="text" class="form-control" id="mnoGateway" name="remote_gateway" placeholder="e.g. 172.16.42.1">
</div>
</div>
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Provisioned Interface Frameworks</h6>
<div class="row g-3">
<div class="col-md-12">
<label class="form-label text-secondary fw-semibold d-block style" style="font-size: 0.85rem; margin-bottom: 0.5rem;">Enable Capabilities</label>
<div class="form-check form-check-inline me-4">
<input class="form-check-input" type="checkbox" id="capUssd" name="capabilities[]" value="ussd">
<label class="form-check-label text-dark" for="capUssd">USSD Gateway (SIGTRAN/M3UA)</label>
</div>
<div class="form-check form-check-inline me-4">
<input class="form-check-input" type="checkbox" id="capSms" name="capabilities[]" value="sms">
<label class="form-check-label text-dark" for="capSms">SMS SMPP Bindings</label>
</div>
<div class="form-check form-check-inline me-4">
<input class="form-check-input" type="checkbox" id="capVoice" name="capabilities[]" value="voice">
<label class="form-check-label text-dark" for="capVoice">SIP Voice Trunking</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="capMomo" name="capabilities[]" value="momo">
<label class="form-check-label text-dark" for="capMomo">Mobile Money Node</label>
</div>
</div>
</div>
</div>
<div class="modal-footer bg-light">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn text-white fw-bold px-4" style="background-color: #5c4df0;" id="btnSubmitMno">
Save Gateway Profile
</button>
</div>
</form>
</div>
</div>
</div>
@include('network_operators.partials.mno_modals')
@endpush
@push('scripts')
<script>
$(document).ready(function() {
const mnoModal = new bootstrap.Modal(document.getElementById('mnoModal'));
const $form = $('#mnoForm');
// --- OPEN MODAL FOR CREATE ---
$('#btnOpenMnoModal').on('click', function() {
$form[0].reset();
$('#mnoId').val('');
$('#mnoModalTitle').text('Configure New MNO Interconnect');
$('#btnSubmitMno').html('<i class="bi bi-save me-2"></i>Save Gateway Profile');
mnoModal.show();
});
// --- OPEN MODAL FOR EDIT ---
$('.btn-edit-mno').on('click', function() {
const data = $(this).data();
$form[0].reset();
$('#mnoId').val(data.id);
$('#mnoName').val(data.name);
$('#mnoCompany').val(data.company);
$('#mnoCountry').val(data.country);
$('#mnoMcc').val(data.mcc);
$('#mnoMnc').val(data.mnc);
$('#mnoLinkType').val(data.link);
$('#mnoGateway').val(data.gateway);
// Clear and map checkmarks safely
$('input[name="capabilities[]"]').prop('checked', false);
if (data.capabilities && Array.isArray(data.capabilities)) {
data.capabilities.forEach(function(cap) {
$('input[value="' + cap + '"]').prop('checked', true);
});
}
$('#mnoModalTitle').text('Modify Link Profiles: ' + data.name);
$('#btnSubmitMno').html('<i class="bi bi-check-circle me-2"></i>Apply Changes');
mnoModal.show();
});
// --- AJAX FORM SUBMISSION SIMULATION ---
$form.on('submit', function(e) {
e.preventDefault();
const $btn = $('#btnSubmitMno');
const originalText = $btn.html();
$btn.html('<span class="spinner-border spinner-border-sm me-2"></span> Updating Trunk Contexts...');
$btn.prop('disabled', true);
setTimeout(() => {
console.log('MNO Payload Synchronized:', $form.serializeArray());
$btn.html(originalText).prop('disabled', false);
mnoModal.hide();
alert('Gateway routing map refreshed successfully.');
}, 900);
});
});
</script>
<script src="{{ asset('public/assets/js/mno_index.js') }} "></script>
@endpush

View File

@@ -0,0 +1,58 @@
<select name="country" class="form-select bg-white" onchange="this.form.submit()">
<option value="">All Regions (Africa)</option>
<option value="Algeria" {{ request('country') == 'Algeria' ? 'selected' : '' }}>Algeria</option>
<option value="Angola" {{ request('country') == 'Angola' ? 'selected' : '' }}>Angola</option>
<option value="Benin" {{ request('country') == 'Benin' ? 'selected' : '' }}>Benin</option>
<option value="Botswana" {{ request('country') == 'Botswana' ? 'selected' : '' }}>Botswana</option>
<option value="Burkina Faso" {{ request('country') == 'Burkina Faso' ? 'selected' : '' }}>Burkina Faso</option>
<option value="Burundi" {{ request('country') == 'Burundi' ? 'selected' : '' }}>Burundi</option>
<option value="Cabo Verde" {{ request('country') == 'Cabo Verde' ? 'selected' : '' }}>Cabo Verde</option>
<option value="Cameroon" {{ request('country') == 'Cameroon' ? 'selected' : '' }}>Cameroon</option>
<option value="Central African Republic" {{ request('country') == 'Central African Republic' ? 'selected' : '' }}>Central African Republic</option>
<option value="Chad" {{ request('country') == 'Chad' ? 'selected' : '' }}>Chad</option>
<option value="Comoros" {{ request('country') == 'Comoros' ? 'selected' : '' }}>Comoros</option>
<option value="Congo" {{ request('country') == 'Congo' ? 'selected' : '' }}>Congo</option>
<option value="Democratic Republic of the Congo" {{ request('country') == 'Democratic Republic of the Congo' ? 'selected' : '' }}>Democratic Republic of the Congo</option>
<option value="Cote d'Ivoire" {{ request('country') == "Cote d'Ivoire" ? 'selected' : '' }}>Cote d'Ivoire</option>
<option value="Djibouti" {{ request('country') == 'Djibouti' ? 'selected' : '' }}>Djibouti</option>
<option value="Egypt" {{ request('country') == 'Egypt' ? 'selected' : '' }}>Egypt</option>
<option value="Equatorial Guinea" {{ request('country') == 'Equatorial Guinea' ? 'selected' : '' }}>Equatorial Guinea</option>
<option value="Eritrea" {{ request('country') == 'Eritrea' ? 'selected' : '' }}>Eritrea</option>
<option value="Eswatini" {{ request('country') == 'Eswatini' ? 'selected' : '' }}>Eswatini</option>
<option value="Ethiopia" {{ request('country') == 'Ethiopia' ? 'selected' : '' }}>Ethiopia</option>
<option value="Gabon" {{ request('country') == 'Gabon' ? 'selected' : '' }}>Gabon</option>
<option value="Gambia" {{ request('country') == 'Gambia' ? 'selected' : '' }}>Gambia</option>
<option value="Ghana" {{ request('country') == 'Ghana' ? 'selected' : '' }}>Ghana</option>
<option value="Guinea" {{ request('country') == 'Guinea' ? 'selected' : '' }}>Guinea</option>
<option value="Guinea-Bissau" {{ request('country') == 'Guinea-Bissau' ? 'selected' : '' }}>Guinea-Bissau</option>
<option value="Kenya" {{ request('country') == 'Kenya' ? 'selected' : '' }}>Kenya</option>
<option value="Lesotho" {{ request('country') == 'Lesotho' ? 'selected' : '' }}>Lesotho</option>
<option value="Liberia" {{ request('country') == 'Liberia' ? 'selected' : '' }}>Liberia</option>
<option value="Libya" {{ request('country') == 'Libya' ? 'selected' : '' }}>Libya</option>
<option value="Madagascar" {{ request('country') == 'Madagascar' ? 'selected' : '' }}>Madagascar</option>
<option value="Malawi" {{ request('country') == 'Malawi' ? 'selected' : '' }}>Malawi</option>
<option value="Mali" {{ request('country') == 'Mali' ? 'selected' : '' }}>Mali</option>
<option value="Mauritania" {{ request('country') == 'Mauritania' ? 'selected' : '' }}>Mauritania</option>
<option value="Mauritius" {{ request('country') == 'Mauritius' ? 'selected' : '' }}>Mauritius</option>
<option value="Morocco" {{ request('country') == 'Morocco' ? 'selected' : '' }}>Morocco</option>
<option value="Mozambique" {{ request('country') == 'Mozambique' ? 'selected' : '' }}>Mozambique</option>
<option value="Namibia" {{ request('country') == 'Namibia' ? 'selected' : '' }}>Namibia</option>
<option value="Niger" {{ request('country') == 'Niger' ? 'selected' : '' }}>Niger</option>
<option value="Nigeria" {{ request('country') == 'Nigeria' ? 'selected' : '' }}>Nigeria</option>
<option value="Rwanda" {{ request('country') == 'Rwanda' ? 'selected' : '' }}>Rwanda</option>
<option value="Sao Tome and Principe" {{ request('country') == 'Sao Tome and Principe' ? 'selected' : '' }}>Sao Tome and Principe</option>
<option value="Senegal" {{ request('country') == 'Senegal' ? 'selected' : '' }}>Senegal</option>
<option value="Seychelles" {{ request('country') == 'Seychelles' ? 'selected' : '' }}>Seychelles</option>
<option value="Sierra Leone" {{ request('country') == 'Sierra Leone' ? 'selected' : '' }}>Sierra Leone</option>
<option value="Somalia" {{ request('country') == 'Somalia' ? 'selected' : '' }}>Somalia</option>
<option value="South Africa" {{ request('country') == 'South Africa' ? 'selected' : '' }}>South Africa</option>
<option value="South Sudan" {{ request('country') == 'South Sudan' ? 'selected' : '' }}>South Sudan</option>
<option value="Sudan" {{ request('country') == 'Sudan' ? 'selected' : '' }}>Sudan</option>
<option value="Tanzania" {{ request('country') == 'Tanzania' ? 'selected' : '' }}>Tanzania</option>
<option value="Togo" {{ request('country') == 'Togo' ? 'selected' : '' }}>Togo</option>
<option value="Tunisia" {{ request('country') == 'Tunisia' ? 'selected' : '' }}>Tunisia</option>
<option value="Uganda" {{ request('country') == 'Uganda' ? 'selected' : '' }}>Uganda</option>
<option value="Zambia" {{ request('country') == 'Zambia' ? 'selected' : '' }}>Zambia</option>
<option value="Zimbabwe" {{ request('country') == 'Zimbabwe' ? 'selected' : '' }}>Zimbabwe</option>
</select>

View File

@@ -0,0 +1,165 @@
<div class="modal fade" id="mnoModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-light">
<h5 class="modal-title fw-bold" id="mnoModalTitle"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form id="mnoForm" method="POST" action="{{ url('mnos') }}">
@csrf
<div id="methodField"></div>
<div class="modal-body p-4">
<input type="hidden" id="mnoId" name="id">
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Carrier Identity</h6>
<div class="row g-3 mb-4">
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Brand Name *</label>
<input type="text" class="form-control" id="mnoName" name="name" required placeholder="e.g. MTN Ghana">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem; width: 100%;">Operating Country *</label>
<select class="form-select w-100" id="mnoCountry" name="country" required>
<option value="">Select Country</option>
<option value="Algeria">Algeria</option>
<option value="Angola">Angola</option>
<option value="Benin">Benin</option>
<option value="Botswana">Botswana</option>
<option value="Burkina Faso">Burkina Faso</option>
<option value="Burundi">Burundi</option>
<option value="Cabo Verde">Cabo Verde</option>
<option value="Cameroon">Cameroon</option>
<option value="Central African Republic">Central African Republic</option>
<option value="Chad">Chad</option>
<option value="Comoros">Comoros</option>
<option value="Congo">Congo</option>
<option value="Democratic Republic of the Congo">Democratic Republic of the Congo</option>
<option value="Cote d'Ivoire">Cote d'Ivoire</option>
<option value="Djibouti">Djibouti</option>
<option value="Egypt">Egypt</option>
<option value="Equatorial Guinea">Equatorial Guinea</option>
<option value="Eritrea">Eritrea</option>
<option value="Eswatini">Eswatini</option>
<option value="Ethiopia">Ethiopia</option>
<option value="Gabon">Gabon</option>
<option value="Gambia">Gambia</option>
<option value="Ghana">Ghana</option>
<option value="Guinea">Guinea</option>
<option value="Guinea-Bissau">Guinea-Bissau</option>
<option value="Kenya">Kenya</option>
<option value="Lesotho">Lesotho</option>
<option value="Liberia">Liberia</option>
<option value="Libya">Libya</option>
<option value="Madagascar">Madagascar</option>
<option value="Malawi">Malawi</option>
<option value="Mali">Mali</option>
<option value="Mauritania">Mauritania</option>
<option value="Mauritius">Mauritius</option>
<option value="Morocco">Morocco</option>
<option value="Mozambique">Mozambique</option>
<option value="Namibia">Namibia</option>
<option value="Niger">Niger</option>
<option value="Nigeria">Nigeria</option>
<option value="Rwanda">Rwanda</option>
<option value="Sao Tome and Principe">Sao Tome and Principe</option>
<option value="Senegal">Senegal</option>
<option value="Seychelles">Seychelles</option>
<option value="Sierra Leone">Sierra Leone</option>
<option value="Somalia">Somalia</option>
<option value="South Africa">South Africa</option>
<option value="South Sudan">South Sudan</option>
<option value="Sudan">Sudan</option>
<option value="Tanzania">Tanzania</option>
<option value="Togo">Togo</option>
<option value="Tunisia">Tunisia</option>
<option value="Uganda">Uganda</option>
<option value="Zambia">Zambia</option>
<option value="Zimbabwe">Zimbabwe</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Connection Status</label>
<select class="form-select" id="mnoConnectionStatus" name="connection_status">
<option value="Active">Active</option>
<option value="Inactive">Inactive</option>
<option value="Pending">Pending</option>
</select>
</div>
</div>
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Contact & Support Personnel</h6>
<div class="row g-3 mb-4">
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Contact Person</label>
<input type="text" class="form-control" id="mnoContactPerson" name="contact_person" placeholder="Full name">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Contact Phone</label>
<input type="text" class="form-control" id="mnoContactPhone" name="contact_person_phone" placeholder="Phone number">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Contact Email</label>
<input type="email" class="form-control" id="mnoContactEmail" name="contact_person_email" placeholder="Email address">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Technical Support Person</label>
<input type="text" class="form-control" id="mnoTechSupport" name="technical_support_person" placeholder="Tech contact">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Support Skype</label>
<input type="text" class="form-control" id="mnoSupportSkype" name="support_skype" placeholder="Skype ID">
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Account Manager</label>
<input type="text" class="form-control" id="mnoAccountManager" name="mno_account_manager" placeholder="Manager name">
</div>
</div>
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Multi-Entry & Services Configuration</h6>
<div class="row g-3 mb-4">
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Services</label>
<select name="services[]" id="mnoServices" class="form-select select2-db" multiple="multiple"></select>
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Support Emails</label>
<select name="support_emails[]" id="mnoSupportEmails" class="form-select select2-tags" multiple="multiple"></select>
</div>
<div class="col-md-4">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Finance Emails</label>
<select name="finance_emails[]" id="mnoFinanceEmails" class="form-select select2-tags" multiple="multiple"></select>
</div>
</div>
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Commercial & Technical Configurations</h6>
<div class="row g-3">
<div class="col-md-3">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Buying Rate</label>
<input type="number" step="0.0001" class="form-control" id="mnoBuyingRate" name="buying_rate" value="0.0000">
</div>
<div class="col-md-3">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Rate Type</label>
<input type="text" class="form-control" id="mnoRateType" name="rate_type" placeholder="e.g. Fixed / Tiered">
</div>
<div class="col-md-3">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Payment Terms</label>
<input type="text" class="form-control" id="mnoPaymentTerms" name="payment_terms" placeholder="e.g. Net 30">
</div>
<div class="col-md-3">
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Connection Type</label>
<input type="text" class="form-control" id="mnoConnectionType" name="connection_type" placeholder="e.g. SMPP / API">
</div>
</div>
</div>
<div class="modal-footer bg-light">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn text-white fw-bold px-4" style="background-color: #5c4df0;" id="btnSubmitMno">
Save Gateway Profile
</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,161 @@
@extends('layouts.masterbeta')
@section('title', 'Cick ERP - ' . $operator->name)
@section('breadcrumbs')
<a href="{{ url('/') }}" class="text-secondary text-decoration-none"><i class="bi bi-house me-2"></i></a>
<i class="bi bi-chevron-right text-secondary me-2" style="font-size: 0.8rem;"></i>
<a href="{{ route('mnos.index') }}" class="text-secondary text-decoration-none me-2" style="font-size: 0.95rem;">MNO Partners</a>
<i class="bi bi-chevron-right text-secondary me-2" style="font-size: 0.8rem;"></i>
<span class="fw-bold" style="font-size: 0.95rem;">{{ $operator->name }}</span>
@endsection
@section('content')
<!-- Header Section -->
<div class="d-flex justify-content-between align-items-center mb-4">
<div class="d-flex align-items-center">
<div class="avatar-circle bg-primary bg-opacity-10 text-primary fw-bold me-3 fs-4" style="width: 55px; height: 55px; border-radius: 50%; display: flex; align-items: center; justify-content: center;">
{{ strtoupper(substr($operator->name, 0, 2)) }}
</div>
<div>
<h3 class="fw-bold mb-1">{{ $operator->name }}</h3>
<p class="text-secondary mb-0" style="font-size: 0.9rem;">
<i class="bi bi-geo-alt me-1"></i> {{ $operator->country }} &bull;
<span class="badge {{ $operator->connection_status == 'Online' ? 'bg-success' : 'bg-danger' }} ms-1">
{{ $operator->connection_status ?? 'Offline' }}
</span>
</p>
</div>
</div>
<div>
<a href="{{ route('mnos.index') }}" class="btn btn-outline-secondary btn-sm fw-bold">
<i class="bi bi-arrow-left me-1"></i> Back to List
</a>
</div>
</div>
<!-- Overview Metrics Row -->
<div class="row g-4 mb-4">
<div class="col-xl-4 col-md-6">
<div class="content-card p-3 h-100 border-start border-4 border-primary">
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">CONNECTION TYPE</div>
<h5 class="fw-bold mb-0 text-dark">{{ $operator->connection_type ?? 'Standard Link' }}</h5>
</div>
</div>
<div class="col-xl-4 col-md-6">
<div class="content-card p-3 h-100 border-start border-4 border-success">
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">BUYING RATE</div>
<h5 class="fw-bold mb-0 text-dark">{{ $operator->buying_rate ? number_format($operator->buying_rate, 4) : '0.0000' }}</h5>
</div>
</div>
<div class="col-xl-4 col-md-6">
<div class="content-card p-3 h-100 border-start border-4 border-warning">
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">PAYMENT TERMS</div>
<h5 class="fw-bold mb-0 text-dark">{{ $operator->payment_terms ?? 'N/A' }}</h5>
</div>
</div>
</div>
<!-- Detailed Attributes Grid -->
<div class="row g-4">
<!-- Left Column: Carrier & Technical Meta -->
<div class="col-lg-8">
<div class="content-card p-4 mb-4">
<h5 class="fw-bold mb-3 text-secondary" style="font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.5px;">
<i class="bi bi-info-circle me-2 text-primary"></i> Carrier & Technical Configuration
</h5>
<hr class="text-muted opacity-25">
<div class="row g-3">
<div class="col-md-6">
<span class="text-muted small d-block">Operating Country</span>
<strong class="text-dark">{{ $operator->country }}</strong>
</div>
<div class="col-md-6">
<span class="text-muted small d-block">Rate Type</span>
<strong class="text-dark">{{ $operator->rate_type ?? 'N/A' }}</strong>
</div>
<div class="col-md-6">
<span class="text-muted small d-block">Account Manager</span>
<strong class="text-dark">{{ $operator->mno_account_manager ?? 'N/A' }}</strong>
</div>
<div class="col-md-6">
<span class="text-muted small d-block">Direct Business</span>
<strong class="text-dark">{{ $operator->direct_business ?? 'YES' }}</strong>
</div>
</div>
</div>
<!-- Provisioned Services Badges -->
<div class="content-card p-4">
<h5 class="fw-bold mb-3 text-secondary" style="font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.5px;">
<i class="bi bi-layers me-2 text-primary"></i> Provisioned Services
</h5>
<hr class="text-muted opacity-25">
<div class="d-flex flex-wrap gap-2">
@if(is_array($operator->services) && count($operator->services) > 0)
@foreach($operator->services as $service)
<span class="badge bg-light text-primary border px-3 py-2" style="font-size: 0.85rem;">
<i class="bi bi-check-circle-fill me-1 text-success"></i> {{ is_numeric($service) ? App\Models\Service::find($service)->name ?? 'Service #'.$service : $service }}
</span>
@endforeach
@else
<span class="text-muted small">No specific services provisioned.</span>
@endif
</div>
</div>
</div>
<!-- Right Column: Contacts & Support Channels -->
<div class="col-lg-4">
<div class="content-card p-4 mb-4">
<h5 class="fw-bold mb-3 text-secondary" style="font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.5px;">
<i class="bi bi-headset me-2 text-primary"></i> Support Contacts
</h5>
<hr class="text-muted opacity-25">
<div class="mb-3">
<span class="text-muted small d-block">Contact Person</span>
<strong class="text-dark">{{ $operator->contact_person ?? 'N/A' }}</strong>
</div>
<div class="mb-3">
<span class="text-muted small d-block">Direct Phone</span>
<strong class="text-dark">{{ $operator->contact_person_phone ?? 'N/A' }}</strong>
</div>
<div class="mb-3">
<span class="text-muted small d-block">Technical Support Lead</span>
<strong class="text-dark">{{ $operator->technical_support_person ?? 'N/A' }}</strong>
</div>
<div class="mb-3">
<span class="text-muted small d-block">Support MS Team</span>
<strong class="text-dark">{{ $operator->support_skype ?? 'N/A' }}</strong>
</div>
<div class="mb-3">
<span class="text-muted small d-block mb-1">Support Emails</span>
<div class="d-flex flex-wrap gap-1">
@if(is_array($operator->support_emails) && count($operator->support_emails) > 0)
@foreach($operator->support_emails as $email)
<span class="badge bg-secondary bg-opacity-10 text-dark border" style="font-size: 0.75rem;">{{ $email }}</span>
@endforeach
@else
<span class="text-muted small">None listed</span>
@endif
</div>
</div>
<div>
<span class="text-muted small d-block mb-1">Finance Emails</span>
<div class="d-flex flex-wrap gap-1">
@if(is_array($operator->finance_emails) && count($operator->finance_emails) > 0)
@foreach($operator->finance_emails as $email)
<span class="badge bg-secondary bg-opacity-10 text-dark border" style="font-size: 0.75rem;">{{ $email }}</span>
@endforeach
@else
<span class="text-muted small">None listed</span>
@endif
</div>
</div>
</div>
</div>
</div>
@endsection