Initial commit
This commit is contained in:
2
resources/css/app.css
Normal file
2
resources/css/app.css
Normal file
@@ -0,0 +1,2 @@
|
||||
@import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
@import './erp.css';
|
||||
17
resources/css/erp.css
Normal file
17
resources/css/erp.css
Normal file
@@ -0,0 +1,17 @@
|
||||
#sidebar {
|
||||
width: 260px;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
#sidebar.collapsed {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#main-content {
|
||||
margin-left: 260px;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
#main-content.expanded {
|
||||
margin-left: 80px;
|
||||
}
|
||||
2
resources/js/app.js
Normal file
2
resources/js/app.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import './bootstrap';
|
||||
import './erp';
|
||||
34
resources/js/bootstrap.js
vendored
Normal file
34
resources/js/bootstrap.js
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import 'bootstrap';
|
||||
|
||||
/**
|
||||
* We'll load the axios HTTP library which allows us to easily issue requests
|
||||
* to our Laravel back-end. This library automatically handles sending the
|
||||
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
||||
*/
|
||||
|
||||
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
|
||||
* allows your team to easily build robust real-time web applications.
|
||||
*/
|
||||
|
||||
// import Echo from 'laravel-echo';
|
||||
|
||||
// import Pusher from 'pusher-js';
|
||||
// window.Pusher = Pusher;
|
||||
|
||||
// window.Echo = new Echo({
|
||||
// broadcaster: 'pusher',
|
||||
// key: import.meta.env.VITE_PUSHER_APP_KEY,
|
||||
// cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
|
||||
// wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
|
||||
// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
|
||||
// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
|
||||
// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
|
||||
// enabledTransports: ['ws', 'wss'],
|
||||
// });
|
||||
9
resources/js/erp.js
Normal file
9
resources/js/erp.js
Normal file
@@ -0,0 +1,9 @@
|
||||
$(document).ready(function() {
|
||||
$('#sidebarToggle').on('click', function () {
|
||||
|
||||
$('#sidebar').toggleClass('collapsed');
|
||||
|
||||
$('#main-content').toggleClass('expanded');
|
||||
|
||||
});
|
||||
});
|
||||
7
resources/sass/_variables.scss
Normal file
7
resources/sass/_variables.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
// Body
|
||||
$body-bg: #f8fafc;
|
||||
|
||||
// Typography
|
||||
$font-family-sans-serif: 'Nunito', sans-serif;
|
||||
$font-size-base: 0.9rem;
|
||||
$line-height-base: 1.6;
|
||||
8
resources/sass/app.scss
Normal file
8
resources/sass/app.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
// Fonts
|
||||
@import url('https://fonts.bunny.net/css?family=Nunito');
|
||||
|
||||
// Variables
|
||||
@import 'variables';
|
||||
|
||||
// Bootstrap
|
||||
@import 'bootstrap/scss/bootstrap';
|
||||
1098
resources/views/adminator.blade.php
Normal file
1098
resources/views/adminator.blade.php
Normal file
File diff suppressed because it is too large
Load Diff
73
resources/views/auth/login.blade.php
Normal file
73
resources/views/auth/login.blade.php
Normal file
@@ -0,0 +1,73 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Login') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
|
||||
<label class="form-check-label" for="remember">
|
||||
{{ __('Remember Me') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Login') }}
|
||||
</button>
|
||||
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn btn-link" href="{{ route('password.request') }}">
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
49
resources/views/auth/passwords/confirm.blade.php
Normal file
49
resources/views/auth/passwords/confirm.blade.php
Normal file
@@ -0,0 +1,49 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Confirm Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
{{ __('Please confirm your password before continuing.') }}
|
||||
|
||||
<form method="POST" action="{{ route('password.confirm') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Confirm Password') }}
|
||||
</button>
|
||||
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn btn-link" href="{{ route('password.request') }}">
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
47
resources/views/auth/passwords/email.blade.php
Normal file
47
resources/views/auth/passwords/email.blade.php
Normal file
@@ -0,0 +1,47 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('password.email') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Send Password Reset Link') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
65
resources/views/auth/passwords/reset.blade.php
Normal file
65
resources/views/auth/passwords/reset.blade.php
Normal file
@@ -0,0 +1,65 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Reset Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('password.update') }}">
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="token" value="{{ $token }}">
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Reset Password') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
77
resources/views/auth/register.blade.php
Normal file
77
resources/views/auth/register.blade.php
Normal file
@@ -0,0 +1,77 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Register') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('register') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="name" class="col-md-4 col-form-label text-md-end">{{ __('Name') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
|
||||
|
||||
@error('name')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Register') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
28
resources/views/auth/verify.blade.php
Normal file
28
resources/views/auth/verify.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Verify Your Email Address') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('resent'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ __('A fresh verification link has been sent to your email address.') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{ __('Before proceeding, please check your email for a verification link.') }}
|
||||
{{ __('If you did not receive the email') }},
|
||||
<form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-link p-0 m-0 align-baseline">{{ __('click here to request another') }}</button>.
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
0
resources/views/clients/clients_pdf.blade.php
Normal file
0
resources/views/clients/clients_pdf.blade.php
Normal file
285
resources/views/clients/index.blade.php
Normal file
285
resources/views/clients/index.blade.php
Normal file
@@ -0,0 +1,285 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'Click ERP - Client Management')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.avatar-circle { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: bold; font-size: 0.85rem; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@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>
|
||||
<span class="fw-bold" style="font-size: 0.95rem;">Clients</span>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<!-- Page Header -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">Client Management</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage clients, payment modes, services etc.</p>
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-secondary d-flex align-items-center dropdown-toggle" type="button" data-bs-toggle="dropdown" style="border-radius: 8px;">
|
||||
<i class="bi bi-download me-2"></i> Export
|
||||
</button>
|
||||
<ul class="dropdown-menu shadow-sm border-0">
|
||||
<li>
|
||||
<a class="dropdown-item btn-export d-flex align-items-center" href="#" data-format="csv">
|
||||
<i class="bi bi-filetype-csv me-2 text-success"></i> Export as CSV (Excel)
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item btn-export d-flex align-items-center" href="#" data-format="pdf">
|
||||
<i class="bi bi-filetype-pdf me-2 text-danger"></i> Export as PDF
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenClientModal">
|
||||
<i class="bi bi-plus-lg me-2"></i> Add New Client
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Data Table Card -->
|
||||
<div class="content-card">
|
||||
<!-- Filters -->
|
||||
<div class="p-3 border-bottom bg-light bg-opacity-50">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<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" id="searchClient" placeholder="Search clients, email, or contact...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white" id="filterService">
|
||||
<option value="">All Service Types</option>
|
||||
<option value="sms">SMS</option>
|
||||
<option value="ussd">USSD</option>
|
||||
<option value="airtime">Airtime</option>
|
||||
<option value="voice">Voice</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white" id="filterBilling">
|
||||
<option value="">Payment Mode: All</option>
|
||||
<option value="postpaid">Postpaid (Invoice)</option>
|
||||
<option value="prepaid">Prepaid (Balance)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="table-responsive">
|
||||
<table class="table table-custom table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client Details</th>
|
||||
<th>Primary Contact</th>
|
||||
<th>Services</th>
|
||||
<th>Billing</th>
|
||||
<th>Status</th>
|
||||
<th class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="clientTableBody">
|
||||
<!-- Data will be injected here via AJAX -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Pagination Container -->
|
||||
<div class="p-3 d-flex justify-content-between align-items-center" id="paginationContainer">
|
||||
<span class="text-secondary" style="font-size: 0.85rem;" id="paginationInfo">Showing 0 to 0 of 0 entries</span>
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0" id="paginationLinks">
|
||||
<!-- Pagination links injected here -->
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
<!-- MODAL HTML REMAINS THE SAME AS BEFORE -->
|
||||
@push('modals')
|
||||
@include('clients.partials.create')
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let searchTimer;
|
||||
|
||||
// Initialize the table on page load
|
||||
fetchClients();
|
||||
|
||||
// Event Listeners for Search and Filters
|
||||
$('#searchClient').on('keyup', function() {
|
||||
clearTimeout(searchTimer);
|
||||
// Debounce the search so we don't spam the server on every keystroke
|
||||
searchTimer = setTimeout(() => fetchClients(1), 400);
|
||||
});
|
||||
|
||||
$('#filterService, #filterBilling').on('change', function() {
|
||||
fetchClients(1);
|
||||
});
|
||||
|
||||
// Handle Pagination Clicks dynamically
|
||||
$(document).on('click', '.page-link-ajax', function(e) {
|
||||
e.preventDefault();
|
||||
let page = $(this).data('page');
|
||||
if (page) fetchClients(page);
|
||||
});
|
||||
|
||||
// AJAX Fetch Function
|
||||
function fetchClients(page = 1) {
|
||||
const search = $('#searchClient').val();
|
||||
const service = $('#filterService').val();
|
||||
const billing = $('#filterBilling').val();
|
||||
|
||||
// Show loading state
|
||||
$('#clientTableBody').html(`
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5">
|
||||
<div class="spinner-border text-primary" role="status" style="color: #5c4df0 !important;"></div>
|
||||
<div class="mt-2 text-secondary" style="font-size: 0.85rem;">Loading clients...</div>
|
||||
</td>
|
||||
</tr>
|
||||
`);
|
||||
|
||||
$.ajax({
|
||||
url: base_url + "/clients/data",
|
||||
type: "GET",
|
||||
data: { page: page, search: search, service: service, billing: billing },
|
||||
success: function(response) {
|
||||
renderTable(response.data);
|
||||
renderPagination(response);
|
||||
},
|
||||
error: function() {
|
||||
$('#clientTableBody').html('<tr><td colspan="6" class="text-center text-danger py-4">Failed to load data. Please try again.</td></tr>');
|
||||
}
|
||||
});
|
||||
}
|
||||
// Handle Export Actions
|
||||
$('.btn-export').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Get current filter values
|
||||
const search = $('#searchClient').val();
|
||||
const service = $('#filterService').val();
|
||||
const billing = $('#filterBilling').val();
|
||||
const format = $(this).data('format'); // 'csv' or 'pdf'
|
||||
|
||||
// Build the query string
|
||||
const queryParams = $.param({
|
||||
search: search,
|
||||
service: service,
|
||||
billing: billing,
|
||||
format: format
|
||||
});
|
||||
|
||||
// Redirect the browser to trigger the file download
|
||||
window.location.href = "{{ route('clients.export') }}?" + queryParams;
|
||||
});
|
||||
// Render Table Rows
|
||||
function renderTable(clients) {
|
||||
let html = '';
|
||||
|
||||
if (clients.length === 0) {
|
||||
$('#clientTableBody').html('<tr><td colspan="6" class="text-center text-secondary py-4">No clients found matching your criteria.</td></tr>');
|
||||
return;
|
||||
}
|
||||
|
||||
clients.forEach(client => {
|
||||
// Extract initials for the avatar
|
||||
let initials = client.name.substring(0, 2).toUpperCase();
|
||||
|
||||
let servicesHtml = '<span class="text-secondary" style="font-size: 0.8rem;">N/A</span>';
|
||||
if (client.services) {
|
||||
try {
|
||||
let servicesArray = JSON.parse(client.services);
|
||||
|
||||
// 2. Map each service into a Bootstrap badge
|
||||
if (Array.isArray(servicesArray) && servicesArray.length > 0) {
|
||||
servicesHtml = servicesArray.map(service =>
|
||||
`<span class="badge bg-secondary bg-opacity-10 text-secondary border me-1 mb-1" style="font-size: 0.7rem;">${service}</span>`
|
||||
).join('');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not parse services for client: " + client.name);
|
||||
}
|
||||
}
|
||||
// Status Badge Logic
|
||||
let statusBadge = client.status === 'active'
|
||||
? '<span class="badge bg-success bg-opacity-10 text-success px-2 py-1"><i class="bi bi-check-circle me-1"></i>Active</span>'
|
||||
: '<span class="badge bg-warning bg-opacity-10 text-warning px-2 py-1"><i class="bi bi-clock me-1"></i>' + client.status + '</span>';
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar-circle bg-primary bg-opacity-10 text-primary me-3">${initials}</div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark">${client.name}</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;"><i class="bi bi-geo-alt me-1"></i>${client.country || 'N/A'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-semibold">${client.contact_person || 'N/A'}</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;">${client.email || 'N/A'}</div>
|
||||
</td>
|
||||
<td style="max-width: 200px; white-space: normal;">
|
||||
${servicesHtml}
|
||||
</td>
|
||||
<td><span class="badge bg-info bg-opacity-10 text-info text-uppercase">${client.pay_mode || 'N/A'}</span></td>
|
||||
<td>${statusBadge}</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-client"
|
||||
data-id="${client.id}">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
$('#clientTableBody').html(html);
|
||||
}
|
||||
|
||||
// Render Pagination Links
|
||||
function renderPagination(response) {
|
||||
// Update "Showing X to Y of Z entries"
|
||||
$('#paginationInfo').text(`Showing ${response.from || 0} to ${response.to || 0} of ${response.total} entries`);
|
||||
|
||||
let paginationHtml = '';
|
||||
|
||||
// Only show pagination if there is more than 1 page
|
||||
if (response.last_page > 1) {
|
||||
// Previous Button
|
||||
let prevDisabled = response.current_page === 1 ? 'disabled' : '';
|
||||
paginationHtml += `<li class="page-item ${prevDisabled}"><a class="page-link page-link-ajax" href="#" data-page="${response.current_page - 1}">Previous</a></li>`;
|
||||
|
||||
// Page Numbers
|
||||
for (let i = 1; i <= response.last_page; i++) {
|
||||
let activeClass = response.current_page === i ? 'active' : '';
|
||||
let style = response.current_page === i ? 'style="background-color: #5c4df0; border-color: #5c4df0;"' : 'class="page-link text-dark"';
|
||||
|
||||
paginationHtml += `<li class="page-item ${activeClass}"><a class="page-link page-link-ajax" href="#" ${style} data-page="${i}">${i}</a></li>`;
|
||||
}
|
||||
|
||||
// Next Button
|
||||
let nextDisabled = response.current_page === response.last_page ? 'disabled' : '';
|
||||
paginationHtml += `<li class="page-item ${nextDisabled}"><a class="page-link page-link-ajax" href="#" data-page="${response.current_page + 1}">Next</a></li>`;
|
||||
}
|
||||
|
||||
$('#paginationLinks').html(paginationHtml);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
413
resources/views/clients/index_raw.blade.php
Normal file
413
resources/views/clients/index_raw.blade.php
Normal file
@@ -0,0 +1,413 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Nexus ERP - Client Management</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
<style>
|
||||
body { background-color: #f8f9fc; }
|
||||
|
||||
/* Sidebar Styling */
|
||||
#sidebar { width: 260px; background-color: #111425; position: fixed; height: 100vh; overflow-y: auto; z-index: 1000; }
|
||||
.sidebar-brand { color: #fff; padding: 1.5rem 1.25rem; font-weight: 700; }
|
||||
.sidebar-brand-icon { background: #5c4df0; padding: 0.5rem; border-radius: 8px; margin-right: 10px; }
|
||||
.sidebar-nav-item { color: #8a90a5; text-decoration: none; padding: 0.75rem 1.25rem; display: block; border-radius: 8px; margin: 0.2rem 1rem; font-size: 0.9rem; }
|
||||
.sidebar-nav-item:hover, .sidebar-nav-item.active { background-color: #5c4df0; color: #fff; }
|
||||
.sidebar-heading { color: #5a617a; font-size: 0.75rem; text-transform: uppercase; padding: 1rem 1.25rem 0.5rem; font-weight: 600; }
|
||||
|
||||
/* Main Layout */
|
||||
#main-content { margin-left: 260px; min-height: 100vh; }
|
||||
.topbar { background: #fff; height: 70px; border-bottom: 1px solid #eaedf1; padding: 0 1.5rem; }
|
||||
|
||||
/* Component Styling */
|
||||
.content-card { background: #fff; border: 1px solid #eaedf1; border-radius: 12px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); }
|
||||
.stat-card { border-left: 4px solid transparent; }
|
||||
.stat-card.primary { border-left-color: #5c4df0; }
|
||||
.stat-card.success { border-left-color: #10b981; }
|
||||
.stat-card.warning { border-left-color: #f59e0b; }
|
||||
|
||||
/* Table Styling */
|
||||
.table-custom th { background-color: #f8f9fc; color: #5a617a; font-weight: 600; font-size: 0.8rem; text-transform: uppercase; border-bottom: 2px solid #eaedf1; padding: 1rem; }
|
||||
.table-custom td { padding: 1rem; vertical-align: middle; font-size: 0.9rem; border-bottom: 1px solid #eaedf1; }
|
||||
.avatar-circle { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: bold; font-size: 0.85rem; }
|
||||
|
||||
/* Modal Customization */
|
||||
.modal-content { border-radius: 12px; border: none; box-shadow: 0 10px 30px rgba(0,0,0,0.1); }
|
||||
.modal-header { border-bottom: 1px solid #eaedf1; background-color: #f8f9fc; border-radius: 12px 12px 0 0; }
|
||||
.modal-footer { border-top: 1px solid #eaedf1; }
|
||||
.form-control:focus, .form-select:focus { border-color: #5c4df0; box-shadow: 0 0 0 0.25rem rgba(92, 77, 240, 0.25); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<aside id="sidebar">
|
||||
<div class="sidebar-brand d-flex align-items-center">
|
||||
<span class="sidebar-brand-icon"><i class="bi bi-buildings"></i></span>
|
||||
<div>
|
||||
<div class="mb-0 fs-6">NEXUS <span class="badge bg-secondary ms-1" style="font-size: 0.6rem;">ERP</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-3 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-dark border-secondary text-secondary"><i class="bi bi-search"></i></span>
|
||||
<input type="text" class="form-control bg-dark border-secondary text-light placeholder-secondary" placeholder="Quick search...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-heading mt-2">Core Entities</div>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-person-badge me-2"></i> Staff Directory</a>
|
||||
<a href="#" class="sidebar-nav-item active"><i class="bi bi-people me-2"></i> Clients</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-broadcast-pin me-2"></i> MNO Partners</a>
|
||||
<div class="sidebar-heading mt-2">Resources</div>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-folder2-open me-2"></i> Document Vault</a>
|
||||
</aside>
|
||||
|
||||
<main id="main-content">
|
||||
<header class="topbar d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<a href="#" class="text-secondary text-decoration-none hover-primary"><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="#" class="text-secondary text-decoration-none me-2" style="font-size: 0.95rem;">Entities</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;">Clients</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="text-secondary me-4" style="font-size: 0.9rem;">
|
||||
<i class="bi bi-clock me-1"></i> <span id="current-time">--:--:--</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="rounded-circle bg-light d-flex justify-content-center align-items-center me-2 border text-dark fw-bold" style="width: 32px; height: 32px; font-size: 0.8rem;">AU</div>
|
||||
<span class="fw-bold" style="font-size: 0.9rem;">Admin User</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container-fluid p-4">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">Client Management</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage corporate accounts, billing types, and service provisions.</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-outline-secondary d-flex align-items-center" style="border-radius: 8px;">
|
||||
<i class="bi bi-download me-2"></i> Export
|
||||
</button>
|
||||
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenClientModal">
|
||||
<i class="bi bi-plus-lg me-2"></i> Add New Client
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="content-card stat-card primary p-3 h-100 border-0">
|
||||
<div class="text-secondary fw-bold mb-2" style="font-size: 0.75rem; letter-spacing: 0.5px;">TOTAL CLIENTS</div>
|
||||
<h3 class="fw-bold mb-0">24</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="content-card stat-card success p-3 h-100 border-0">
|
||||
<div class="text-secondary fw-bold mb-2" style="font-size: 0.75rem; letter-spacing: 0.5px;">ACTIVE SIP TRUNKS</div>
|
||||
<h3 class="fw-bold mb-0">18</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="content-card stat-card warning p-3 h-100 border-0">
|
||||
<div class="text-secondary fw-bold mb-2" style="font-size: 0.75rem; letter-spacing: 0.5px;">PREPAID ACCOUNTS</div>
|
||||
<h3 class="fw-bold mb-0">12</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="p-3 border-bottom bg-light bg-opacity-50 rounded-top" style="border-top-left-radius: 12px; border-top-right-radius: 12px;">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<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 clients, email, or contact...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">All Service Types</option>
|
||||
<option value="voip">PBX / SIP Trunking</option>
|
||||
<option value="gis">GIS Mapping Services</option>
|
||||
<option value="web">Web Infrastructure</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">Billing: All</option>
|
||||
<option value="prepaid">Prepaid</option>
|
||||
<option value="postpaid">Postpaid</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-custom table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client Details</th>
|
||||
<th>Primary Contact</th>
|
||||
<th>Services</th>
|
||||
<th>Billing</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-primary bg-opacity-10 text-primary me-3">CT</div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark">Click Tech Team</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;"><i class="bi bi-geo-alt me-1"></i>Accra, GH</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-semibold">Admin Desk</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;">hello@clicktechteam.com</div>
|
||||
</td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary border">Web Infrastructure</span></td>
|
||||
<td><span class="badge bg-info bg-opacity-10 text-info">Postpaid</span></td>
|
||||
<td><span class="badge bg-success bg-opacity-10 text-success px-2 py-1"><i class="bi bi-check-circle me-1"></i>Active</span></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-secondary me-1"><i class="bi bi-eye"></i></button>
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-client"
|
||||
data-id="1" data-name="Click Tech Team" data-email="hello@clicktechteam.com" data-contact="Admin Desk" data-phone="+233 20 000 0000" data-location="Accra, GH" data-service="web" data-billing="postpaid" data-status="active">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar-circle bg-success bg-opacity-10 text-success me-3">AT</div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark">Alpha Telecom Services</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;"><i class="bi bi-geo-alt me-1"></i>Kumasi, GH</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-semibold">Michael Osei</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;">m.osei@alphatel.com.gh</div>
|
||||
</td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary border">SIP Trunking / PBX</span></td>
|
||||
<td><span class="badge bg-warning bg-opacity-10 text-warning text-dark">Prepaid</span></td>
|
||||
<td><span class="badge bg-success bg-opacity-10 text-success px-2 py-1"><i class="bi bi-check-circle me-1"></i>Active</span></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-secondary me-1"><i class="bi bi-eye"></i></button>
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-client"
|
||||
data-id="2" data-name="Alpha Telecom Services" data-email="m.osei@alphatel.com.gh" data-contact="Michael Osei" data-phone="+233 24 000 0000" data-location="Kumasi, GH" data-service="pbx" data-billing="prepaid" data-status="active">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar-circle bg-warning bg-opacity-10 text-warning me-3">LS</div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark">LiveScores Media ZM</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;"><i class="bi bi-geo-alt me-1"></i>Lusaka, ZM</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-semibold">David Phiri</div>
|
||||
<div class="text-secondary" style="font-size: 0.8rem;">david@livescores.co.zm</div>
|
||||
</td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary border">USSD App / API</span></td>
|
||||
<td><span class="badge bg-info bg-opacity-10 text-info">Postpaid</span></td>
|
||||
<td><span class="badge bg-warning bg-opacity-10 text-warning px-2 py-1"><i class="bi bi-clock me-1"></i>Onboarding</span></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-secondary me-1"><i class="bi bi-eye"></i></button>
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-client"
|
||||
data-id="3" data-name="LiveScores Media ZM" data-email="david@livescores.co.zm" data-contact="David Phiri" data-phone="+260 97 000 0000" data-location="Lusaka, ZM" data-service="api" data-billing="postpaid" data-status="onboarding">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="p-3 d-flex justify-content-between align-items-center">
|
||||
<span class="text-secondary" style="font-size: 0.85rem;">Showing 1 to 3 of 24 entries</span>
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
|
||||
<li class="page-item active"><a class="page-link" href="#" style="background-color: #5c4df0; border-color: #5c4df0;">1</a></li>
|
||||
<li class="page-item"><a class="page-link text-dark" href="#">2</a></li>
|
||||
<li class="page-item"><a class="page-link text-dark" href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="modal fade" id="clientModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold" id="clientModalTitle">Add New Client</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<form id="clientForm">
|
||||
<div class="modal-body p-4">
|
||||
<input type="hidden" id="clientId" name="id">
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Company Details</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;">Company Name *</label>
|
||||
<input type="text" class="form-control" id="clientName" name="name" required placeholder="e.g. Acme Corp">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Location / Region</label>
|
||||
<input type="text" class="form-control" id="clientLocation" name="location" placeholder="e.g. Accra, GH">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Primary Contact</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;">Full Name</label>
|
||||
<input type="text" class="form-control" id="clientContact" name="contact_name" placeholder="Contact person">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Email Address *</label>
|
||||
<input type="email" class="form-control" id="clientEmail" name="email" required placeholder="name@company.com">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Phone Number</label>
|
||||
<input type="text" class="form-control" id="clientPhone" name="phone" placeholder="+233 ...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Service & Billing Configuration</h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Primary Service</label>
|
||||
<select class="form-select" id="clientService" name="service_type">
|
||||
<option value="pbx">SIP Trunking / PBX</option>
|
||||
<option value="api">USSD App / API</option>
|
||||
<option value="gis">GIS Data / Mapping</option>
|
||||
<option value="web">Web Infrastructure</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Billing Type</label>
|
||||
<select class="form-select" id="clientBilling" name="billing_type">
|
||||
<option value="postpaid">Postpaid (Invoice)</option>
|
||||
<option value="prepaid">Prepaid (Balance)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Account Status</label>
|
||||
<select class="form-select" id="clientStatus" name="status">
|
||||
<option value="active">Active</option>
|
||||
<option value="onboarding">Onboarding</option>
|
||||
<option value="suspended">Suspended</option>
|
||||
</select>
|
||||
</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="btnSubmitClient">
|
||||
Save Client
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Reusable Clock Update
|
||||
function updateClock() {
|
||||
const now = new Date();
|
||||
$('#current-time').text(now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true }));
|
||||
}
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
|
||||
const clientModal = new bootstrap.Modal(document.getElementById('clientModal'));
|
||||
const $form = $('#clientForm');
|
||||
|
||||
// --- OPEN MODAL FOR CREATE ---
|
||||
$('#btnOpenClientModal').on('click', function() {
|
||||
$form[0].reset();
|
||||
$('#clientId').val('');
|
||||
$('#clientModalTitle').text('Add New Client');
|
||||
$('#btnSubmitClient').html('<i class="bi bi-save me-2"></i>Save Client');
|
||||
clientModal.show();
|
||||
});
|
||||
|
||||
// --- OPEN MODAL FOR EDIT ---
|
||||
$('.btn-edit-client').on('click', function() {
|
||||
// Fetch data attributes from the clicked button
|
||||
const data = $(this).data();
|
||||
|
||||
// Populate the form
|
||||
$('#clientId').val(data.id);
|
||||
$('#clientName').val(data.name);
|
||||
$('#clientLocation').val(data.location);
|
||||
$('#clientContact').val(data.contact);
|
||||
$('#clientEmail').val(data.email);
|
||||
$('#clientPhone').val(data.phone);
|
||||
$('#clientService').val(data.service);
|
||||
$('#clientBilling').val(data.billing);
|
||||
$('#clientStatus').val(data.status);
|
||||
|
||||
// Update UI text
|
||||
$('#clientModalTitle').text('Edit Client: ' + data.name);
|
||||
$('#btnSubmitClient').html('<i class="bi bi-check-circle me-2"></i>Update Client');
|
||||
|
||||
clientModal.show();
|
||||
});
|
||||
|
||||
// --- HANDLE FORM SUBMISSION ---
|
||||
$form.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const $btn = $('#btnSubmitClient');
|
||||
const originalText = $btn.html();
|
||||
const isEdit = $('#clientId').val() !== '';
|
||||
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2"></span> Processing...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
// Simulate AJAX Request to Laravel Backend
|
||||
setTimeout(() => {
|
||||
const formData = $(this).serializeArray();
|
||||
console.log('Submitted Client Data:', formData);
|
||||
|
||||
$btn.html(originalText);
|
||||
$btn.prop('disabled', false);
|
||||
clientModal.hide();
|
||||
|
||||
alert(isEdit ? 'Client updated successfully!' : 'New client created successfully!');
|
||||
// Normally you would reload the datatable here or append the new row
|
||||
}, 800);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
108
resources/views/clients/partials/create.blade.php
Normal file
108
resources/views/clients/partials/create.blade.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<div class="modal fade" id="clientModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold" id="clientModalTitle">Add New Client</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<form id="clientForm">
|
||||
<div class="modal-body p-4">
|
||||
<input type="hidden" id="clientId" name="id">
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Company Details</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;">Company Name *</label>
|
||||
<input type="text" class="form-control" id="clientName" name="name" required placeholder="e.g. Kasapreko Distilleries">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Location / Country</label>
|
||||
<input type="text" class="form-control" id="country" name="location" placeholder="">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Company Type</label>
|
||||
<select class="form-select" id="companyType" name="company_type">
|
||||
<option value="" selected disabled>--Select--</option>
|
||||
<option value="aggregator">Aggregator/Supplier</option>
|
||||
<option value="enterprise">Enterprice</option>
|
||||
<option value="hybrid">Hybrid</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Industry Type</label>
|
||||
<select class="form-select" id="industryType" name="industry_type">
|
||||
<option value="" selected disabled>--Select--</option>
|
||||
<option value="aggregator">Aggregator SMS/USSD/Voice</option>
|
||||
<option value="delivery">Delivery Service</option>
|
||||
<option value="education">Education </option>
|
||||
<option value="financial">Financial Institution</option>
|
||||
<option value="games">Games & Gambling</option>
|
||||
<option value="general">General</option>
|
||||
<option value="government">Government</option>
|
||||
<option value="health">Health</option>
|
||||
<option value="hospitality">Hospitality</option>
|
||||
<option value="mobile_network_operator">Mobile Network Operator</option>
|
||||
<option value="ngo">NGO</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Primary Contact</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;">Full Name</label>
|
||||
<input type="text" class="form-control" id="clientContact" name="contact_name" placeholder="Contact person">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Email Address *</label>
|
||||
<input type="email" class="form-control" id="clientEmail" name="email" required placeholder="name@company.com">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Phone Number</label>
|
||||
<input type="text" class="form-control" id="clientPhone" name="phone" placeholder="+233 ...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Service & Billing Configuration</h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Primary Service</label>
|
||||
<select class="form-select" id="clientService" name="service_type">
|
||||
<option value="" selected disabled>--Select--</option>
|
||||
<option value="sms">SMS</option>
|
||||
<option value="ussd">USSD</option>
|
||||
<option value="airtime">Airtime</option>
|
||||
<option value="voice">Voice</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Billing Type</label>
|
||||
<select class="form-select" id="clientBilling" name="billing_type">
|
||||
<option value="" selected disabled>--Select--</option>
|
||||
<option value="postpaid">Postpaid (Invoice)</option>
|
||||
<option value="prepaid">Prepaid (Balance)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Account Status</label>
|
||||
<select class="form-select" id="clientStatus" name="status">
|
||||
<option value="" selected disabled>--Select--</option>
|
||||
<option value="active">Active</option>
|
||||
<option value="onboarding">Prospective</option>
|
||||
<option value="suspended">In Discussion</option>
|
||||
</select>
|
||||
</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="btnSubmitClient">
|
||||
Save Client
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
46
resources/views/comments/create.blade.php
Normal file
46
resources/views/comments/create.blade.php
Normal file
@@ -0,0 +1,46 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mt-5">
|
||||
<h2>{{ isset($comment) ? 'Edit comment' : 'Manager Comment Section' }}</h2>
|
||||
@include('commons.notifications')
|
||||
<form action="{{ isset($comment) ? route('comments.update', $comment->id) : route('comments.store') }}" method="POST">
|
||||
<input type="hidden" name="user_id" value="{{ \Auth::user()->id }}">
|
||||
@csrf
|
||||
@if (isset($comment_body))
|
||||
@method('PUT')
|
||||
@endif
|
||||
<div class="card w-100">
|
||||
<div class="card-body">
|
||||
<h3>Project Details</h3>
|
||||
<h5 class="card-title">{{ $project_arr->project->name }}</h5>
|
||||
<p class="card-text">{{ $project_arr->project->description }} </p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<h3>Latest Update</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Status Description</th>
|
||||
<th scope="col">Current Status</th>
|
||||
<th scope="col">Date Updated</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ $project_arr->description }}</td>
|
||||
<td>{{ $project_arr->status }}</td>
|
||||
<td>{{ $project_arr->created_at }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="mb-3">
|
||||
<label for="commnetBody" class="form-label">Comment Body</label>
|
||||
<textarea class="form-control" id="commnetBody" name="comment_body" rows="4" required>{{ $comment->body ?? '' }}</textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Create comment</button>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
51
resources/views/comments/index.blade.php
Normal file
51
resources/views/comments/index.blade.php
Normal file
@@ -0,0 +1,51 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-10">
|
||||
@include('commons.notifications')
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Projects') }}</div>
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
<div class="float-end">
|
||||
<a href="/projects/create" class="btn btn-primary btn-sm">Add Projects</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Description</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Date Created</th>
|
||||
<th scope="col">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $count = 1; ?>
|
||||
@foreach($projects as $row)
|
||||
<tr>
|
||||
<th scope="row">{{ $count }}</th>
|
||||
<td>{{ $row->name }}</td>
|
||||
<td>{{ $row->description }}</td>
|
||||
<td>{{ $row->status }}</td>
|
||||
<td>{{ $row->created_at }}</td>
|
||||
<td><a href="{{ url('project-status/add_status', $row->id)}}" class="btn btn-link">Add Status</a></td>
|
||||
</tr>
|
||||
<?php $count++; ?>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
18
resources/views/commons/notifications.blade.php
Normal file
18
resources/views/commons/notifications.blade.php
Normal file
@@ -0,0 +1,18 @@
|
||||
@if ($errors->any())
|
||||
<ul class="alert alert-danger" style="padding-left:10px; list-style-type: none;">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{!! $error !!}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
<!-- color: #fff; -->
|
||||
@if(Session::has('success_message'))
|
||||
<div style="text-align: center" class="alert alert-success notification-alert" style="">
|
||||
{{ Session::get('success_message') }}
|
||||
</div>
|
||||
@elseif(Session::has('error_message'))
|
||||
<div style="text-align: center" class="alert alert-danger notification-alert" style="">
|
||||
{{ Session::get('error_message') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
157
resources/views/dashboard/index.blade.php
Normal file
157
resources/views/dashboard/index.blade.php
Normal file
@@ -0,0 +1,157 @@
|
||||
@extends('layouts.master')
|
||||
|
||||
@section('title', 'Dashboard')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="hero-banner p-4 mb-4">
|
||||
<h3>Dashboard</h3>
|
||||
</div>
|
||||
|
||||
<!-- <div class="row"> -->
|
||||
<!-- <div class="hero-banner p-4 mb-4 d-flex justify-content-between align-items-center">
|
||||
<div class="w-50">
|
||||
<h3 class="fw-bold mb-3">Base ERP Workstation <span class="badge bg-primary fs-6 align-middle ms-2" style="background-color: #5c4df0 !important;">ACTIVE</span></h3>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.95rem; line-height: 1.6;">
|
||||
Welcome to Nexus-ERP base mockup. This screen loads aggregated statistics computed React state modifications (Customer Directory alterations, invoices creations, etc.) instantly.
|
||||
</p>
|
||||
</div>
|
||||
<div class="d-flex gap-3">
|
||||
<button class="btn text-white fw-bold d-flex align-items-center px-4" style="background-color: #5c4df0; border-radius: 8px;" id="seedBtn">
|
||||
<i class="bi bi-stars me-2"></i> Seed Demo Records
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary text-white fw-bold d-flex align-items-center px-4" style="border-radius: 8px; border-color: #5a617a;">
|
||||
<i class="bi bi-plus-square me-2"></i> New Record Form
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">SMS Clients</div>
|
||||
<div class="stat-icon bg-success bg-opacity-10 text-success"><i class="bi bi-chat-dots"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">150</h2>
|
||||
<div class="d-flex align-items-center mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-success fw-bold"><i class="bi bi-arrow-up-right me-1"></i>+1.4%</span>
|
||||
<span class="text-secondary ms-2">quarter over quarter</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">USSD Clients</div>
|
||||
<div class="stat-icon bg-primary bg-opacity-10 text-primary" style="color: #5c4df0 !important;"><i class="bi bi-phone"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">50</h2>
|
||||
<div class="d-flex align-items-center justify-content-between mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-primary fw-bold" style="color: #5c4df0 !important;">4 new clients</span>
|
||||
<span class="text-secondary">recent engagement result</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">Voice Clients</div>
|
||||
<div class="stat-icon bg-warning bg-opacity-10 text-warning"><i class="bi bi-megaphone"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">10</h2>
|
||||
<div class="d-flex align-items-center mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-warning fw-bold">Darwin System</span>
|
||||
<span class="text-secondary ms-3 lh-sm" style="font-size: 0.7rem;">Newly Acquired <br>client</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">Airtime Clients</div>
|
||||
<div class="stat-icon bg-danger bg-opacity-10 text-danger"><i class="bi bi-telephone-plus"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">15</h2>
|
||||
<div class="d-flex align-items-center mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-success fw-bold"><i class="bi bi-circle-fill me-1" style="font-size: 0.5rem;"></i>Healthy</span>
|
||||
<span class="text-secondary ms-3">Average bill secons: 3.5 mins</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-8">
|
||||
<div class="card stat-card border-0 p-4 h-100">
|
||||
<div class="d-flex justify-content-between align-items-start mb-4">
|
||||
<div>
|
||||
<h6 class="fw-bold mb-1">Revenue Projections Trend</h6>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.85rem;">Demonstrating visual charts using pure responsive vector layouts</p>
|
||||
</div>
|
||||
<div class="d-flex gap-3" style="font-size: 0.85rem;">
|
||||
<span class="d-flex align-items-center"><i class="bi bi-circle-fill text-primary me-2" style="font-size: 0.5rem;"></i> Sales Target</span>
|
||||
<span class="d-flex align-items-center text-secondary"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #d1d5db;"></i> Prior Year</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-100 mt-auto position-relative" style="height: 200px;">
|
||||
<svg viewBox="0 0 800 200" class="w-100 h-100" preserveAspectRatio="none">
|
||||
<path d="M0,180 Q200,220 400,100 T800,20" fill="none" stroke="#e0e0e0" stroke-width="2" stroke-dasharray="5,5"/>
|
||||
<path d="M0,200 Q200,220 400,160 T800,0" fill="none" stroke="#5c4df0" stroke-width="4"/>
|
||||
<circle cx="400" cy="160" r="6" fill="#5c4df0" stroke="white" stroke-width="2"/>
|
||||
<circle cx="600" cy="50" r="6" fill="#5c4df0" stroke="white" stroke-width="2"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="card stat-card border-0 p-4 h-100">
|
||||
<h6 class="fw-bold mb-1">Department Distribution</h6>
|
||||
<p class="text-secondary mb-4" style="font-size: 0.85rem;">Ratio of active records grouped by segment</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #5c4df0;"></i> Finance</span>
|
||||
<span class="text-secondary">1 (25%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 25%; background-color: #5c4df0;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #10b981;"></i> Operations</span>
|
||||
<span class="text-secondary">1 (25%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 25%; background-color: #10b981;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #f59e0b;"></i> Sales</span>
|
||||
<span class="text-secondary">1 (25%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 25%; background-color: #f59e0b;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #ef4444;"></i> Marketing</span>
|
||||
<span class="text-secondary">0 (0%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 0%; background-color: #ef4444;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@endsection
|
||||
306
resources/views/dashboard/index_two.blade.php
Normal file
306
resources/views/dashboard/index_two.blade.php
Normal file
@@ -0,0 +1,306 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'Click ERP - Dashboard')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
/* Typography overrides for Dashboard headers */
|
||||
.card-heading { font-size: 0.95rem; font-weight: 600; color: #4a90e2; padding: 1rem 1.25rem; border-bottom: 1px solid #eaedf1; }
|
||||
.kpi-title { color: #4a90e2; font-size: 1.1rem; font-weight: 600; }
|
||||
.kpi-value { font-size: 2.2rem; font-weight: 700; color: #4b5563; line-height: 1; }
|
||||
.kpi-icon { font-size: 3rem; color: #d1d5db; }
|
||||
|
||||
/* Quotes Section */
|
||||
.quote-block { border-left: 3px solid #e5e7eb; padding-left: 1rem; margin-bottom: 1rem; color: #4b5563; font-size: 0.95rem; }
|
||||
.quote-author { font-size: 0.8rem; color: #6b7280; }
|
||||
|
||||
/* Badges */
|
||||
.badge-rounded { border-radius: 12px; padding: 0.25rem 0.6rem; font-size: 0.75rem; font-weight: bold; }
|
||||
.bg-red-custom { background-color: #ef4444; color: white; }
|
||||
.bg-orange-custom { background-color: #f59e0b; color: white; }
|
||||
.bg-teal-custom { background-color: #14b8a6; color: white; }
|
||||
|
||||
/* Timeline / Recent Activities */
|
||||
.activity-timeline { position: relative; padding-left: 1.5rem; list-style: none; margin: 0; }
|
||||
.activity-timeline::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: #e5e7eb; }
|
||||
.timeline-item { position: relative; margin-bottom: 1.5rem; }
|
||||
.timeline-item:last-child { margin-bottom: 0; }
|
||||
.timeline-item::before { content: ''; position: absolute; left: -1.8rem; top: 0.2rem; width: 10px; height: 10px; border-radius: 50%; background: #fff; border: 2px solid #cbd5e1; }
|
||||
.timeline-text { font-size: 0.85rem; color: #4b5563; margin-bottom: 0.25rem; }
|
||||
.timeline-time { font-size: 0.75rem; color: #9ca3af; font-style: italic; }
|
||||
|
||||
/* Client Date Badge */
|
||||
.date-badge { background-color: #d97706; color: white; border-radius: 6px; text-align: center; width: 45px; padding: 0.3rem 0; flex-shrink: 0; }
|
||||
.date-badge .month { font-size: 0.7rem; text-transform: uppercase; line-height: 1; }
|
||||
.date-badge .day { font-size: 1.1rem; font-weight: bold; line-height: 1.1; margin: 0.1rem 0; }
|
||||
.date-badge .year { font-size: 0.7rem; line-height: 1; }
|
||||
|
||||
/* Empty States */
|
||||
.empty-state { min-height: 200px; display: flex; align-items: center; justify-content: center; color: #9ca3af; font-size: 0.9rem; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('breadcrumbs')
|
||||
<i class="bi bi-list text-secondary me-3" style="font-size: 1.5rem; cursor: pointer;"></i>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<!-- KPI Row -->
|
||||
<div class="row g-3 mb-4">
|
||||
<!-- SMS Clients -->
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-4 d-flex justify-content-between align-items-center h-100">
|
||||
<div>
|
||||
<div class="kpi-value mb-1">150</div>
|
||||
<div class="kpi-title">SMS Clients</div>
|
||||
</div>
|
||||
<i class="bi bi-chat-dots kpi-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- USSD Clients -->
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-4 d-flex justify-content-between align-items-center h-100">
|
||||
<div>
|
||||
<div class="kpi-value mb-1">230</div>
|
||||
<div class="kpi-title">USSD Client</div>
|
||||
</div>
|
||||
<i class="bi bi-phone kpi-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Voice Clients -->
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-4 d-flex justify-content-between align-items-center h-100">
|
||||
<div>
|
||||
<div class="kpi-value mb-1">5</div>
|
||||
<div class="kpi-title">Voice Clients</div>
|
||||
</div>
|
||||
<i class="bi bi-megaphone kpi-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Airtime Clients -->
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-4 d-flex justify-content-between align-items-center h-100">
|
||||
<div>
|
||||
<div class="kpi-value mb-1">6</div>
|
||||
<div class="kpi-title">Airtime Clients</div>
|
||||
</div>
|
||||
<i class="bi bi-patch-check kpi-icon" style="transform: rotate(45deg);"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quotes & Contracts Row -->
|
||||
<div class="row g-4 mb-4">
|
||||
|
||||
<!-- Quotes Section -->
|
||||
<div class="col-lg-6">
|
||||
<div class="content-card h-100">
|
||||
<div class="card-heading">Quotes</div>
|
||||
<div class="p-4 row g-0">
|
||||
<div class="col-sm-6 border-end pe-sm-4 mb-4 mb-sm-0 d-flex flex-column">
|
||||
<div class="quote-block">Change in all things is sweet.</div>
|
||||
<div class="quote-author mt-2">Aristotle</div>
|
||||
<div class="mt-auto pt-4 text-danger fw-bold" style="font-size: 0.85rem;">Quote of the Day</div>
|
||||
</div>
|
||||
<div class="col-sm-6 ps-sm-4 d-flex flex-column">
|
||||
<div class="quote-block">Genius is one percent inspiration and ninety-nine percent perspiration.</div>
|
||||
<div class="quote-author mt-2">Thomas Edison</div>
|
||||
<div class="mt-auto pt-4 text-primary fw-bold" style="font-size: 0.85rem; color: #4a90e2 !important;">Message of the Day</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contract Expiry Notice -->
|
||||
<div class="col-lg-6">
|
||||
<div class="content-card h-100">
|
||||
<div class="card-heading">Contract Expiry Notice</div>
|
||||
<div class="p-4">
|
||||
<!-- MNO Contracts -->
|
||||
<div class="text-center mb-4">
|
||||
<a href="#" class="text-decoration-underline fw-semibold d-block mb-3" style="color: #4a90e2;">MNO Contracts</a>
|
||||
<div class="row text-center">
|
||||
<div class="col-4">
|
||||
<div class="text-danger fw-bold mb-1" style="font-size: 0.8rem;">Expired</div>
|
||||
<span class="badge-rounded bg-red-custom">9</span>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="text-warning fw-bold mb-1" style="font-size: 0.8rem; color: #d97706 !important;">Expiring This Month</div>
|
||||
<span class="badge-rounded bg-orange-custom">0</span>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="text-success fw-bold mb-1" style="font-size: 0.8rem; color: #0d9488 !important;">Expiring in 3 months</div>
|
||||
<span class="badge-rounded bg-teal-custom">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="text-secondary opacity-25 my-4">
|
||||
|
||||
<!-- Client Contracts -->
|
||||
<div class="text-center">
|
||||
<a href="#" class="text-decoration-underline fw-semibold d-block mb-3" style="color: #4a90e2;">Client Contracts</a>
|
||||
<div class="row text-center">
|
||||
<div class="col-4">
|
||||
<div class="text-danger fw-bold mb-1" style="font-size: 0.8rem;">Expired</div>
|
||||
<span class="badge-rounded bg-red-custom">313</span>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="text-warning fw-bold mb-1" style="font-size: 0.8rem; color: #d97706 !important;">Expiring This Month</div>
|
||||
<span class="badge-rounded bg-orange-custom">12</span>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="text-success fw-bold mb-1" style="font-size: 0.8rem; color: #0d9488 !important;">Expiring in 3 months</div>
|
||||
<span class="badge-rounded bg-teal-custom">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom Lists Row -->
|
||||
<div class="row g-4">
|
||||
|
||||
<!-- Recent Activities -->
|
||||
<div class="col-xl-3 col-lg-6">
|
||||
<div class="content-card h-100 d-flex flex-column">
|
||||
<div class="card-heading">Recent Activities</div>
|
||||
<div class="p-4 flex-grow-1">
|
||||
<ul class="activity-timeline">
|
||||
<li class="timeline-item">
|
||||
<div class="timeline-text">User ID : 15 (Mphatso Katundu) Added a new Note for : CLOUD COM</div>
|
||||
<div class="timeline-time">7 months ago</div>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<div class="timeline-text">User ID : 16 (Diana Towett) Added a new Note for : PCCW</div>
|
||||
<div class="timeline-time">7 months ago</div>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<div class="timeline-text">User ID : 16 (Diana Towett) Added a new Note for : Panacea</div>
|
||||
<div class="timeline-time">7 months ago</div>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<div class="timeline-text">User ID : 16 (Diana Towett) Added a new Note for : Termii</div>
|
||||
<div class="timeline-time">7 months ago</div>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<div class="timeline-text">Diana Towett Successfully Logged In</div>
|
||||
<div class="timeline-time">7 months ago</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="p-3 border-top">
|
||||
<a href="#" class="text-decoration-none" style="font-size: 0.85rem; color: #4a90e2;">View More</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Upcoming Holidays -->
|
||||
<div class="col-xl-3 col-lg-6">
|
||||
<div class="content-card h-100">
|
||||
<div class="card-heading">Upcoming Holidays</div>
|
||||
<div class="empty-state">
|
||||
No upcoming holidays
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Upcoming Birthdays -->
|
||||
<div class="col-xl-3 col-lg-6">
|
||||
<div class="content-card h-100">
|
||||
<div class="card-heading">Upcoming Birthdays</div>
|
||||
<div class="empty-state">
|
||||
No upcoming birthdays
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Newly Added Clients -->
|
||||
<div class="col-xl-3 col-lg-6">
|
||||
<div class="content-card h-100">
|
||||
<div class="card-heading">Newly Added Clients</div>
|
||||
<div class="p-3">
|
||||
|
||||
<div class="d-flex align-items-start mb-3 border-bottom pb-3">
|
||||
<div class="date-badge me-3">
|
||||
<div class="month">Nov</div>
|
||||
<div class="day">10</div>
|
||||
<div class="year">2025</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold" style="font-size: 0.8rem; color: #374151;">Solidaridad Network</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.7rem; line-height: 1.4;">
|
||||
Company Type : ENTERPRISE<br>
|
||||
Account Manager : KWESI BANSON
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-start mb-3 border-bottom pb-3">
|
||||
<div class="date-badge me-3">
|
||||
<div class="month">Nov</div>
|
||||
<div class="day">10</div>
|
||||
<div class="year">2025</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold" style="font-size: 0.8rem; color: #374151;">Avada Pay</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.7rem; line-height: 1.4;">
|
||||
Company Type : AGGREGATOR/SUPPLIER<br>
|
||||
Account Manager : MELISSA SHUMA
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-start mb-3 border-bottom pb-3">
|
||||
<div class="date-badge me-3">
|
||||
<div class="month">Nov</div>
|
||||
<div class="day">10</div>
|
||||
<div class="year">2025</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold" style="font-size: 0.8rem; color: #374151;">Pezesha Limited</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.7rem; line-height: 1.4;">
|
||||
Company Type : ENTERPRISE<br>
|
||||
Account Manager : MELISSA SHUMA
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-start mb-3 border-bottom pb-3">
|
||||
<div class="date-badge me-3">
|
||||
<div class="month">Nov</div>
|
||||
<div class="day">10</div>
|
||||
<div class="year">2025</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold" style="font-size: 0.8rem; color: #374151;">NUETECH STACK LLC</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.7rem; line-height: 1.4;">
|
||||
Company Type : AGGREGATOR/SUPPLIER<br>
|
||||
Account Manager : MELISSA SHUMA
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-start">
|
||||
<div class="date-badge me-3">
|
||||
<div class="month">Oct</div>
|
||||
<div class="day">29</div>
|
||||
<div class="year">2025</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold" style="font-size: 0.8rem; color: #374151; line-height: 1.2;">THABA-ENHLE ZIM (PRIVATE) LIMITED-ChapChapBet</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.7rem; line-height: 1.4;">
|
||||
Company Type : ENTERPRISE<br>
|
||||
Account Manager : CHARITY MTEMBEZEKA
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
283
resources/views/documents/index.blade.php
Normal file
283
resources/views/documents/index.blade.php
Normal file
@@ -0,0 +1,283 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>CML ERP</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
<style>
|
||||
body { background-color: #f8f9fc; }
|
||||
|
||||
/* Sidebar & Topbar (Inherited from Base Design) */
|
||||
#sidebar { width: 260px; background-color: #111425; position: fixed; height: 100vh; overflow-y: auto; z-index: 1000; }
|
||||
.sidebar-brand { color: #fff; padding: 1.5rem 1.25rem; font-weight: 700; }
|
||||
.sidebar-brand-icon { background: #5c4df0; padding: 0.5rem; border-radius: 8px; margin-right: 10px; }
|
||||
.sidebar-nav-item { color: #8a90a5; text-decoration: none; padding: 0.75rem 1.25rem; display: block; border-radius: 8px; margin: 0.2rem 1rem; font-size: 0.9rem; }
|
||||
.sidebar-nav-item:hover, .sidebar-nav-item.active { background-color: #5c4df0; color: #fff; }
|
||||
.sidebar-heading { color: #5a617a; font-size: 0.75rem; text-transform: uppercase; padding: 1rem 1.25rem 0.5rem; font-weight: 600; }
|
||||
|
||||
#main-content { margin-left: 260px; min-height: 100vh; }
|
||||
.topbar { background: #fff; height: 70px; border-bottom: 1px solid #eaedf1; padding: 0 1.5rem; }
|
||||
|
||||
/* Cards & Tables */
|
||||
.content-card { background: #fff; border: 1px solid #eaedf1; border-radius: 12px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); }
|
||||
.table-custom th { background-color: #f8f9fc; color: #5a617a; font-weight: 600; font-size: 0.8rem; text-transform: uppercase; border-bottom: 2px solid #eaedf1; padding: 1rem; }
|
||||
.table-custom td { padding: 1rem; vertical-align: middle; font-size: 0.9rem; border-bottom: 1px solid #eaedf1; }
|
||||
|
||||
/* Modal Customization */
|
||||
.modal-content { border-radius: 12px; border: none; box-shadow: 0 10px 30px rgba(0,0,0,0.1); }
|
||||
.modal-header { border-bottom: 1px solid #eaedf1; background-color: #f8f9fc; border-radius: 12px 12px 0 0; }
|
||||
.modal-footer { border-top: 1px solid #eaedf1; }
|
||||
.form-control:focus, .form-select:focus { border-color: #5c4df0; box-shadow: 0 0 0 0.25rem rgba(92, 77, 240, 0.25); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<aside id="sidebar">
|
||||
<div class="sidebar-brand d-flex align-items-center">
|
||||
<span class="sidebar-brand-icon"><i class="bi bi-buildings"></i></span>
|
||||
<div>
|
||||
<div class="mb-0 fs-6">NEXUS <span class="badge bg-secondary ms-1" style="font-size: 0.6rem;">ERP</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-heading mt-2">Core Entities</div>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-person-badge me-2"></i> Staff Directory</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-people me-2"></i> Clients</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-broadcast-pin me-2"></i> MNO Partners</a>
|
||||
<div class="sidebar-heading mt-2">Resources</div>
|
||||
<a href="#" class="sidebar-nav-item active"><i class="bi bi-folder2-open me-2"></i> Document Vault</a>
|
||||
</aside>
|
||||
|
||||
<main id="main-content">
|
||||
<header class="topbar d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="fw-bold" style="font-size: 0.95rem;">Document Vault</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container-fluid p-4">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">Corporate Documents</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage compliance files, MNO agreements, and client contracts.</p>
|
||||
</div>
|
||||
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenUploadModal">
|
||||
<i class="bi bi-cloud-upload me-2"></i> Upload Document
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-custom table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>File Name</th>
|
||||
<th>Related Entity</th>
|
||||
<th>Type</th>
|
||||
<th>Size</th>
|
||||
<th>Uploaded</th>
|
||||
<th class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi bi-file-earmark-pdf text-danger me-2"></i>
|
||||
<span class="fw-bold text-dark">MTN_SIP_Trunk_SLA_2026.pdf</span>
|
||||
</td>
|
||||
<td><span class="badge bg-dark bg-opacity-10 text-dark">MNO: MTN</span></td>
|
||||
<td>Contract</td>
|
||||
<td class="text-secondary">2.4 MB</td>
|
||||
<td class="text-secondary">Jun 15, 2026</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1"><i class="bi bi-download"></i></button>
|
||||
<button class="btn btn-sm btn-light text-secondary me-1 btn-edit-doc" data-id="1" data-filename="MTN_SIP_Trunk_SLA_2026.pdf" data-entity="mno_mtn" data-type="contract"><i class="bi bi-pencil"></i></button>
|
||||
<button class="btn btn-sm btn-light text-danger"><i class="bi bi-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi bi-file-earmark-word text-primary me-2"></i>
|
||||
<span class="fw-bold text-dark">Telecel_Interconnect_Draft.docx</span>
|
||||
</td>
|
||||
<td><span class="badge bg-dark bg-opacity-10 text-dark">MNO: Telecel</span></td>
|
||||
<td>Draft</td>
|
||||
<td class="text-secondary">850 KB</td>
|
||||
<td class="text-secondary">Jun 12, 2026</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1"><i class="bi bi-download"></i></button>
|
||||
<button class="btn btn-sm btn-light text-secondary me-1 btn-edit-doc" data-id="2" data-filename="Telecel_Interconnect_Draft.docx" data-entity="mno_telecel" data-type="draft"><i class="bi bi-pencil"></i></button>
|
||||
<button class="btn btn-sm btn-light text-danger"><i class="bi bi-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="modal fade" id="documentModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold" id="documentModalTitle">Upload New Document</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<form id="documentForm" enctype="multipart/form-data">
|
||||
<div class="modal-body p-4">
|
||||
<input type="hidden" id="docId" name="id">
|
||||
<input type="hidden" id="docMethod" name="_method" value="POST">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Select File</label>
|
||||
<input class="form-control" type="file" id="docFile" name="file">
|
||||
<div class="form-text" id="fileHelpText">Max size: 10MB. Allowed: PDF, DOCX, PNG, JPG.</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Document Type</label>
|
||||
<select class="form-select" id="docType" name="type" required>
|
||||
<option value="" selected disabled>Select...</option>
|
||||
<option value="contract">SLA / Contract</option>
|
||||
<option value="draft">Draft Proposal</option>
|
||||
<option value="identity">KYC / Identity</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Related Entity</label>
|
||||
<select class="form-select" id="docEntity" name="entity_id">
|
||||
<option value="">General (None)</option>
|
||||
<optgroup label="Mobile Network Operators">
|
||||
<option value="mno_mtn">MTN</option>
|
||||
<option value="mno_telecel">Telecel</option>
|
||||
<option value="mno_at">AT</option>
|
||||
</optgroup>
|
||||
<optgroup label="Clients">
|
||||
<option value="client_1">Click Tech Corp</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Description</label>
|
||||
<textarea class="form-control" id="docNotes" name="notes" rows="2" placeholder="Optional notes..."></textarea>
|
||||
</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="btnSubmitDoc">
|
||||
Upload File
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Setup CSRF token for all AJAX requests
|
||||
$.ajaxSetup({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
}
|
||||
});
|
||||
|
||||
const docModal = new bootstrap.Modal(document.getElementById('documentModal'));
|
||||
const $form = $('#documentForm');
|
||||
|
||||
// --- OPEN MODAL FOR CREATE ---
|
||||
$('#btnOpenUploadModal').on('click', function() {
|
||||
$form[0].reset(); // Clear previous data
|
||||
$('#docId').val('');
|
||||
$('#docMethod').val('POST');
|
||||
|
||||
$('#documentModalTitle').text('Upload New Document');
|
||||
$('#btnSubmitDoc').html('<i class="bi bi-cloud-upload me-2"></i>Upload File');
|
||||
$('#docFile').prop('required', true); // File is mandatory for upload
|
||||
$('#fileHelpText').text('Max size: 10MB. Allowed: PDF, DOCX, PNG, JPG.');
|
||||
|
||||
docModal.show();
|
||||
});
|
||||
|
||||
// --- OPEN MODAL FOR EDIT ---
|
||||
$('.btn-edit-doc').on('click', function() {
|
||||
const id = $(this).data('id');
|
||||
const filename = $(this).data('filename');
|
||||
const entity = $(this).data('entity');
|
||||
const type = $(this).data('type');
|
||||
|
||||
$form[0].reset();
|
||||
$('#docId').val(id);
|
||||
$('#docMethod').val('PUT'); // Set to PUT for backend routing
|
||||
|
||||
// Populate existing data
|
||||
$('#docType').val(type);
|
||||
$('#docEntity').val(entity);
|
||||
|
||||
$('#documentModalTitle').text('Edit Document Info');
|
||||
$('#btnSubmitDoc').html('<i class="bi bi-save me-2"></i>Save Changes');
|
||||
$('#docFile').prop('required', false); // File is optional when editing
|
||||
$('#fileHelpText').text('Leave file input blank to keep existing file: ' + filename);
|
||||
|
||||
docModal.show();
|
||||
});
|
||||
|
||||
// --- HANDLE FORM SUBMISSION VIA AJAX ---
|
||||
$form.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const $btn = $('#btnSubmitDoc');
|
||||
const originalText = $btn.html();
|
||||
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2"></span> Processing...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
// Use FormData to handle the multipart/form-data payload natively
|
||||
let formData = new FormData(this);
|
||||
let isEdit = $('#docId').val() !== '';
|
||||
let ajaxUrl = isEdit ? '/api/documents/' + $('#docId').val() : '/api/documents';
|
||||
|
||||
// Simulating the AJAX call
|
||||
setTimeout(() => {
|
||||
console.log('Submitted Payload:', Object.fromEntries(formData));
|
||||
|
||||
$btn.html(originalText);
|
||||
$btn.prop('disabled', false);
|
||||
docModal.hide();
|
||||
|
||||
// Here you would normally trigger a toast notification or reload the data table
|
||||
alert(isEdit ? 'Document metadata updated successfully!' : 'File uploaded successfully!');
|
||||
}, 1200);
|
||||
|
||||
/* // Actual AJAX Call Structure:
|
||||
$.ajax({
|
||||
url: ajaxUrl,
|
||||
type: 'POST', // Always POST for FormData, pass _method=PUT in data for edits
|
||||
data: formData,
|
||||
processData: false, // Prevent jQuery from processing the data
|
||||
contentType: false, // Prevent jQuery from setting contentType
|
||||
success: function(response) {
|
||||
docModal.hide();
|
||||
// Refresh DataTables or UI
|
||||
},
|
||||
error: function(xhr) {
|
||||
$btn.html(originalText).prop('disabled', false);
|
||||
// Handle validation errors
|
||||
}
|
||||
});
|
||||
*/
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
323
resources/views/documents_vault/index.blade.php
Normal file
323
resources/views/documents_vault/index.blade.php
Normal file
@@ -0,0 +1,323 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'Nexus ERP - Document Vault')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.file-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 8px; font-size: 1.25rem; }
|
||||
.icon-pdf { background-color: rgba(239, 68, 68, 0.1); color: #ef4444; }
|
||||
.icon-word { background-color: rgba(59, 130, 246, 0.1); color: #3b82f6; }
|
||||
.icon-img { background-color: rgba(16, 185, 129, 0.1); color: #10b981; }
|
||||
|
||||
.sync-badge { font-size: 0.7rem; padding: 0.25rem 0.5rem; border-radius: 4px; display: inline-flex; align-items: center; gap: 4px; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@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="#" class="text-secondary text-decoration-none me-2" style="font-size: 0.95rem;">Resources</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;">Document Vault</span>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">Document Vault</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage corporate files, SLA agreements, and compliance records.</p>
|
||||
</div>
|
||||
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenDocModal">
|
||||
<i class="bi bi-cloud-upload me-2"></i> Upload File
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-3 h-100 border-0">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">TOTAL FILES</div>
|
||||
<i class="bi bi-files text-secondary"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold mb-0">1,248</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-3 h-100 border-0">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">STORAGE USED</div>
|
||||
<i class="bi bi-hdd-network text-primary"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold mb-0">4.2 GB <span class="fs-6 fw-normal text-secondary">/ 50 GB</span></h3>
|
||||
<div class="progress mt-2" style="height: 4px;">
|
||||
<div class="progress-bar bg-primary" role="progressbar" style="width: 8.4%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-3 h-100 border-0">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">PAPERLESS-NGX SYNC</div>
|
||||
<i class="bi bi-box-arrow-up-right text-success"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold mb-0">892 <span class="fs-6 fw-normal text-secondary">Archived</span></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="content-card p-3 h-100 border-0 bg-primary bg-opacity-10">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div class="text-primary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">PENDING REVIEW</div>
|
||||
<i class="bi bi-clock-history text-primary"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold text-primary mb-0">14</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="p-3 border-bottom bg-light bg-opacity-50">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-5">
|
||||
<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 filenames, tags, or entities...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">All Document Types</option>
|
||||
<option value="contract">Contracts & SLAs</option>
|
||||
<option value="kyc">KYC & Identity</option>
|
||||
<option value="invoice">Invoices</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">Status: All</option>
|
||||
<option value="synced">Archived in Paperless</option>
|
||||
<option value="local">Local Only</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button class="btn btn-secondary w-100"><i class="bi bi-funnel"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-custom table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>File Details</th>
|
||||
<th>Related Entity</th>
|
||||
<th>Category</th>
|
||||
<th>Size / Date</th>
|
||||
<th>Archive Status</th>
|
||||
<th class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="file-icon icon-pdf me-3"><i class="bi bi-file-earmark-pdf-fill"></i></div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark">MTN_SIP_Trunk_SLA_2026.pdf</div>
|
||||
<div class="text-secondary" style="font-size: 0.75rem;">ID: DOC-9942</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="badge bg-dark bg-opacity-10 text-dark border"><i class="bi bi-broadcast-pin me-1"></i>MNO: MTN Ghana</span></td>
|
||||
<td><span class="badge bg-primary bg-opacity-10 text-primary">SLA Contract</span></td>
|
||||
<td>
|
||||
<div class="text-dark fw-semibold" style="font-size: 0.85rem;">2.4 MB</div>
|
||||
<div class="text-secondary" style="font-size: 0.75rem;">Jun 15, 2026</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="sync-badge bg-success bg-opacity-10 text-success border border-success-subtle">
|
||||
<i class="bi bi-check-circle-fill"></i> Synced to Paperless
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-secondary me-1" title="Download"><i class="bi bi-download"></i></button>
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-doc"
|
||||
data-id="1" data-filename="MTN_SIP_Trunk_SLA_2026.pdf" data-entity="mno_1" data-type="contract" data-notes="Signed copy for 2026 SIP links.">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="file-icon icon-word me-3"><i class="bi bi-file-earmark-word-fill"></i></div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark">ClickTech_Hosting_Proposal_Draft.docx</div>
|
||||
<div class="text-secondary" style="font-size: 0.75rem;">ID: DOC-9943</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="badge bg-info bg-opacity-10 text-info border border-info-subtle"><i class="bi bi-people me-1"></i>Client: Click Tech</span></td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary">Draft / Proposal</span></td>
|
||||
<td>
|
||||
<div class="text-dark fw-semibold" style="font-size: 0.85rem;">850 KB</div>
|
||||
<div class="text-secondary" style="font-size: 0.75rem;">Jun 18, 2026</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="sync-badge bg-secondary bg-opacity-10 text-secondary border">
|
||||
<i class="bi bi-hdd"></i> Local Storage Only
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-secondary me-1" title="Download"><i class="bi bi-download"></i></button>
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-doc"
|
||||
data-id="2" data-filename="ClickTech_Hosting_Proposal_Draft.docx" data-entity="client_1" data-type="draft" data-notes="Awaiting feedback before finalizing.">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('modals')
|
||||
<div class="modal fade" id="docModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title fw-bold" id="docModalTitle">Upload Document</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<form id="docForm" enctype="multipart/form-data">
|
||||
<div class="modal-body p-4">
|
||||
<input type="hidden" id="docId" name="id">
|
||||
<input type="hidden" id="docMethod" name="_method" value="POST">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Select File</label>
|
||||
<input class="form-control" type="file" id="docFile" name="file">
|
||||
<div class="form-text" id="fileHelpText">Max size: 10MB. Allowed: PDF, DOCX, PNG, JPG.</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Document Type *</label>
|
||||
<select class="form-select" id="docType" name="type" required>
|
||||
<option value="" selected disabled>Select...</option>
|
||||
<option value="contract">SLA / Contract</option>
|
||||
<option value="draft">Draft Proposal</option>
|
||||
<option value="kyc">KYC / Identity</option>
|
||||
<option value="invoice">Invoice</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Related Entity</label>
|
||||
<select class="form-select" id="docEntity" name="entity_id">
|
||||
<option value="">General (None)</option>
|
||||
<optgroup label="MNO Partners">
|
||||
<option value="mno_1">MTN Ghana</option>
|
||||
<option value="mno_2">Telecel Ghana</option>
|
||||
</optgroup>
|
||||
<optgroup label="Clients">
|
||||
<option value="client_1">Click Tech Corp</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Notes & Description</label>
|
||||
<textarea class="form-control" id="docNotes" name="notes" rows="2" placeholder="Optional context about this file..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="p-3 bg-light rounded border border-secondary-subtle">
|
||||
<div class="form-check form-switch d-flex align-items-center mb-0">
|
||||
<input class="form-check-input mt-0 me-3" type="checkbox" role="switch" id="pushToPaperless" name="push_to_paperless" value="1" style="width: 2.5em; height: 1.25em;">
|
||||
<label class="form-check-label" for="pushToPaperless">
|
||||
<span class="fw-bold text-dark d-block" style="font-size: 0.85rem;">Archive to Paperless-Ngx</span>
|
||||
<span class="text-secondary" style="font-size: 0.75rem;">Automatically map tags and push this file to the OCR server in the background.</span>
|
||||
</label>
|
||||
</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="btnSubmitDoc">
|
||||
Upload File
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
const docModal = new bootstrap.Modal(document.getElementById('docModal'));
|
||||
const $form = $('#docForm');
|
||||
|
||||
// --- OPEN MODAL FOR CREATE ---
|
||||
$('#btnOpenDocModal').on('click', function() {
|
||||
$form[0].reset();
|
||||
$('#docId').val('');
|
||||
$('#docMethod').val('POST');
|
||||
|
||||
$('#docModalTitle').text('Upload Document');
|
||||
$('#btnSubmitDoc').html('<i class="bi bi-cloud-upload me-2"></i>Upload File');
|
||||
$('#docFile').prop('required', true);
|
||||
$('#fileHelpText').text('Max size: 10MB. Allowed: PDF, DOCX, PNG, JPG.');
|
||||
|
||||
docModal.show();
|
||||
});
|
||||
|
||||
// --- OPEN MODAL FOR EDIT ---
|
||||
$('.btn-edit-doc').on('click', function() {
|
||||
const data = $(this).data();
|
||||
|
||||
$form[0].reset();
|
||||
$('#docId').val(data.id);
|
||||
$('#docMethod').val('PUT');
|
||||
|
||||
$('#docType').val(data.type);
|
||||
$('#docEntity').val(data.entity);
|
||||
$('#docNotes').val(data.notes);
|
||||
|
||||
$('#docModalTitle').text('Edit Document Info');
|
||||
$('#btnSubmitDoc').html('<i class="bi bi-save me-2"></i>Save Changes');
|
||||
$('#docFile').prop('required', false); // File is optional on edit
|
||||
$('#fileHelpText').html('Leave blank to keep existing file: <strong class="text-dark">' + data.filename + '</strong>');
|
||||
|
||||
docModal.show();
|
||||
});
|
||||
|
||||
// --- HANDLE FORM SUBMISSION ---
|
||||
$form.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const $btn = $('#btnSubmitDoc');
|
||||
const originalText = $btn.html();
|
||||
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2"></span> Processing...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
let formData = new FormData(this);
|
||||
const isPaperless = formData.get('push_to_paperless') === '1';
|
||||
|
||||
setTimeout(() => {
|
||||
$btn.html(originalText).prop('disabled', false);
|
||||
docModal.hide();
|
||||
|
||||
if (isPaperless) {
|
||||
alert('File saved locally and queued for Paperless-Ngx sync!');
|
||||
} else {
|
||||
alert('File metadata updated successfully!');
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
23
resources/views/home.blade.php
Normal file
23
resources/views/home.blade.php
Normal file
@@ -0,0 +1,23 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Dashboard') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{ __('You are logged in!') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
74
resources/views/layouts/app.blade.php
Normal file
74
resources/views/layouts/app.blade.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<!doctype html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- CSRF Token -->
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<title>Project Status Reporting</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="//fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<link rel="stylesheet" href="{{ url('public/assets/libs/bootstrap/css/bootstrap5.3.2.css') }}">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">CML</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/projects">Projects</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/project-status">Project Statuses</a>
|
||||
</li>
|
||||
<!-- <li class="nav-item">
|
||||
<a class="nav-link" href="#">Contact</a>
|
||||
</li> -->
|
||||
</ul>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
User Profile
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="userDropdown">
|
||||
<li><a class="dropdown-item" href="#">My Profile</a></li>
|
||||
<li><a class="dropdown-item" href="#">Settings</a></li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ route('logout') }}"
|
||||
onclick="event.preventDefault();
|
||||
document.getElementById('logout-form').submit();">
|
||||
{{ __('Logout') }}
|
||||
</a>
|
||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
|
||||
@csrf
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="py-4">
|
||||
@yield('content')
|
||||
</main>
|
||||
</div>
|
||||
<script src="{{ url('public/assets/libs/bootstrap/js/bootstrap5.3.2.js') }}" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
103
resources/views/layouts/master.blade.php
Normal file
103
resources/views/layouts/master.blade.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>@yield('title', config('app.name'))</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
<style>
|
||||
body { background-color: #f8f9fc; }
|
||||
|
||||
/* Sidebar Styling */
|
||||
#sidebar {
|
||||
width: 260px;
|
||||
background-color: #111425;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.sidebar-brand { color: #fff; padding: 1.5rem 1.25rem; font-weight: 700; }
|
||||
.sidebar-brand-icon { background: #5c4df0; padding: 0.5rem; border-radius: 8px; margin-right: 10px; }
|
||||
.sidebar-nav-item { color: #8a90a5; text-decoration: none; padding: 0.75rem 1.25rem; display: block; border-radius: 8px; margin: 0.2rem 1rem; font-size: 0.9rem; }
|
||||
.sidebar-nav-item:hover, .sidebar-nav-item.active { background-color: #5c4df0; color: #fff; }
|
||||
.sidebar-heading { color: #5a617a; font-size: 0.75rem; text-transform: uppercase; padding: 1rem 1.25rem 0.5rem; font-weight: 600; letter-spacing: 0.5px; }
|
||||
|
||||
/* Main Content Layout */
|
||||
#main-content { margin-left: 260px; min-height: 100vh; }
|
||||
|
||||
/* Topbar Styling */
|
||||
.topbar { background: #fff; height: 70px; border-bottom: 1px solid #eaedf1; padding: 0 1.5rem; }
|
||||
.badge-notification { position: absolute; top: -5px; right: -5px; background: #e74a3b; border-radius: 50%; padding: 3px 6px; font-size: 10px; color: white;}
|
||||
|
||||
/* Dashboard Cards */
|
||||
.hero-banner { background-color: #181b31; color: white; border-radius: 12px; }
|
||||
.stat-card { border: 1px solid #eaedf1; border-radius: 12px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); }
|
||||
.stat-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 8px; font-size: 1.2rem; }
|
||||
|
||||
.progress-slim { height: 6px; border-radius: 4px; }
|
||||
</style>
|
||||
@stack('styles')
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@include('layouts.partials.sidebar')
|
||||
<main id="main-content">
|
||||
@include('layouts.partials.topbar')
|
||||
<div class="container-fluid p-4">
|
||||
|
||||
@yield('content')
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<!-- jQuery -->
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Function to update the clock dynamically
|
||||
function updateClock() {
|
||||
const now = new Date();
|
||||
|
||||
// Format Date: Thu, Jun 18, 2026
|
||||
const dateOptions = { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' };
|
||||
const formattedDate = now.toLocaleDateString('en-US', dateOptions);
|
||||
|
||||
// Format Time: 01:37:34 PM
|
||||
const timeOptions = { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true };
|
||||
const formattedTime = now.toLocaleTimeString('en-US', timeOptions);
|
||||
|
||||
$('#current-date').text(formattedDate);
|
||||
$('#current-time').text(formattedTime);
|
||||
}
|
||||
|
||||
// Run clock update immediately and then every second
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
|
||||
// Basic button interaction demo using jQuery
|
||||
$('#seedBtn').on('click', function() {
|
||||
const $btn = $(this);
|
||||
const originalText = $btn.html();
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span> Seeding...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
// Simulate an API call
|
||||
setTimeout(() => {
|
||||
$btn.html(originalText);
|
||||
$btn.prop('disabled', false);
|
||||
alert('Demo records seeded successfully!');
|
||||
}, 1500);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@stack('scripts')
|
||||
|
||||
</body>
|
||||
</html>
|
||||
75
resources/views/layouts/masterbeta.blade.php
Normal file
75
resources/views/layouts/masterbeta.blade.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<title>@yield('title', 'CML ERP')</title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
|
||||
<style>
|
||||
body { background-color: #f8f9fc; }
|
||||
|
||||
/* Sidebar Styling */
|
||||
#sidebar { width: 260px; background-color: #111425; position: fixed; height: 100vh; overflow-y: auto; z-index: 1000; }
|
||||
.sidebar-brand { color: #fff; padding: 1.5rem 1.25rem; font-weight: 700; }
|
||||
.sidebar-brand-icon { background: #5c4df0; padding: 0.5rem; border-radius: 8px; margin-right: 10px; }
|
||||
.sidebar-nav-item { color: #8a90a5; text-decoration: none; padding: 0.75rem 1.25rem; display: block; border-radius: 8px; margin: 0.2rem 1rem; font-size: 0.9rem; transition: all 0.2s; }
|
||||
.sidebar-nav-item:hover, .sidebar-nav-item.active { background-color: #5c4df0; color: #fff; }
|
||||
.sidebar-heading { color: #5a617a; font-size: 0.75rem; text-transform: uppercase; padding: 1rem 1.25rem 0.5rem; font-weight: 600; }
|
||||
|
||||
/* Main Content & Topbar */
|
||||
#main-content { margin-left: 260px; min-height: 100vh; display: flex; flex-direction: column; }
|
||||
.topbar { background: #fff; height: 70px; border-bottom: 1px solid #eaedf1; padding: 0 1.5rem; flex-shrink: 0; }
|
||||
|
||||
/* Reusable Components */
|
||||
.content-card { background: #fff; border: 1px solid #eaedf1; border-radius: 12px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); }
|
||||
.table-custom th { background-color: #f8f9fc; color: #5a617a; font-weight: 600; font-size: 0.8rem; text-transform: uppercase; border-bottom: 2px solid #eaedf1; padding: 1rem; }
|
||||
.table-custom td { padding: 1rem; vertical-align: middle; font-size: 0.9rem; border-bottom: 1px solid #eaedf1; }
|
||||
.form-control:focus, .form-select:focus { border-color: #5c4df0; box-shadow: 0 0 0 0.25rem rgba(92, 77, 240, 0.25); }
|
||||
</style>
|
||||
|
||||
@stack('styles')
|
||||
<script>
|
||||
var base_url = "{!! url('/') !!}";
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@include('layouts.partials.sidebar')
|
||||
|
||||
<main id="main-content">
|
||||
|
||||
@include('layouts.partials.topbar')
|
||||
|
||||
<div class="container-fluid p-4 flex-grow-1">
|
||||
@yield('content')
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@stack('modals')
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$.ajaxSetup({
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
|
||||
});
|
||||
|
||||
function updateClock() {
|
||||
const now = new Date();
|
||||
$('#current-time').text(now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true }));
|
||||
}
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
});
|
||||
</script>
|
||||
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
||||
309
resources/views/layouts/new_master.blade.php
Normal file
309
resources/views/layouts/new_master.blade.php
Normal file
@@ -0,0 +1,309 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Nexus ERP Dashboard</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
<style>
|
||||
body { background-color: #f8f9fc; }
|
||||
|
||||
/* Sidebar Styling */
|
||||
#sidebar {
|
||||
width: 260px;
|
||||
background-color: #111425;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.sidebar-brand { color: #fff; padding: 1.5rem 1.25rem; font-weight: 700; }
|
||||
.sidebar-brand-icon { background: #5c4df0; padding: 0.5rem; border-radius: 8px; margin-right: 10px; }
|
||||
.sidebar-nav-item { color: #8a90a5; text-decoration: none; padding: 0.75rem 1.25rem; display: block; border-radius: 8px; margin: 0.2rem 1rem; font-size: 0.9rem; }
|
||||
.sidebar-nav-item:hover, .sidebar-nav-item.active { background-color: #5c4df0; color: #fff; }
|
||||
.sidebar-heading { color: #5a617a; font-size: 0.75rem; text-transform: uppercase; padding: 1rem 1.25rem 0.5rem; font-weight: 600; letter-spacing: 0.5px; }
|
||||
|
||||
/* Main Content Layout */
|
||||
#main-content { margin-left: 260px; min-height: 100vh; }
|
||||
|
||||
/* Topbar Styling */
|
||||
.topbar { background: #fff; height: 70px; border-bottom: 1px solid #eaedf1; padding: 0 1.5rem; }
|
||||
.badge-notification { position: absolute; top: -5px; right: -5px; background: #e74a3b; border-radius: 50%; padding: 3px 6px; font-size: 10px; color: white;}
|
||||
|
||||
/* Dashboard Cards */
|
||||
.hero-banner { background-color: #181b31; color: white; border-radius: 12px; }
|
||||
.stat-card { border: 1px solid #eaedf1; border-radius: 12px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); }
|
||||
.stat-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 8px; font-size: 1.2rem; }
|
||||
|
||||
.progress-slim { height: 6px; border-radius: 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<aside id="sidebar">
|
||||
<div class="sidebar-brand d-flex align-items-center">
|
||||
<span class="sidebar-brand-icon"><i class="bi bi-buildings"></i></span>
|
||||
<div>
|
||||
<div class="mb-0 fs-6">NEXUS <span class="badge bg-secondary ms-1" style="font-size: 0.6rem;">ERP</span></div>
|
||||
<div class="text-secondary" style="font-size: 0.65rem; letter-spacing: 1px;">v1.2.0 • PROTOTYPE</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-3 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-dark border-secondary text-secondary"><i class="bi bi-search"></i></span>
|
||||
<input type="text" class="form-control bg-dark border-secondary text-light placeholder-secondary" placeholder="Quick search menus...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-heading">Overview</div>
|
||||
<a href="#" class="sidebar-nav-item active"><i class="bi bi-grid-1x2 me-2"></i> Dashboard</a>
|
||||
|
||||
<div class="sidebar-heading mt-2">Sales & Operations</div>
|
||||
<a href="#" class="sidebar-nav-item d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-people me-2"></i> Customers</span>
|
||||
<span class="badge rounded-pill bg-success text-dark" style="background-color: #c3e6cb !important;">4</span>
|
||||
</a>
|
||||
<a href="#" class="sidebar-nav-item d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-receipt me-2"></i> Invoices</span>
|
||||
<span class="badge rounded-pill bg-warning text-dark" style="background-color: #ffeeba !important;">3</span>
|
||||
</a>
|
||||
|
||||
<div class="sidebar-heading mt-2">Core Templates</div>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-file-earmark-text me-2"></i> General Record Form</a>
|
||||
|
||||
<div class="sidebar-heading mt-2">Intelligence</div>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-graph-up-arrow me-2"></i> Reports & Analytics</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-gear me-2"></i> System Settings</a>
|
||||
|
||||
<div class="position-absolute bottom-0 w-100 p-3">
|
||||
<div class="d-flex align-items-center bg-dark rounded p-2 text-light" style="background-color: #0d1020 !important;">
|
||||
<div class="rounded-circle bg-primary d-flex justify-content-center align-items-center me-2" style="width: 32px; height: 32px; font-size: 0.8rem;">AD</div>
|
||||
<div>
|
||||
<div class="fs-6 fw-bold" style="font-size: 0.85rem !important;">Admin User</div>
|
||||
<div class="text-secondary" style="font-size: 0.7rem;">admin@nexuserp.io</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main id="main-content">
|
||||
<header class="topbar d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="bi bi-house text-secondary me-2"></i>
|
||||
<i class="bi bi-chevron-right text-secondary me-2" style="font-size: 0.8rem;"></i>
|
||||
<span class="fw-bold">Dashboard</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="text-secondary me-4" style="font-size: 0.9rem;">
|
||||
<i class="bi bi-calendar4 me-1"></i> <span id="current-date">Thu, Jun 18, 2026</span>
|
||||
<span class="mx-2">|</span>
|
||||
<i class="bi bi-clock me-1"></i> <span id="current-time">01:37:34 PM</span>
|
||||
</div>
|
||||
<div class="position-relative me-4">
|
||||
<i class="bi bi-bell fs-5 text-secondary"></i>
|
||||
<span class="badge-notification">2</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="rounded-circle bg-light d-flex justify-content-center align-items-center me-2 border text-dark fw-bold" style="width: 32px; height: 32px; font-size: 0.8rem;">AU</div>
|
||||
<span class="fw-bold" style="font-size: 0.9rem;">Admin User</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container-fluid p-4">
|
||||
|
||||
<div class="hero-banner p-4 mb-4 d-flex justify-content-between align-items-center">
|
||||
<div class="w-50">
|
||||
<h3 class="fw-bold mb-3">Base ERP Workstation <span class="badge bg-primary fs-6 align-middle ms-2" style="background-color: #5c4df0 !important;">ACTIVE</span></h3>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.95rem; line-height: 1.6;">
|
||||
Welcome to Nexus-ERP base mockup. This screen loads aggregated statistics computed React state modifications (Customer Directory alterations, invoices creations, etc.) instantly.
|
||||
</p>
|
||||
</div>
|
||||
<div class="d-flex gap-3">
|
||||
<button class="btn text-white fw-bold d-flex align-items-center px-4" style="background-color: #5c4df0; border-radius: 8px;" id="seedBtn">
|
||||
<i class="bi bi-stars me-2"></i> Seed Demo Records
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary text-white fw-bold d-flex align-items-center px-4" style="border-radius: 8px; border-color: #5a617a;">
|
||||
<i class="bi bi-plus-square me-2"></i> New Record Form
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">ENTERPRISE REVENUE</div>
|
||||
<div class="stat-icon bg-success bg-opacity-10 text-success"><i class="bi bi-currency-dollar"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">$1,438,950</h2>
|
||||
<div class="d-flex align-items-center mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-success fw-bold"><i class="bi bi-arrow-up-right me-1"></i>+12.4%</span>
|
||||
<span class="text-secondary ms-2">quarter over quarter</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">ACTIVE CUSTOMERS</div>
|
||||
<div class="stat-icon bg-primary bg-opacity-10 text-primary" style="color: #5c4df0 !important;"><i class="bi bi-people"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">2</h2>
|
||||
<div class="d-flex align-items-center justify-content-between mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-primary fw-bold" style="color: #5c4df0 !important;">4 total entries</span>
|
||||
<span class="text-secondary">98% engagement index</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">PENDING RECEIVABLES</div>
|
||||
<div class="stat-icon bg-warning bg-opacity-10 text-warning"><i class="bi bi-clock"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">$7,800</h2>
|
||||
<div class="d-flex align-items-center mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-warning fw-bold">1 current bills</span>
|
||||
<span class="text-secondary ms-3 lh-sm" style="font-size: 0.7rem;">Immediate settlement<br>needed</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6">
|
||||
<div class="card stat-card h-100 p-3 border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-secondary fw-bold" style="font-size: 0.75rem; letter-spacing: 0.5px;">SLA DELIVERY INDEX</div>
|
||||
<div class="stat-icon bg-danger bg-opacity-10 text-danger"><i class="bi bi-percent"></i></div>
|
||||
</div>
|
||||
<h2 class="fw-bold mt-2 mb-3">84.5%</h2>
|
||||
<div class="d-flex align-items-center mt-auto" style="font-size: 0.8rem;">
|
||||
<span class="text-success fw-bold"><i class="bi bi-circle-fill me-1" style="font-size: 0.5rem;"></i>Healthy</span>
|
||||
<span class="text-secondary ms-3">Average response: 3.5 hrs</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-8">
|
||||
<div class="card stat-card border-0 p-4 h-100">
|
||||
<div class="d-flex justify-content-between align-items-start mb-4">
|
||||
<div>
|
||||
<h6 class="fw-bold mb-1">Revenue Projections Trend</h6>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.85rem;">Demonstrating visual charts using pure responsive vector layouts</p>
|
||||
</div>
|
||||
<div class="d-flex gap-3" style="font-size: 0.85rem;">
|
||||
<span class="d-flex align-items-center"><i class="bi bi-circle-fill text-primary me-2" style="font-size: 0.5rem;"></i> Sales Target</span>
|
||||
<span class="d-flex align-items-center text-secondary"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #d1d5db;"></i> Prior Year</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-100 mt-auto position-relative" style="height: 200px;">
|
||||
<svg viewBox="0 0 800 200" class="w-100 h-100" preserveAspectRatio="none">
|
||||
<path d="M0,180 Q200,220 400,100 T800,20" fill="none" stroke="#e0e0e0" stroke-width="2" stroke-dasharray="5,5"/>
|
||||
<path d="M0,200 Q200,220 400,160 T800,0" fill="none" stroke="#5c4df0" stroke-width="4"/>
|
||||
<circle cx="400" cy="160" r="6" fill="#5c4df0" stroke="white" stroke-width="2"/>
|
||||
<circle cx="600" cy="50" r="6" fill="#5c4df0" stroke="white" stroke-width="2"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="card stat-card border-0 p-4 h-100">
|
||||
<h6 class="fw-bold mb-1">Department Distribution</h6>
|
||||
<p class="text-secondary mb-4" style="font-size: 0.85rem;">Ratio of active records grouped by segment</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #5c4df0;"></i> Finance</span>
|
||||
<span class="text-secondary">1 (25%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 25%; background-color: #5c4df0;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #10b981;"></i> Operations</span>
|
||||
<span class="text-secondary">1 (25%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 25%; background-color: #10b981;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #f59e0b;"></i> Sales</span>
|
||||
<span class="text-secondary">1 (25%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 25%; background-color: #f59e0b;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1" style="font-size: 0.85rem;">
|
||||
<span class="fw-bold"><i class="bi bi-circle-fill me-2" style="font-size: 0.5rem; color: #ef4444;"></i> Marketing</span>
|
||||
<span class="text-secondary">0 (0%)</span>
|
||||
</div>
|
||||
<div class="progress progress-slim">
|
||||
<div class="progress-bar" role="progressbar" style="width: 0%; background-color: #ef4444;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Function to update the clock dynamically
|
||||
function updateClock() {
|
||||
const now = new Date();
|
||||
|
||||
// Format Date: Thu, Jun 18, 2026
|
||||
const dateOptions = { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' };
|
||||
const formattedDate = now.toLocaleDateString('en-US', dateOptions);
|
||||
|
||||
// Format Time: 01:37:34 PM
|
||||
const timeOptions = { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true };
|
||||
const formattedTime = now.toLocaleTimeString('en-US', timeOptions);
|
||||
|
||||
$('#current-date').text(formattedDate);
|
||||
$('#current-time').text(formattedTime);
|
||||
}
|
||||
|
||||
// Run clock update immediately and then every second
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
|
||||
// Basic button interaction demo using jQuery
|
||||
$('#seedBtn').on('click', function() {
|
||||
const $btn = $(this);
|
||||
const originalText = $btn.html();
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span> Seeding...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
// Simulate an API call
|
||||
setTimeout(() => {
|
||||
$btn.html(originalText);
|
||||
$btn.prop('disabled', false);
|
||||
alert('Demo records seeded successfully!');
|
||||
}, 1500);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
45
resources/views/layouts/partials/sidebar.blade.php
Normal file
45
resources/views/layouts/partials/sidebar.blade.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<aside id="sidebar">
|
||||
<div class="sidebar-brand d-flex align-items-center">
|
||||
<span class="sidebar-brand-icon"><i class="bi bi-cpu"></i></span>
|
||||
<div>
|
||||
<div class="mb-0 fs-6">Click <span class="badge bg-secondary ms-1" style="font-size: 0.8rem;">ERP</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-3 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-dark border-secondary text-secondary"><i class="bi bi-search"></i></span>
|
||||
<input type="text" class="form-control bg-dark border-secondary text-light placeholder-secondary" placeholder="Quick search...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-heading mt-2">Home</div>
|
||||
<a href="{{ url('/') }}" class="sidebar-nav-item {{ request()->is('/') ? 'active' : '' }}">
|
||||
<i class="bi bi-people me-2"></i> Dashboard
|
||||
</a>
|
||||
<div class="sidebar-heading mt-2">Core Entities</div>
|
||||
<a href="{{ url('/clients') }}" class="sidebar-nav-item {{ request()->is('clients*') ? 'active' : '' }}">
|
||||
<i class="bi bi-people me-2"></i> Clients
|
||||
</a>
|
||||
|
||||
|
||||
<a href="{{ url('/mnos') }}" class="sidebar-nav-item {{ request()->is('mnos*') ? 'active' : '' }}">
|
||||
<i class="bi bi-broadcast-pin me-2"></i> MNO Partners
|
||||
</a>
|
||||
<a href="{{ url('/senderids') }}" class="sidebar-nav-item {{ request()->is('senderids*') ? 'active' : '' }}">
|
||||
<i class="bi bi-alphabet me-2"></i> Sender IDs
|
||||
</a>
|
||||
<a href="{{ url('/shortcodes') }}" class="sidebar-nav-item {{ request()->is('shortcodes*') ? 'active' : '' }}">
|
||||
<i class="bi bi-123 me-2"></i> Short Codes
|
||||
</a>
|
||||
|
||||
<div class="sidebar-heading mt-2">Resources</div>
|
||||
<a href="{{ url('/documents') }}" class="sidebar-nav-item {{ request()->is('documents*') ? 'active' : '' }}">
|
||||
<i class="bi bi-folder2-open me-2"></i> Document Vault
|
||||
</a>
|
||||
|
||||
|
||||
<div class="sidebar-heading mt-2">Others</div>
|
||||
<a href="{{ url('/staff') }}" class="sidebar-nav-item {{ request()->is('staff*') ? 'active' : '' }}">
|
||||
<i class="bi bi-person-badge me-2"></i> Staff Directory
|
||||
</a>
|
||||
</aside>
|
||||
51
resources/views/layouts/partials/sidebarxx.blade.php
Normal file
51
resources/views/layouts/partials/sidebarxx.blade.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<aside id="sidebar">
|
||||
<div class="sidebar-brand d-flex align-items-center">
|
||||
<span class="sidebar-brand-icon"><i class="bi bi-buildings"></i></span>
|
||||
<div>
|
||||
<div class="mb-0 fs-6">CML <span class="badge bg-secondary ms-1" style="font-size: 0.6rem;">ERP</span></div>
|
||||
<div class="text-secondary" style="font-size: 0.65rem; letter-spacing: 1px;">v1.0.0 • PROTOTYPE</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-3 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-dark border-secondary text-secondary"><i class="bi bi-search"></i></span>
|
||||
<input type="text" class="form-control bg-dark border-secondary text-light placeholder-secondary" placeholder="Quick search menus...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-heading">Overview</div>
|
||||
<a href="#" class="sidebar-nav-item active"><i class="bi bi-grid-1x2 me-2"></i> Dashboard</a>
|
||||
|
||||
<div class="sidebar-heading mt-2">Clients & MNOs</div>
|
||||
<a href="#" class="sidebar-nav-item d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-people me-2"></i> Clients</span>
|
||||
<span class="badge rounded-pill bg-success text-dark" style="background-color: #c3e6cb !important;">4</span>
|
||||
</a>
|
||||
<a href="#" class="sidebar-nav-item d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-receipt me-2"></i> Network Operators</span>
|
||||
<span class="badge rounded-pill bg-warning text-dark" style="background-color: #ffeeba !important;">3</span>
|
||||
</a>
|
||||
|
||||
<div class="sidebar-heading mt-2">Other Modules</div>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-file-earmark-text me-2"></i> Sender IDs</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-file-earmark-text me-2"></i> Short Codes</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-file-earmark-text me-2"></i> Documents</a>
|
||||
|
||||
<div class="sidebar-heading mt-2">Utilities</div>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-graph-up-arrow me-2"></i> National Holidays</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-gear me-2"></i> Services</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-gear me-2"></i> Countries</a>
|
||||
<a href="#" class="sidebar-nav-item"><i class="bi bi-gear me-2"></i> Daily Quotes</a>
|
||||
<!-- <a href="#" class="sidebar-nav-item"><i class="bi bi-gear me-2"></i> Services</a> -->
|
||||
|
||||
<div class="position-absolute bottom-0 w-100 p-3">
|
||||
<div class="d-flex align-items-center bg-dark rounded p-2 text-light" style="background-color: #0d1020 !important;">
|
||||
<div class="rounded-circle bg-primary d-flex justify-content-center align-items-center me-2" style="width: 32px; height: 32px; font-size: 0.8rem;">AD</div>
|
||||
<div>
|
||||
<div class="fs-6 fw-bold" style="font-size: 0.85rem !important;">Admin User</div>
|
||||
<div class="text-secondary" style="font-size: 0.7rem;">admin@nexuserp.io</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
22
resources/views/layouts/partials/topbar.blade.php
Normal file
22
resources/views/layouts/partials/topbar.blade.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<header class="topbar d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
@yield('breadcrumbs')
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="text-secondary me-4" style="font-size: 0.9rem;">
|
||||
<i class="bi bi-clock me-1"></i> <span id="current-time">--:--:--</span>
|
||||
</div>
|
||||
|
||||
<div class="position-relative me-4">
|
||||
<i class="bi bi-bell fs-5 text-secondary"></i>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="rounded-circle bg-light d-flex justify-content-center align-items-center me-2 border text-dark fw-bold" style="width: 32px; height: 32px; font-size: 0.8rem;">
|
||||
{{ substr(auth()->user()->name ?? 'Admin', 0, 1) }}
|
||||
</div>
|
||||
<span class="fw-bold" style="font-size: 0.9rem;">{{ auth()->user()->name ?? 'Admin User' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
339
resources/views/network_operators/index.blade.php
Normal file
339
resources/views/network_operators/index.blade.php
Normal file
@@ -0,0 +1,339 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'Cick ERP - MNO Partners')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.avatar-circle { width: 38px; height: 38px; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: bold; font-size: 0.85rem; }
|
||||
.status-indicator { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
|
||||
.tech-badge { font-family: monospace; font-size: 0.75rem; background-color: #f1f3f9; color: #3e445b; padding: 2px 6px; border-radius: 4px; border: 1px solid #e2e8f0; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@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="#" class="text-secondary text-decoration-none me-2" style="font-size: 0.95rem;">Core Entities</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;">MNO Partners</span>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<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>
|
||||
</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>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
<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: #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>
|
||||
</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: #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>
|
||||
</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: #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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="p-3 border-bottom bg-light bg-opacity-50">
|
||||
<div 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...">
|
||||
</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>
|
||||
</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">Tailscale Mesh</option>
|
||||
<option value="public">Whitelisted Public IP</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-custom table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Operator</th>
|
||||
<th>Country</th>
|
||||
<th>Network Codes</th>
|
||||
<th>Infrastructure Links</th>
|
||||
<th>Capabilities</th>
|
||||
<th>Link 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>
|
||||
</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>
|
||||
</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> Tailscale Node</div>
|
||||
<div class="text-secondary" style="font-size: 0.75rem;">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;">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="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>
|
||||
</tbody>
|
||||
</table>
|
||||
</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>
|
||||
@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>
|
||||
@endpush
|
||||
31
resources/views/project_status/add_status.blade.php
Normal file
31
resources/views/project_status/add_status.blade.php
Normal file
@@ -0,0 +1,31 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="container mt-5">
|
||||
<h2>{{ 'Add Project Status' }}</h2>
|
||||
@include('commons.notifications')
|
||||
<form action="{{ isset($project_status) ? route('project-status.update', $project_status->id) : route('project-status.store') }}" method="POST">
|
||||
<input type="hidden" name="assignee_id" value="{{ \Auth::user()->id }}">
|
||||
<input type="hidden" name="project_id" value="{{ $project->id }}">
|
||||
@csrf
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" name="description" id="description" rows="4" required></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">Status</label>
|
||||
<select class="form-select" id="status" name="status" required>
|
||||
<option value="" disabled>-- Select Status--</option>
|
||||
<option value="Pending">Pending</option>
|
||||
<option value="In Progress">In Progress</option>
|
||||
<option value="Completed">Completed</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">{{ 'Add Status' }}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
55
resources/views/project_status/index.blade.php
Normal file
55
resources/views/project_status/index.blade.php
Normal file
@@ -0,0 +1,55 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-10">
|
||||
@include('commons.notifications')
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Project Status Reports') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Project</th>
|
||||
<th scope="col">Status Description</th>
|
||||
<th scope="col">Current Status</th>
|
||||
<th scope="col">Date Updated</th>
|
||||
<th scope="col">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $count = 1; ?>
|
||||
@foreach($project_statuses as $row)
|
||||
<tr>
|
||||
<th scope="row">{{ $count }}</th>
|
||||
<td>{{ $row->project->name }}</td>
|
||||
<td>{{ $row->description }}</td>
|
||||
<td>{{ $row->status }}</td>
|
||||
<td>{{ $row->created_at }}</td>
|
||||
<td>
|
||||
<a href="{{ url('comments/add_comment', $row->id)}}" title="Add Comments" class="btn btn-success btn-sm"><i class="bi bi-plus-circle"></i> Add Comment</a>
|
||||
<!-- <a href="{{ url('project-status/add_status', $row->id)}}" title="Add New Status" class="btn "></a> -->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<?php $count++; ?>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
44
resources/views/projects/create.blade.php
Normal file
44
resources/views/projects/create.blade.php
Normal file
@@ -0,0 +1,44 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mt-5">
|
||||
<h2>{{ isset($project) ? 'Edit project' : 'Create project' }}</h2>
|
||||
@include('commons.notifications')
|
||||
<form action="{{ isset($project) ? route('projects.update', $project->id) : route('projects.store') }}" method="POST">
|
||||
<input type="hidden" name="user_id" value="{{ \Auth::user()->id }}">
|
||||
|
||||
@csrf
|
||||
@if (isset($project))
|
||||
@method('PUT')
|
||||
@endif
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Project Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="{{ $project->name ?? '' }}" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="4" required>{{ $project->description ?? '' }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dependancy" class="form-label">Dependancy</label>
|
||||
<input type="text" class="form-control" id="dependancy" name="dependancy" value="{{ $project->dependancy ?? '' }}" placeholder="e.g., project ID or Name" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">Status</label>
|
||||
<select class="form-select" id="status" name="status" required>
|
||||
<option value="" disabled>Select Status</option>
|
||||
<option value="Active" {{ (isset($project) && $project->status == 'Active') ? 'selected' : '' }}>Active</option>
|
||||
<option value="Completed" {{ (isset($project) && $project->status == 'Completed') ? 'selected' : '' }}>Completed</option>
|
||||
<option value="Pending" {{ (isset($project) && $project->status == 'Pending') ? 'selected' : '' }}>Pending</option>
|
||||
<option value="On Hold" {{ (isset($project) && $project->status == 'On Hold') ? 'selected' : '' }}>On Hold</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">{{ isset($project) ? 'Update project' : 'Create project' }}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
43
resources/views/projects/edit.blade.php
Normal file
43
resources/views/projects/edit.blade.php
Normal file
@@ -0,0 +1,43 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mt-5">
|
||||
<h2>{{ isset($project) ? 'Edit project' : 'Create project' }}</h2>
|
||||
@include('commons.notifications')
|
||||
<form action="{{ isset($project) ? route('projects.update', $project->id) : route('projects.store') }}" method="POST">
|
||||
<input type="hidden" name="user_id" value="{{ \Auth::user()->id }}">
|
||||
@csrf
|
||||
@if (isset($project))
|
||||
@method('PUT')
|
||||
@endif
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Project Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="{{ $project->name ?? '' }}" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="4" required>{{ $project->description ?? '' }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dependancy" class="form-label">Dependancy</label>
|
||||
<input type="text" class="form-control" id="dependancy" name="dependancy" value="{{ $project->dependancy ?? '' }}" placeholder="e.g., project ID or Name" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">Status</label>
|
||||
<select class="form-select" id="status" name="status" required>
|
||||
<option value="" disabled>Select Status</option>
|
||||
<option value="Active" {{ (isset($project) && $project->status == 'Active') ? 'selected' : '' }}>Active</option>
|
||||
<option value="Completed" {{ (isset($project) && $project->status == 'Completed') ? 'selected' : '' }}>Completed</option>
|
||||
<option value="Pending" {{ (isset($project) && $project->status == 'Pending') ? 'selected' : '' }}>Pending</option>
|
||||
<option value="On Hold" {{ (isset($project) && $project->status == 'On Hold') ? 'selected' : '' }}>On Hold</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">{{ isset($project) ? 'Update project' : 'Create project' }}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
57
resources/views/projects/index.blade.php
Normal file
57
resources/views/projects/index.blade.php
Normal file
@@ -0,0 +1,57 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12">
|
||||
@include('commons.notifications')
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Projects') }}</div>
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
<div class="float-end">
|
||||
<a href="/projects/create" class="btn btn-primary btn-sm"><i class="bi bi-plus-circle"></i> Add Project</a>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-1">#</th>
|
||||
<th class="col-2">Name</th>
|
||||
<th class="col-4">Description</th>
|
||||
<th class="col-1">Status</th>
|
||||
<th class="col-2">Date Created</th>
|
||||
<th class="col-2">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $count = 1; ?>
|
||||
@foreach($projects as $row)
|
||||
<tr>
|
||||
<th scope="row">{{ $count }}</th>
|
||||
<td>{{ $row->name }}</td>
|
||||
<td>{{ $row->description }}</td>
|
||||
<td>{{ $row->status }}</td>
|
||||
<td>{{ $row->created_at }}</td>
|
||||
<td>
|
||||
<a href="{{ url('projects', $row->id)}}" title="View Project Details" class="btn btn-info btn-sm"><i class="bi bi-eye"></i></a>
|
||||
<a href="{{ url('projects/'. $row->id . '/edit') }}" title="Edit Project Details" class="btn btn-warning btn-sm"><i class="bi bi-pen"></i></a>
|
||||
<a href="{{ url('project-status/add_status', $row->id)}}" title="Add New Status" class="btn btn-success btn-sm"><i class="bi bi-plus-square"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $count++; ?>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
50
resources/views/projects/show.blade.php
Normal file
50
resources/views/projects/show.blade.php
Normal file
@@ -0,0 +1,50 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mt-5">
|
||||
<h2>{{ isset($comment) ? 'Edit comment' : 'Project Details' }}</h2>
|
||||
@include('commons.notifications')
|
||||
<input type="hidden" name="user_id" value="{{ \Auth::user()->id }}">
|
||||
@csrf
|
||||
@if (isset($comment_body))
|
||||
@method('PUT')
|
||||
@endif
|
||||
<div class="card text-dark bg-light mb-3 card w-100">
|
||||
<div class="card-body">
|
||||
<!-- <h3>Project Details/</h3> -->
|
||||
<h5 class="card-title">{{ $project->name }}</h5>
|
||||
<p class="card-text">Description : {{ $project->description }} </p>
|
||||
<p class="card-text">Date Created : {{ $project->created_at }} </p>
|
||||
<p class="card-text">Last Updated : {{ $project->updated_at }} </p>
|
||||
<a href="{{ url('projects/'. $project->id . '/edit') }}" title="Edit Project Details" class="btn btn-warning btn-sm"><i class="bi bi-pencil"></i> Edit Details</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<h3>Status Updates</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Status Update</th>
|
||||
<th scope="col">Current Status</th>
|
||||
<th scope="col">Date Updated</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $count = 1; ?>
|
||||
@foreach($project->statusInfo as $row)
|
||||
<tr>
|
||||
<th scope="row">{{ $count }}</th>
|
||||
<td>{{ $row->description }}</td>
|
||||
<td>{{ $row->status }}</td>
|
||||
<td>{{ $row->created_at }}</td>
|
||||
</tr>
|
||||
<?php $count++; ?>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{{ url('project-status/add_status', $project->id)}}" class="btn btn-success btn-sm"><i class="bi bi-plus-square"></i> Add New Status Update</a>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
319
resources/views/senderids/index.blade.php
Normal file
319
resources/views/senderids/index.blade.php
Normal file
@@ -0,0 +1,319 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'Click ERP - SMS Sender IDs')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.network-badge { font-size: 0.65rem; padding: 0.2rem 0.4rem; border-radius: 4px; border: 1px solid #e2e8f0; font-weight: 600; display: inline-flex; align-items: center; gap: 3px; }
|
||||
.net-approved { background-color: rgba(16, 185, 129, 0.1); color: #10b981; border-color: rgba(16, 185, 129, 0.2); }
|
||||
.net-pending { background-color: rgba(245, 158, 11, 0.1); color: #f59e0b; border-color: rgba(245, 158, 11, 0.2); }
|
||||
.net-rejected { background-color: rgba(239, 68, 68, 0.1); color: #ef4444; border-color: rgba(239, 68, 68, 0.2); }
|
||||
|
||||
.sender-id-text { font-family: monospace; font-size: 1.1rem; letter-spacing: 1px; color: #111425; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@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="#" class="text-secondary text-decoration-none me-2" style="font-size: 0.95rem;">Operations</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;">Sender IDs</span>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<!-- Page Header -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">SMS Sender IDs</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage alphanumeric masks, shortcodes, and MNO registration statuses.</p>
|
||||
</div>
|
||||
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenSenderModal">
|
||||
<i class="bi bi-plus-lg me-2"></i> Request Sender ID
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- KPIs -->
|
||||
<div class="row g-4 mb-4">
|
||||
<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: #5c4df0 !important;">
|
||||
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">TOTAL SENDER IDs</div>
|
||||
<h3 class="fw-bold mb-0">48</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: #10b981 !important;">
|
||||
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">FULLY APPROVED</div>
|
||||
<h3 class="fw-bold mb-0">36</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: #f59e0b !important;">
|
||||
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">PENDING MNO REVIEW</div>
|
||||
<h3 class="fw-bold mb-0">9</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;">REJECTED / BLOCKED</div>
|
||||
<h3 class="fw-bold mb-0">3</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data Table -->
|
||||
<div class="content-card">
|
||||
<div class="p-3 border-bottom bg-light bg-opacity-50">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-5">
|
||||
<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 by sender name or client...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">All Clients</option>
|
||||
<option value="client_1">Click Tech Corp</option>
|
||||
<option value="client_2">Alpha Telecom</option>
|
||||
<option value="internal">Internal System</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">Status: All</option>
|
||||
<option value="approved">Fully Approved</option>
|
||||
<option value="pending">Pending Review</option>
|
||||
<option value="rejected">Rejected</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button class="btn btn-secondary w-100"><i class="bi bi-funnel"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-custom table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Sender Name</th>
|
||||
<th>Client / Owner</th>
|
||||
<th>Type</th>
|
||||
<th>Network Status</th>
|
||||
<th>Global Status</th>
|
||||
<th class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Row 1 -->
|
||||
<tr>
|
||||
<td>
|
||||
<div class="sender-id-text fw-bold">NEXUS-OTP</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.75rem;">Created: May 12, 2026</div>
|
||||
</td>
|
||||
<td><span class="badge bg-dark bg-opacity-10 text-dark border">Internal System</span></td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary border">Alphanumeric</span></td>
|
||||
<td>
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> MTN</span>
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> Telecel</span>
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> AT</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="badge bg-success bg-opacity-10 text-success px-2 py-1"><i class="bi bi-check-all me-1"></i>Active</span></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-sender"
|
||||
data-id="1" data-sender="NEXUS-OTP" data-client="internal" data-type="alpha" data-purpose="Sending internal authentication codes." data-status="approved">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-light text-danger"><i class="bi bi-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 2 -->
|
||||
<tr>
|
||||
<td>
|
||||
<div class="sender-id-text fw-bold">CLICKTECH</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.75rem;">Created: Jun 02, 2026</div>
|
||||
</td>
|
||||
<td><span class="badge bg-info bg-opacity-10 text-info border border-info-subtle">Client: Click Tech</span></td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary border">Alphanumeric</span></td>
|
||||
<td>
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> MTN</span>
|
||||
<span class="network-badge net-pending"><i class="bi bi-clock-fill"></i> Telecel</span>
|
||||
<span class="network-badge net-pending"><i class="bi bi-clock-fill"></i> AT</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="badge bg-warning bg-opacity-10 text-warning px-2 py-1"><i class="bi bi-hourglass-split me-1"></i>Pending</span></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-sender"
|
||||
data-id="2" data-sender="CLICKTECH" data-client="client_1" data-type="alpha" data-purpose="Marketing updates and promotions for hosting services." data-status="pending">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-light text-danger"><i class="bi bi-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 3 -->
|
||||
<tr>
|
||||
<td>
|
||||
<div class="sender-id-text fw-bold">1334</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.75rem;">Created: Jun 10, 2026</div>
|
||||
</td>
|
||||
<td><span class="badge bg-info bg-opacity-10 text-info border border-info-subtle">Client: Alpha Telecom</span></td>
|
||||
<td><span class="badge bg-primary bg-opacity-10 text-primary border border-primary-subtle">Shortcode</span></td>
|
||||
<td>
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<span class="network-badge net-rejected"><i class="bi bi-x-circle-fill"></i> MTN</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="badge bg-danger bg-opacity-10 text-danger px-2 py-1"><i class="bi bi-x-octagon me-1"></i>Rejected</span></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-sender"
|
||||
data-id="3" data-sender="1334" data-client="client_2" data-type="shortcode" data-purpose="Interactive USSD/SMS fallback." data-status="rejected">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-light text-danger"><i class="bi bi-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('modals')
|
||||
<!-- SENDER ID MODAL -->
|
||||
<div class="modal fade" id="senderModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title fw-bold" id="senderModalTitle">Request Sender ID</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<form id="senderForm">
|
||||
<div class="modal-body p-4">
|
||||
<input type="hidden" id="senderRecordId" name="id">
|
||||
|
||||
<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;">Sender Name / Shortcode *</label>
|
||||
<input type="text" class="form-control fw-bold" id="senderName" name="sender_name" required maxlength="11" placeholder="e.g. NEXUS">
|
||||
<div class="form-text">Max 11 chars (Alphanumeric) or 15 digits (Numeric). No spaces.</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Type</label>
|
||||
<select class="form-select" id="senderType" name="type">
|
||||
<option value="alpha">Alphanumeric</option>
|
||||
<option value="shortcode">Numeric Shortcode</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Client / Owner *</label>
|
||||
<select class="form-select" id="senderClient" name="client_id" required>
|
||||
<option value="" selected disabled>Select Client...</option>
|
||||
<option value="internal">Internal System (Nexus ERP)</option>
|
||||
<option value="client_1">Click Tech Corp</option>
|
||||
<option value="client_2">Alpha Telecom</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Purpose & Sample Message *</label>
|
||||
<textarea class="form-control" id="senderPurpose" name="purpose" rows="3" required placeholder="Required by MNOs for whitelisting. Provide a sample of the SMS content that will be sent."></textarea>
|
||||
<div class="form-text">Example: "Your verification code is 12345. Valid for 5 minutes."</div>
|
||||
</div>
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">MNO Submission Targets</h6>
|
||||
<div class="p-3 bg-light rounded border border-secondary-subtle">
|
||||
<div class="form-check form-check-inline me-4">
|
||||
<input class="form-check-input" type="checkbox" id="mnoMtn" name="networks[]" value="mtn" checked>
|
||||
<label class="form-check-label fw-semibold text-dark" for="mnoMtn">MTN Ghana</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline me-4">
|
||||
<input class="form-check-input" type="checkbox" id="mnoTelecel" name="networks[]" value="telecel" checked>
|
||||
<label class="form-check-label fw-semibold text-dark" for="mnoTelecel">Telecel</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="mnoAt" name="networks[]" value="at" checked>
|
||||
<label class="form-check-label fw-semibold text-dark" for="mnoAt">AT</label>
|
||||
</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="btnSubmitSender">
|
||||
Submit Registration
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
const senderModal = new bootstrap.Modal(document.getElementById('senderModal'));
|
||||
const $form = $('#senderForm');
|
||||
|
||||
// Force Uppercase and trim spaces on Sender ID input
|
||||
$('#senderName').on('input', function() {
|
||||
$(this).val($(this).val().toUpperCase().replace(/\s/g, ''));
|
||||
});
|
||||
|
||||
// --- OPEN MODAL FOR CREATE ---
|
||||
$('#btnOpenSenderModal').on('click', function() {
|
||||
$form[0].reset();
|
||||
$('#senderRecordId').val('');
|
||||
|
||||
$('#senderModalTitle').text('Request Sender ID');
|
||||
$('#btnSubmitSender').html('<i class="bi bi-send me-2"></i>Submit Registration');
|
||||
|
||||
senderModal.show();
|
||||
});
|
||||
|
||||
// --- OPEN MODAL FOR EDIT ---
|
||||
$('.btn-edit-sender').on('click', function() {
|
||||
const data = $(this).data();
|
||||
|
||||
$form[0].reset();
|
||||
$('#senderRecordId').val(data.id);
|
||||
|
||||
$('#senderName').val(data.sender);
|
||||
$('#senderType').val(data.type);
|
||||
$('#senderClient').val(data.client);
|
||||
$('#senderPurpose').val(data.purpose);
|
||||
|
||||
$('#senderModalTitle').text('Edit Sender ID: ' + data.sender);
|
||||
$('#btnSubmitSender').html('<i class="bi bi-save me-2"></i>Update Request');
|
||||
|
||||
senderModal.show();
|
||||
});
|
||||
|
||||
// --- HANDLE FORM SUBMISSION ---
|
||||
$form.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const $btn = $('#btnSubmitSender');
|
||||
const originalText = $btn.html();
|
||||
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2"></span> Processing...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
setTimeout(() => {
|
||||
const formData = $(this).serializeArray();
|
||||
console.log('Sender ID Request Payload:', formData);
|
||||
|
||||
$btn.html(originalText).prop('disabled', false);
|
||||
senderModal.hide();
|
||||
alert('Sender ID request saved and queued for MNO submission.');
|
||||
}, 800);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
359
resources/views/shortcodes/index.blade.php
Normal file
359
resources/views/shortcodes/index.blade.php
Normal file
@@ -0,0 +1,359 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'Nexus ERP - Short Codes')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.network-badge { font-size: 0.65rem; padding: 0.2rem 0.4rem; border-radius: 4px; border: 1px solid #e2e8f0; font-weight: 600; display: inline-flex; align-items: center; gap: 3px; }
|
||||
.net-approved { background-color: rgba(16, 185, 129, 0.1); color: #10b981; border-color: rgba(16, 185, 129, 0.2); }
|
||||
.net-pending { background-color: rgba(245, 158, 11, 0.1); color: #f59e0b; border-color: rgba(245, 158, 11, 0.2); }
|
||||
|
||||
.code-text { font-family: 'Courier New', Courier, monospace; font-size: 1.2rem; font-weight: 700; color: #111425; letter-spacing: 1px; }
|
||||
|
||||
.cat-badge { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 6px; margin-right: 10px; font-size: 1rem; }
|
||||
.cat-sms { background-color: rgba(59, 130, 246, 0.1); color: #3b82f6; }
|
||||
.cat-ussd { background-color: rgba(139, 92, 246, 0.1); color: #8b5cf6; }
|
||||
.cat-voice { background-color: rgba(16, 185, 129, 0.1); color: #10b981; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@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="#" class="text-secondary text-decoration-none me-2" style="font-size: 0.95rem;">Operations</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;">Short Codes</span>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<!-- Page Header -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">Short Code Management</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Provision and manage dedicated/shared codes for SMS, USSD, and Voice routing.</p>
|
||||
</div>
|
||||
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenCodeModal">
|
||||
<i class="bi bi-plus-lg me-2"></i> Provision Short Code
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- KPIs -->
|
||||
<div class="row g-4 mb-4">
|
||||
<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: #4b5563 !important;">
|
||||
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">TOTAL CODES</div>
|
||||
<h3 class="fw-bold mb-0">34</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: #3b82f6 !important;">
|
||||
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">ACTIVE SMS CODES</div>
|
||||
<h3 class="fw-bold mb-0">18</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: #8b5cf6 !important;">
|
||||
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">ACTIVE USSD CODES</div>
|
||||
<h3 class="fw-bold mb-0">12</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: #10b981 !important;">
|
||||
<div class="text-secondary fw-bold mb-1" style="font-size: 0.75rem; letter-spacing: 0.5px;">ACTIVE VOICE CODES</div>
|
||||
<h3 class="fw-bold mb-0">4</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data Table -->
|
||||
<div class="content-card">
|
||||
<div class="p-3 border-bottom bg-light bg-opacity-50">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<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 by code or client...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">All Categories</option>
|
||||
<option value="sms">SMS Only</option>
|
||||
<option value="ussd">USSD</option>
|
||||
<option value="voice">Voice / IVR</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select bg-white">
|
||||
<option value="">Billing: All</option>
|
||||
<option value="standard">Standard Rated</option>
|
||||
<option value="reverse">Reverse Billed (Toll-Free)</option>
|
||||
<option value="premium">Premium Rated</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-secondary w-100">Filter</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-custom table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Short Code</th>
|
||||
<th>Category</th>
|
||||
<th>Client / Assignment</th>
|
||||
<th>Billing Type</th>
|
||||
<th>Network Provisioning</th>
|
||||
<th class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Row 1: SMS -->
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="cat-badge cat-sms"><i class="bi bi-chat-text-fill"></i></div>
|
||||
<div>
|
||||
<div class="code-text">1334</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.75rem;">Dedicated</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="fw-semibold text-dark">SMS</span></td>
|
||||
<td>
|
||||
<div class="fw-semibold" style="font-size: 0.85rem;">Click Tech Corp</div>
|
||||
<div class="text-secondary text-truncate" style="font-size: 0.75rem; max-width: 150px;" title="https://api.clicktech.com/webhook/sms">https://api.clicktech.com/...</div>
|
||||
</td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary border">Standard</span></td>
|
||||
<td>
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> MTN</span>
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> Telecel</span>
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> AT</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-code"
|
||||
data-id="1" data-code="1334" data-category="sms" data-type="dedicated" data-client="client_1" data-billing="standard" data-webhook="https://api.clicktech.com/webhook/sms">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 2: USSD -->
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="cat-badge cat-ussd"><i class="bi bi-phone-fill"></i></div>
|
||||
<div>
|
||||
<div class="code-text">*711*50#</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.75rem;">Extension (Shared)</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="fw-semibold text-dark">USSD</span></td>
|
||||
<td>
|
||||
<div class="fw-semibold" style="font-size: 0.85rem;">Alpha Telecom</div>
|
||||
<div class="text-secondary text-truncate" style="font-size: 0.75rem; max-width: 150px;" title="https://ussd.alphatel.com/callback">https://ussd.alphatel.com/...</div>
|
||||
</td>
|
||||
<td><span class="badge bg-danger bg-opacity-10 text-danger border border-danger-subtle">Reverse Billed</span></td>
|
||||
<td>
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> MTN</span>
|
||||
<span class="network-badge net-pending"><i class="bi bi-clock-fill"></i> Telecel</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-code"
|
||||
data-id="2" data-code="*711*50#" data-category="ussd" data-type="shared" data-client="client_2" data-billing="reverse" data-webhook="https://ussd.alphatel.com/callback">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 3: Voice -->
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="cat-badge cat-voice"><i class="bi bi-mic-fill"></i></div>
|
||||
<div>
|
||||
<div class="code-text">3001</div>
|
||||
<div class="text-secondary mt-1" style="font-size: 0.75rem;">Dedicated IVR</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="fw-semibold text-dark">Voice</span></td>
|
||||
<td>
|
||||
<div class="fw-semibold" style="font-size: 0.85rem;">Internal Customer Service</div>
|
||||
<div class="text-secondary text-truncate" style="font-size: 0.75rem; max-width: 150px;">SIP: trunk.nexus.local</div>
|
||||
</td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary border">Standard</span></td>
|
||||
<td>
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<span class="network-badge net-approved"><i class="bi bi-check-circle-fill"></i> MTN</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light text-primary me-1 btn-edit-code"
|
||||
data-id="3" data-code="3001" data-category="voice" data-type="dedicated" data-client="internal" data-billing="standard" data-webhook="SIP: trunk.nexus.local">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('modals')
|
||||
<!-- SHORT CODE MODAL -->
|
||||
<div class="modal fade" id="codeModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title fw-bold" id="codeModalTitle">Provision Short Code</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<form id="codeForm">
|
||||
<div class="modal-body p-4">
|
||||
<input type="hidden" id="recordId" name="id">
|
||||
|
||||
<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;">Short Code Number *</label>
|
||||
<input type="text" class="form-control fw-bold" id="codeNumber" name="code_number" required placeholder="e.g. 1334 or *711#">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Service Category *</label>
|
||||
<select class="form-select" id="codeCategory" name="category" required>
|
||||
<option value="" selected disabled>Select Category...</option>
|
||||
<option value="sms">SMS</option>
|
||||
<option value="ussd">USSD</option>
|
||||
<option value="voice">Voice / IVR</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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;">Setup Type</label>
|
||||
<select class="form-select" id="codeType" name="setup_type">
|
||||
<option value="dedicated">Dedicated</option>
|
||||
<option value="shared">Shared (Keyword/Extension)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Billing Model</label>
|
||||
<select class="form-select" id="codeBilling" name="billing_type">
|
||||
<option value="standard">Standard Rated</option>
|
||||
<option value="reverse">Reverse Billed (Toll-Free)</option>
|
||||
<option value="premium">Premium Rated</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Assigned Client *</label>
|
||||
<select class="form-select" id="codeClient" name="client_id" required>
|
||||
<option value="internal">Internal System</option>
|
||||
<option value="client_1">Click Tech Corp</option>
|
||||
<option value="client_2">Alpha Telecom</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Callback URL / Webhook Endpoint</label>
|
||||
<input type="text" class="form-control" id="codeWebhook" name="webhook_url" placeholder="https://api.client.com/receive">
|
||||
<div class="form-text">Where incoming payloads (MO messages, USSD sessions, SIP invites) should be routed.</div>
|
||||
</div>
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">MNO Routing Map</h6>
|
||||
<div class="p-3 bg-light rounded border border-secondary-subtle">
|
||||
<div class="form-check form-check-inline me-4">
|
||||
<input class="form-check-input" type="checkbox" id="routeMtn" name="routing[]" value="mtn" checked>
|
||||
<label class="form-check-label fw-semibold text-dark" for="routeMtn">MTN Ghana</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline me-4">
|
||||
<input class="form-check-input" type="checkbox" id="routeTelecel" name="routing[]" value="telecel" checked>
|
||||
<label class="form-check-label fw-semibold text-dark" for="routeTelecel">Telecel</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="routeAt" name="routing[]" value="at" checked>
|
||||
<label class="form-check-label fw-semibold text-dark" for="routeAt">AT</label>
|
||||
</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="btnSubmitCode">
|
||||
Save Configuration
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
const codeModal = new bootstrap.Modal(document.getElementById('codeModal'));
|
||||
const $form = $('#codeForm');
|
||||
|
||||
// --- OPEN MODAL FOR CREATE ---
|
||||
$('#btnOpenCodeModal').on('click', function() {
|
||||
$form[0].reset();
|
||||
$('#recordId').val('');
|
||||
|
||||
$('#codeModalTitle').text('Provision New Short Code');
|
||||
$('#btnSubmitCode').html('<i class="bi bi-save me-2"></i>Save Configuration');
|
||||
|
||||
codeModal.show();
|
||||
});
|
||||
|
||||
// --- OPEN MODAL FOR EDIT ---
|
||||
$('.btn-edit-code').on('click', function() {
|
||||
const data = $(this).data();
|
||||
|
||||
$form[0].reset();
|
||||
$('#recordId').val(data.id);
|
||||
|
||||
$('#codeNumber').val(data.code);
|
||||
$('#codeCategory').val(data.category);
|
||||
$('#codeType').val(data.type);
|
||||
$('#codeClient').val(data.client);
|
||||
$('#codeBilling').val(data.billing);
|
||||
$('#codeWebhook').val(data.webhook);
|
||||
|
||||
$('#codeModalTitle').text('Edit Route: ' + data.code);
|
||||
$('#btnSubmitCode').html('<i class="bi bi-check-circle me-2"></i>Update Route');
|
||||
|
||||
codeModal.show();
|
||||
});
|
||||
|
||||
// --- HANDLE FORM SUBMISSION ---
|
||||
$form.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const $btn = $('#btnSubmitCode');
|
||||
const originalText = $btn.html();
|
||||
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2"></span> Provisioning...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
setTimeout(() => {
|
||||
const formData = $(this).serializeArray();
|
||||
console.log('Short Code Payload:', formData);
|
||||
|
||||
$btn.html(originalText).prop('disabled', false);
|
||||
codeModal.hide();
|
||||
alert('Short code configuration applied to gateway successfully.');
|
||||
}, 800);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
375
resources/views/staff/index.blade.php
Normal file
375
resources/views/staff/index.blade.php
Normal file
@@ -0,0 +1,375 @@
|
||||
@extends('layouts.masterbeta')
|
||||
|
||||
@section('title', 'CML ERP - Staff Directory')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
/* Staff Card Specific Styling */
|
||||
.staff-card {
|
||||
background: #fff;
|
||||
border: 1px solid #eaedf1;
|
||||
border-radius: 12px;
|
||||
transition: all 0.2s ease-in-out;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.staff-card:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 15px rgba(0,0,0,0.05);
|
||||
border-color: #d1d5db;
|
||||
}
|
||||
|
||||
/* The decorative colored top border */
|
||||
.card-top-bar {
|
||||
height: 4px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.dept-engineering { background-color: #5c4df0; }
|
||||
.dept-sales { background-color: #10b981; }
|
||||
.dept-support { background-color: #f59e0b; }
|
||||
|
||||
.staff-avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 12px;
|
||||
object-fit: cover;
|
||||
background-color: #f8f9fc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: #5c4df0;
|
||||
}
|
||||
|
||||
.contact-row {
|
||||
font-size: 0.85rem;
|
||||
padding: 0.4rem 0;
|
||||
border-bottom: 1px solid #f8f9fc;
|
||||
}
|
||||
.contact-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@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="#" class="text-secondary text-decoration-none me-2" style="font-size: 0.95rem;">Core Entities</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;">Staff Directory</span>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">Staff Directory</h4>
|
||||
<p class="text-secondary mb-0" style="font-size: 0.9rem;">Manage employee profiles, department roles, and system access.</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-outline-secondary d-flex align-items-center" style="border-radius: 8px;">
|
||||
<i class="bi bi-diagram-3 me-2"></i> Org Chart
|
||||
</button>
|
||||
<button class="btn text-white fw-bold d-flex align-items-center" style="background-color: #5c4df0; border-radius: 8px;" id="btnOpenStaffModal">
|
||||
<i class="bi bi-person-plus me-2"></i> Add Employee
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-card p-3 mb-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-5">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-transparent border-end-0 text-secondary"><i class="bi bi-search"></i></span>
|
||||
<input type="text" class="form-control border-start-0 ps-0" placeholder="Search by name, role, or extension...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select">
|
||||
<option value="">All Departments</option>
|
||||
<option value="engineering">Engineering & IT</option>
|
||||
<option value="sales">Sales & Accounts</option>
|
||||
<option value="support">Technical Support</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select class="form-select">
|
||||
<option value="active">Active</option>
|
||||
<option value="on-leave">On Leave</option>
|
||||
<option value="inactive">Inactive</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-secondary w-100" style="border-radius: 8px;">Filter</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
|
||||
<div class="col-xl-3 col-lg-4 col-md-6">
|
||||
<div class="staff-card p-4 h-100">
|
||||
<div class="card-top-bar dept-engineering"></div>
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="staff-avatar bg-primary bg-opacity-10 me-3">AD</div>
|
||||
<div>
|
||||
<h6 class="fw-bold mb-1 text-dark">Admin Desk</h6>
|
||||
<span class="badge bg-primary bg-opacity-10 text-primary border border-primary-subtle px-2 py-1" style="font-size: 0.7rem;">Systems Admin</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="contact-row d-flex justify-content-between align-items-center">
|
||||
<span class="text-secondary"><i class="bi bi-buildings me-2"></i>Engineering</span>
|
||||
<span class="badge bg-success bg-opacity-10 text-success" style="font-size: 0.65rem;">ACTIVE</span>
|
||||
</div>
|
||||
<div class="contact-row d-flex justify-content-between align-items-center">
|
||||
<span class="text-secondary"><i class="bi bi-envelope me-2"></i>admin@nexus.io</span>
|
||||
<a href="mailto:admin@nexus.io" class="text-secondary hover-primary"><i class="bi bi-box-arrow-up-right" style="font-size: 0.7rem;"></i></a>
|
||||
</div>
|
||||
<div class="contact-row d-flex align-items-center">
|
||||
<span class="text-secondary"><i class="bi bi-telephone me-2"></i>Ext: 1001</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2 mt-auto pt-2 border-top">
|
||||
<button class="btn btn-sm btn-light text-secondary flex-grow-1 fw-semibold btn-edit-staff"
|
||||
data-id="1" data-name="Admin Desk" data-email="admin@nexus.io" data-ext="1001" data-role="Systems Admin" data-dept="engineering" data-status="active">
|
||||
<i class="bi bi-pencil me-1"></i> Edit
|
||||
</button>
|
||||
<button class="btn btn-sm btn-light text-secondary flex-grow-1 fw-semibold">
|
||||
<i class="bi bi-shield-lock me-1"></i> Access
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-lg-4 col-md-6">
|
||||
<div class="staff-card p-4 h-100">
|
||||
<div class="card-top-bar dept-sales"></div>
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="staff-avatar bg-success bg-opacity-10 text-success me-3">MO</div>
|
||||
<div>
|
||||
<h6 class="fw-bold mb-1 text-dark">Mansa Olympio</h6>
|
||||
<span class="badge bg-success bg-opacity-10 text-success border border-success-subtle px-2 py-1" style="font-size: 0.7rem;">Account Executive</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="contact-row d-flex justify-content-between align-items-center">
|
||||
<span class="text-secondary"><i class="bi bi-buildings me-2"></i>Sales</span>
|
||||
<span class="badge bg-success bg-opacity-10 text-success" style="font-size: 0.65rem;">ACTIVE</span>
|
||||
</div>
|
||||
<div class="contact-row d-flex justify-content-between align-items-center">
|
||||
<span class="text-secondary text-truncate" style="max-width: 150px;"><i class="bi bi-envelope me-2"></i>m.osei@nexus.io</span>
|
||||
<a href="mailto:m.osei@nexus.io" class="text-secondary hover-primary"><i class="bi bi-box-arrow-up-right" style="font-size: 0.7rem;"></i></a>
|
||||
</div>
|
||||
<div class="contact-row d-flex align-items-center">
|
||||
<span class="text-secondary"><i class="bi bi-telephone me-2"></i>Ext: 1045</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2 mt-auto pt-2 border-top">
|
||||
<button class="btn btn-sm btn-light text-secondary flex-grow-1 fw-semibold btn-edit-staff"
|
||||
data-id="2" data-name="Michael Osei" data-email="m.osei@nexus.io" data-ext="1045" data-role="Account Executive" data-dept="sales" data-status="active">
|
||||
<i class="bi bi-pencil me-1"></i> Edit
|
||||
</button>
|
||||
<button class="btn btn-sm btn-light text-secondary flex-grow-1 fw-semibold">
|
||||
<i class="bi bi-shield-lock me-1"></i> Access
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-lg-4 col-md-6">
|
||||
<div class="staff-card p-4 h-100">
|
||||
<div class="card-top-bar dept-support"></div>
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<img src="https://ui-avatars.com/api/?name=David+Kumwenda&background=f59e0b&color=fff" class="staff-avatar me-3" alt="David Kumwenda">
|
||||
<div>
|
||||
<h6 class="fw-bold mb-1 text-dark">David Kumwenda</h6>
|
||||
<span class="badge bg-warning bg-opacity-10 text-dark border border-warning-subtle px-2 py-1" style="font-size: 0.7rem;">Software Developer</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="contact-row d-flex justify-content-between align-items-center">
|
||||
<span class="text-secondary"><i class="bi bi-buildings me-2"></i>Tech</span>
|
||||
<span class="badge bg-secondary bg-opacity-10 text-secondary" style="font-size: 0.65rem;">ON LEAVE</span>
|
||||
</div>
|
||||
<div class="contact-row d-flex justify-content-between align-items-center">
|
||||
<span class="text-secondary text-truncate" style="max-width: 150px;"><i class="bi bi-envelope me-2"></i>s.mensah@nexus.io</span>
|
||||
<a href="mailto:s.mensah@nexus.io" class="text-secondary hover-primary"><i class="bi bi-box-arrow-up-right" style="font-size: 0.7rem;"></i></a>
|
||||
</div>
|
||||
<div class="contact-row d-flex align-items-center">
|
||||
<span class="text-secondary"><i class="bi bi-telephone me-2"></i>Ext: 1022</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2 mt-auto pt-2 border-top">
|
||||
<button class="btn btn-sm btn-light text-secondary flex-grow-1 fw-semibold btn-edit-staff"
|
||||
data-id="3" data-name="Sarah Mensah" data-email="s.mensah@nexus.io" data-ext="1022" data-role="VoIP Specialist" data-dept="support" data-status="on-leave">
|
||||
<i class="bi bi-pencil me-1"></i> Edit
|
||||
</button>
|
||||
<button class="btn btn-sm btn-light text-secondary flex-grow-1 fw-semibold">
|
||||
<i class="bi bi-shield-lock me-1"></i> Access
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('modals')
|
||||
<div class="modal fade" id="staffModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content" style="border-radius: 12px; border: none;">
|
||||
<div class="modal-header bg-light" style="border-radius: 12px 12px 0 0;">
|
||||
<h5 class="modal-title fw-bold" id="staffModalTitle">Add New Employee</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<form id="staffForm" enctype="multipart/form-data">
|
||||
<div class="modal-body p-4">
|
||||
<input type="hidden" id="staffId" name="id">
|
||||
<input type="hidden" id="staffMethod" name="_method" value="POST">
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3 text-center border-end pe-4">
|
||||
<div class="staff-avatar mx-auto mb-3" style="width: 100px; height: 100px; font-size: 2rem;" id="avatarPreview">
|
||||
<i class="bi bi-person text-secondary"></i>
|
||||
</div>
|
||||
<label for="staffPhoto" class="btn btn-sm btn-outline-secondary w-100">Upload Photo</label>
|
||||
<input type="file" id="staffPhoto" name="photo" class="d-none" accept="image/*">
|
||||
</div>
|
||||
|
||||
<div class="col-md-9 ps-4">
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Identity</h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Full Name *</label>
|
||||
<input type="text" class="form-control" id="staffName" name="name" required placeholder="Jane Doe">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Job Title *</label>
|
||||
<input type="text" class="form-control" id="staffRole" name="role" required placeholder="e.g. Network Engineer">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Email Address *</label>
|
||||
<input type="email" class="form-control" id="staffEmail" name="email" required placeholder="jane@nexus.io">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">PBX Extension</label>
|
||||
<input type="text" class="form-control" id="staffExt" name="extension" placeholder="e.g. 1010">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="text-secondary opacity-25">
|
||||
|
||||
<h6 class="fw-bold mb-3 text-secondary text-uppercase" style="font-size: 0.75rem;">Organizational Assignment</h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Department</label>
|
||||
<select class="form-select" id="staffDept" name="department_id">
|
||||
<option value="engineering">Engineering & IT</option>
|
||||
<option value="sales">Sales & Accounts</option>
|
||||
<option value="support">Technical Support</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-secondary fw-semibold" style="font-size: 0.85rem;">Status</label>
|
||||
<select class="form-select" id="staffStatus" name="status">
|
||||
<option value="active">Active</option>
|
||||
<option value="on-leave">On Leave</option>
|
||||
<option value="inactive">Inactive</option>
|
||||
</select>
|
||||
</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="btnSubmitStaff">
|
||||
Save Employee
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
const staffModal = new bootstrap.Modal(document.getElementById('staffModal'));
|
||||
const $form = $('#staffForm');
|
||||
|
||||
// --- OPEN MODAL FOR CREATE ---
|
||||
$('#btnOpenStaffModal').on('click', function() {
|
||||
$form[0].reset();
|
||||
$('#staffId').val('');
|
||||
$('#staffMethod').val('POST');
|
||||
$('#staffModalTitle').text('Add New Employee');
|
||||
$('#btnSubmitStaff').html('<i class="bi bi-save me-2"></i>Save Employee');
|
||||
$('#avatarPreview').html('<i class="bi bi-person text-secondary"></i>');
|
||||
staffModal.show();
|
||||
});
|
||||
|
||||
// --- OPEN MODAL FOR EDIT ---
|
||||
$('.btn-edit-staff').on('click', function() {
|
||||
const data = $(this).data();
|
||||
|
||||
$form[0].reset();
|
||||
$('#staffId').val(data.id);
|
||||
$('#staffMethod').val('PUT');
|
||||
|
||||
$('#staffName').val(data.name);
|
||||
$('#staffRole').val(data.role);
|
||||
$('#staffEmail').val(data.email);
|
||||
$('#staffExt').val(data.ext);
|
||||
$('#staffDept').val(data.dept);
|
||||
$('#staffStatus').val(data.status);
|
||||
|
||||
// Show initials in preview for demo purposes
|
||||
const initials = data.name.split(' ').map(n => n[0]).join('').substring(0,2);
|
||||
$('#avatarPreview').html(initials).addClass('bg-primary bg-opacity-10 text-primary');
|
||||
|
||||
$('#staffModalTitle').text('Edit Employee: ' + data.name);
|
||||
$('#btnSubmitStaff').html('<i class="bi bi-check-circle me-2"></i>Update Employee');
|
||||
|
||||
staffModal.show();
|
||||
});
|
||||
|
||||
// --- HANDLE FORM SUBMISSION ---
|
||||
$form.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const $btn = $('#btnSubmitStaff');
|
||||
const originalText = $btn.html();
|
||||
|
||||
$btn.html('<span class="spinner-border spinner-border-sm me-2"></span> Saving...');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
// Use FormData to allow file uploads (profile picture)
|
||||
let formData = new FormData(this);
|
||||
|
||||
// Simulate AJAX Request
|
||||
setTimeout(() => {
|
||||
console.log('Staff Data Saved');
|
||||
$btn.html(originalText).prop('disabled', false);
|
||||
staffModal.hide();
|
||||
alert('Employee record saved successfully!');
|
||||
}, 800);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
204
resources/views/test.blade.php
Normal file
204
resources/views/test.blade.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>ERP Dashboard</title>
|
||||
<link rel="stylesheet" href="{{ url('public/june_assets/css/bootstrap.min.css') }}">
|
||||
</head>
|
||||
<body class="bg-body-tertiary">
|
||||
<nav class="navbar navbar-expand-lg bg-body border-bottom sticky-top">
|
||||
<div class="container-fluid">
|
||||
<button class="btn btn-outline-secondary d-lg-none me-2" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebar" aria-controls="sidebar">
|
||||
Menu
|
||||
</button>
|
||||
<a class="navbar-brand fw-semibold" href="index.html">ERP</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#topbar" aria-controls="topbar" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="topbar">
|
||||
<form class="d-flex ms-lg-4 my-3 my-lg-0 w-100" role="search">
|
||||
<input class="form-control" type="search" placeholder="Search records" aria-label="Search">
|
||||
</form>
|
||||
<div class="dropdown ms-lg-3">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
Admin
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="blank.html">General page</a></li>
|
||||
<li><a class="dropdown-item" href="#">Settings</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="#">Sign out</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<aside class="col-lg-2 d-none d-lg-block bg-body border-end min-vh-100 p-3">
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action active" href="index.html">Dashboard</a>
|
||||
<a class="list-group-item list-group-item-action" href="blank.html">General Page</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Customers</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Invoices</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Reports</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Settings</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="offcanvas offcanvas-start d-lg-none" tabindex="-1" id="sidebar" aria-labelledby="sidebarLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="sidebarLabel">ERP</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action active" href="index.html">Dashboard</a>
|
||||
<a class="list-group-item list-group-item-action" href="blank.html">General Page</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Customers</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Invoices</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Reports</a>
|
||||
<a class="list-group-item list-group-item-action" href="#">Settings</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="col-lg-10 p-4">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between gap-3 mb-4">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Dashboard</h1>
|
||||
<p class="text-secondary mb-0">Business overview and recent activity</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-outline-secondary" type="button">Export</button>
|
||||
<button class="btn btn-primary" type="button">New Record</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-secondary mb-1">Revenue</p>
|
||||
<h2 class="h4 mb-1">GHS 128,400</h2>
|
||||
<span class="badge text-bg-success">Up 12%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-secondary mb-1">Orders</p>
|
||||
<h2 class="h4 mb-1">1,284</h2>
|
||||
<span class="badge text-bg-primary">Today</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-secondary mb-1">Pending</p>
|
||||
<h2 class="h4 mb-1">38</h2>
|
||||
<span class="badge text-bg-warning">Review</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-secondary mb-1">Customers</p>
|
||||
<h2 class="h4 mb-1">864</h2>
|
||||
<span class="badge text-bg-info">Active</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-xl-8">
|
||||
<div class="card">
|
||||
<div class="card-header bg-body d-flex justify-content-between align-items-center">
|
||||
<h2 class="h5 mb-0">Recent Transactions</h2>
|
||||
<a class="btn btn-sm btn-outline-primary" href="#">View all</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th scope="col">Reference</th>
|
||||
<th scope="col">Customer</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col" class="text-end">Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>INV-1024</td>
|
||||
<td>North Ridge Ltd</td>
|
||||
<td><span class="badge text-bg-success">Paid</span></td>
|
||||
<td class="text-end">GHS 12,000</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INV-1025</td>
|
||||
<td>Adenta Stores</td>
|
||||
<td><span class="badge text-bg-warning">Pending</span></td>
|
||||
<td class="text-end">GHS 4,850</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INV-1026</td>
|
||||
<td>Osu Supplies</td>
|
||||
<td><span class="badge text-bg-secondary">Draft</span></td>
|
||||
<td class="text-end">GHS 9,300</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INV-1027</td>
|
||||
<td>Labone Foods</td>
|
||||
<td><span class="badge text-bg-success">Paid</span></td>
|
||||
<td class="text-end">GHS 7,600</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-body">
|
||||
<h2 class="h5 mb-0">Tasks</h2>
|
||||
</div>
|
||||
<div class="list-group list-group-flush">
|
||||
<label class="list-group-item d-flex gap-3">
|
||||
<input class="form-check-input flex-shrink-0" type="checkbox" value="">
|
||||
<span>Approve purchase requests</span>
|
||||
</label>
|
||||
<label class="list-group-item d-flex gap-3">
|
||||
<input class="form-check-input flex-shrink-0" type="checkbox" value="">
|
||||
<span>Review pending invoices</span>
|
||||
</label>
|
||||
<label class="list-group-item d-flex gap-3">
|
||||
<input class="form-check-input flex-shrink-0" type="checkbox" value="">
|
||||
<span>Send stock report</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h2 class="h5">Monthly Target</h2>
|
||||
<p class="text-secondary">Current progress toward the sales target.</p>
|
||||
<div class="progress" role="progressbar" aria-label="Monthly target" aria-valuenow="72" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress-bar" style="width: 72%">72%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script src="{{ url('public/june_assets/js/bootstrap_bundle.min.js') }}" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
176
resources/views/welcome.blade.php
Normal file
176
resources/views/welcome.blade.php
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user