590 lines
18 KiB
PHP
590 lines
18 KiB
PHP
@extends('theme::layouts.app')
|
|
|
|
@section('style')
|
|
<style>
|
|
#userAccessLogsListTable_wrapper {
|
|
border: 2px solid #D6DEE9 !important;
|
|
box-shadow: none !important;
|
|
margin-bottom: 30px;
|
|
}
|
|
#userAccessLogsListTable_wrapper tbody tr {
|
|
background-color: #D6DEE9;
|
|
color: #364257;
|
|
}
|
|
</style>
|
|
@endsection
|
|
|
|
@section('content')
|
|
|
|
<h2 class="dashboard-title">{{ __("CRM") }}</h2>
|
|
<form class="search-fields flex" action="#" id="searchFrm">
|
|
<div class="search-field d-flex align-items-center">
|
|
<label class="label-field mr-2" style="white-space: nowrap;">
|
|
{{ __("Company") }}
|
|
</label>
|
|
<input type="text" class="w-100" id="search_company_name">
|
|
</div>
|
|
<div class="search-field d-flex align-items-center">
|
|
<label class="label-field mr-2" style="white-space: nowrap;">
|
|
{{ __("First name") }}
|
|
</label>
|
|
<input type="text" class="w-100" id="search_first_name">
|
|
</div>
|
|
<div class="search-field d-flex align-items-center">
|
|
<label class="label-field mr-2" style="white-space: nowrap;">
|
|
{{ __("Last name") }}
|
|
</label>
|
|
<input type="text" class="w-100" id="search_last_name">
|
|
</div>
|
|
<div class="search-field d-flex align-items-center">
|
|
<label class="label-field mr-2" style="white-space: nowrap;">
|
|
{{ __("Phone number") }}
|
|
</label>
|
|
<input type="text" class="w-100" id="search_phone">
|
|
</div>
|
|
<div class="search-field width-auto">
|
|
<button type="submit" class="btn primary-button btn-normal">{{ __("Search") }}</button>
|
|
</div>
|
|
</form>
|
|
|
|
<table id="crmTable" class="">
|
|
<thead>
|
|
<tr>
|
|
<td>{{ __("Company") }}</td>
|
|
<td>{{ __("First name") }}</td>
|
|
<td>{{ __("Last name") }}</td>
|
|
<td>{{ __("Phone number") }}</td>
|
|
<td>{{ __("Access level") }}</td>
|
|
<td>{{ __("Status") }}</td>
|
|
<td>{{ __("Action") }}</td>
|
|
</tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
|
|
{{-- Modals --}}
|
|
{{-- Edit User Modal --}}
|
|
<div class="modal fade custom-modal" id="editUserModal" tabindex="-1" aria-labelledby="editUserModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-xl modal-dialog-centered">
|
|
<div class="modal-content mx-auto">
|
|
<div class="modal-body p-0">
|
|
<p class="modal-title">{{ __("User Detail") }}</p>
|
|
|
|
<form action="#" class="theme-form" id="editUserFrm">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("First name") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<input type="text" class="form-control" value="" name="first_name" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("Current Password") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<input type="password" class="form-control" value="" name="current_password">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("Last name") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<input type="text" class="form-control" value="" name="last_name" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("Password") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<div class="password-wrapper">
|
|
<input type="password" class="form-control" value="" name="password">
|
|
<img class="mx-auto password-hide-show" src="{{ asset('themes/tailwind/images/password-hide-show.png') }}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("Phone") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<input type="text" class="form-control" value="" name="phone" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("Confirm Password") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<div class="password-wrapper">
|
|
<input type="password" class="form-control" value="" name="password_confirmation">
|
|
<img class="mx-auto password-hide-show" src="{{ asset('themes/tailwind/images/password-hide-show.png') }}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("Email") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<input type="email" class="form-control" value="" name="email" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto">
|
|
<label class="col-form-label">{{ __("Access Level") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<select class="w-100" name="role_id" required>
|
|
<option value="" disabled selected>{{ __("Select an option") }}</option>
|
|
@foreach ($roles as $role)
|
|
<option value="{{ $role->id }}">{{ $role->display_name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-5 align-items-center">
|
|
<div class="col-auto" required>
|
|
<label class="col-form-label">{{ __("Status") }}</label>
|
|
</div>
|
|
<div class="col">
|
|
<select class="w-100" name="status">
|
|
<option value="active" selected>{{ __("Active") }}</option>
|
|
<option value="inactive">{{ __("Inactive") }}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex align-items-center justify-content-center">
|
|
<button type="submit" class="btn green-btn mx-3">{{ __("Save") }}</button>
|
|
<button type="button" class="btn red-btn mx-3" data-bs-dismiss="modal">{{ __("Cancel") }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{-- User Action Logs Modal --}}
|
|
<div class="modal fade custom-modal" id="userActionLogsModal" tabindex="-1" aria-labelledby="userActionLogsModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-xl modal-dialog-centered">
|
|
<div class="modal-content mx-auto">
|
|
<div class="modal-body p-0">
|
|
<p class="modal-title mb-4">{{ __("User Log") }}</p>
|
|
|
|
<table id="userAccessLogsListTable" class="">
|
|
<thead>
|
|
<tr>
|
|
<td>{{ __("Date") }}</td>
|
|
<td>{{ __("Time") }}</td>
|
|
<td>{{ __("Event") }}</td>
|
|
<td>{{ __("Description") }}</td>
|
|
<td>{{ __("Status") }}</td>
|
|
</tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
|
|
<div class="d-flex align-items-center justify-content-center">
|
|
<button type="button" class="btn red-btn mx-3" data-bs-dismiss="modal">{{ __("Back") }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{-- Saved Success Modal --}}
|
|
<div class="modal fade validation-modal style2" id="validationModal" tabindex="-1" aria-labelledby="validationModal1Label" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content mx-auto">
|
|
<div class="modal-body p-0">
|
|
<p class="text-center error-message">{{ __("All changes have been saved!") }}</p>
|
|
<button type="button" class="btn br-0" data-bs-dismiss="modal">{{ __("Back") }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@endsection
|
|
|
|
@section('script')
|
|
<script>
|
|
$(document).ready( function () {
|
|
$.ajaxSetup({
|
|
headers: {
|
|
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
|
}
|
|
});
|
|
|
|
var userListTableColumns = [
|
|
('{{ strtolower(app()->getLocale()) }}' == 'zh_hk' ? {data: 'name_chinese', name: 'companies.name_chinese'} : {data: 'name_english', name: 'companies.name_english'}),
|
|
{data: 'first_name', name: 'users.first_name'},
|
|
{data: 'last_name', name: 'users.last_name'},
|
|
{data: 'phone', name: 'users.phone'},
|
|
{data: 'display_name', name: 'roles.display_name'},
|
|
{data: 'status', name: 'users.status'},
|
|
{data: 'actions', name: 'actions', searchable: false, sortable: false}
|
|
];
|
|
var userListTable = $("#crmTable").DataTable({
|
|
processing: true,
|
|
serverSide: true,
|
|
ajax: {
|
|
url: '{{ route("cms.crm.table") }}',
|
|
type: 'post',
|
|
"data": function ( d ) {
|
|
return $.extend( {}, d, {
|
|
"company_name": $('#searchFrm #search_company_name').val(),
|
|
"first_name": $('#searchFrm #search_first_name').val(),
|
|
"last_name": $('#searchFrm #search_last_name').val(),
|
|
"phone": $('#searchFrm #search_phone').val(),
|
|
} );
|
|
},
|
|
"dataSrc": function ( json ) {
|
|
for (var i = 0; i < json.data.length; i++) {
|
|
$.each( json.data[i], function( key, value ) {
|
|
json.data[i][key] = value ? value : '-';
|
|
});
|
|
}
|
|
|
|
return json.data;
|
|
}
|
|
},
|
|
columns: userListTableColumns,
|
|
order: [[0, "asc"]],
|
|
searchDelay: 500,
|
|
"language": {
|
|
"paginate": {
|
|
"next": ">", // Text for the "Next" page button
|
|
"previous": "<" // Text for the "Previous" page button
|
|
},
|
|
"emptyTable": '{{ __("No data available in table") }}'
|
|
// Add more text customizations if needed
|
|
}
|
|
});
|
|
|
|
$('#searchFrm').submit(function(e) {
|
|
e.preventDefault();
|
|
userListTable.ajax.reload();
|
|
});
|
|
|
|
$('.password-hide-show').click(function() {
|
|
var type = $(this).parent().find('input').attr('type');
|
|
|
|
if (type == 'password') {
|
|
$(this).parent().find('input').attr('type', 'text');
|
|
}
|
|
else {
|
|
$(this).parent().find('input').attr('type', 'password');
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.suspend-user', function(e) {
|
|
var action = $(this).attr('data-action');
|
|
|
|
if (action) {
|
|
Swal.fire({
|
|
title: '{{ __("Are you sure?") }}',
|
|
text: `{{ __("You would not be able to revert this!") }}`,
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#3085d6',
|
|
cancelButtonColor: '#d33',
|
|
confirmButtonText: '{{ __("Yes") }}',
|
|
cancelButtonText: '{{ __("Cancel") }}'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$.ajax({
|
|
url: action,
|
|
type: "post",
|
|
data: {},
|
|
dataType: 'json',
|
|
success:function(data) {
|
|
if (data.success) {
|
|
$('#validationModal').modal('show');
|
|
$('#validationModal .error-message').html(data.message);
|
|
|
|
userListTable.ajax.reload();
|
|
}
|
|
},
|
|
error: function(data) {
|
|
var errors = data.responseJSON.errors;
|
|
var errorMessage = '<ul>';
|
|
$.each(errors, function(index, error) {
|
|
console.log(error);
|
|
errorMessage += '<li>' + error[0] + '</li>';
|
|
});
|
|
errorMessage += '</ul>';
|
|
|
|
$('#validationModal .error-message').html(errorMessage);
|
|
$('#validationModal').modal('show');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.activate-user', function(e) {
|
|
var action = $(this).attr('data-action');
|
|
|
|
if (action) {
|
|
Swal.fire({
|
|
title: '{{ __("Are you sure?") }}',
|
|
text: `{{ __("You would not be able to revert this!") }}`,
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#3085d6',
|
|
cancelButtonColor: '#d33',
|
|
confirmButtonText: '{{ __("Yes") }}',
|
|
cancelButtonText: '{{ __("Cancel") }}'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$.ajax({
|
|
url: action,
|
|
type: "post",
|
|
data: {},
|
|
dataType: 'json',
|
|
success:function(data) {
|
|
if (data.success) {
|
|
$('#validationModal').modal('show');
|
|
$('#validationModal .error-message').html(data.message);
|
|
|
|
userListTable.ajax.reload();
|
|
}
|
|
},
|
|
error: function(data) {
|
|
var errors = data.responseJSON.errors;
|
|
var errorMessage = '<ul>';
|
|
$.each(errors, function(index, error) {
|
|
console.log(error);
|
|
errorMessage += '<li>' + error[0] + '</li>';
|
|
});
|
|
errorMessage += '</ul>';
|
|
|
|
$('#validationModal .error-message').html(errorMessage);
|
|
$('#validationModal').modal('show');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.remove-user', function(e) {
|
|
var action = $(this).attr('data-action');
|
|
|
|
if (action) {
|
|
Swal.fire({
|
|
title: '{{ __("Are you sure?") }}',
|
|
text: `{{ __("You would not be able to revert this!") }}`,
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#3085d6',
|
|
cancelButtonColor: '#d33',
|
|
confirmButtonText: '{{ __("Yes") }}',
|
|
cancelButtonText: '{{ __("Cancel") }}'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$.ajax({
|
|
url: action,
|
|
type: "post",
|
|
data: {},
|
|
dataType: 'json',
|
|
success:function(data) {
|
|
if (data.success) {
|
|
$('#validationModal').modal('show');
|
|
$('#validationModal .error-message').html(data.message);
|
|
|
|
userListTable.ajax.reload();
|
|
}
|
|
},
|
|
error: function(data) {
|
|
var errors = data.responseJSON.errors;
|
|
var errorMessage = '<ul>';
|
|
$.each(errors, function(index, error) {
|
|
console.log(error);
|
|
errorMessage += '<li>' + error[0] + '</li>';
|
|
});
|
|
errorMessage += '</ul>';
|
|
|
|
$('#validationModal .error-message').html(errorMessage);
|
|
$('#validationModal').modal('show');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.edit-user', function(e) {
|
|
var actionShow = $(this).attr('data-action-show');
|
|
var actionUpdate = $(this).attr('data-action-update');
|
|
|
|
if (actionShow && actionUpdate) {
|
|
$.ajax({
|
|
url: actionShow,
|
|
type: "post",
|
|
data: {},
|
|
dataType: 'json',
|
|
success:function(data) {
|
|
if (data.success) {
|
|
$('#editUserFrm').attr('action', actionUpdate);
|
|
$('#editUserFrm input[name="first_name"]').val(data.user.first_name);
|
|
$('#editUserFrm input[name="last_name"]').val(data.user.last_name);
|
|
$('#editUserFrm input[name="phone"]').val(data.user.phone);
|
|
$('#editUserFrm input[name="email"]').val(data.user.email);
|
|
$('#editUserFrm select[name="role_id"]').val(data.user.role_id);
|
|
$('#editUserFrm input[name="status"]').val(data.user.status);
|
|
$('#editUserModal').modal('show');
|
|
}
|
|
},
|
|
error: function(data) {
|
|
var errors = data.responseJSON.errors;
|
|
var errorMessage = '<ul>';
|
|
$.each(errors, function(index, error) {
|
|
console.log(error);
|
|
errorMessage += '<li>' + error[0] + '</li>';
|
|
});
|
|
errorMessage += '</ul>';
|
|
|
|
$('#validationModal .error-message').html(errorMessage);
|
|
$('#validationModal').modal('show');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$('#editUserFrm').submit(function(e) {
|
|
e.preventDefault();
|
|
var action = $(this).attr('action');
|
|
var button = $(this).find('button[type="submit"]');
|
|
var buttonHtml = button.html();
|
|
|
|
if (!button.is(':disabled') && action) {
|
|
button.attr('disabled', 'disabled');
|
|
button.html('<i class="fa fa-spinner fa-spin" style="font-size:24px"></i>');
|
|
|
|
$.ajax({
|
|
url: action,
|
|
type: "post",
|
|
data: $(this).serialize(),
|
|
dataType: 'json',
|
|
success:function(data) {
|
|
button.removeAttr('disabled');
|
|
button.html(buttonHtml);
|
|
|
|
if (data.success) {
|
|
$('#editUserModal').modal('hide');
|
|
$('#validationModal').modal('show');
|
|
$('#validationModal .error-message').html(data.message);
|
|
|
|
$('#editUserFrm').trigger("reset");
|
|
userListTable.ajax.reload();
|
|
}
|
|
else {
|
|
$('#validationModal .error-message').html(data.message);
|
|
$('#validationModal').modal('show');
|
|
}
|
|
},
|
|
error: function(data) {
|
|
var errors = data.responseJSON.errors;
|
|
var errorMessage = '<ul>';
|
|
$.each(errors, function(index, error) {
|
|
console.log(error);
|
|
errorMessage += '<li>' + error[0] + '</li>';
|
|
});
|
|
errorMessage += '</ul>';
|
|
|
|
$('#validationModal .error-message').html(errorMessage);
|
|
$('#validationModal').modal('show');
|
|
button.removeAttr('disabled');
|
|
button.html(buttonHtml);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.view-user-log', function(e) {
|
|
var action = $(this).attr('data-action');
|
|
|
|
if (action) {
|
|
initializeUserAccessLogsListTable(action);
|
|
$('#userActionLogsModal').modal('show');
|
|
}
|
|
});
|
|
|
|
var userAccessLogsListTable = null;
|
|
function initializeUserAccessLogsListTable(url = '{{ route("cms.users.accessLogsTable") }}') {
|
|
if (userAccessLogsListTable) {
|
|
userAccessLogsListTable.destroy();
|
|
}
|
|
|
|
userAccessLogsListTable = $("#userAccessLogsListTable").DataTable({
|
|
processing: true,
|
|
serverSide: true,
|
|
ajax: {
|
|
url: url,
|
|
type: 'post',
|
|
"dataSrc": function ( json ) {
|
|
for (var i = 0; i < json.data.length; i++) {
|
|
$.each( json.data[i], function( key, value ) {
|
|
json.data[i][key] = value ? value : '-';
|
|
});
|
|
}
|
|
|
|
return json.data;
|
|
}
|
|
},
|
|
columns: [
|
|
{data: 'date', name: 'user_access_logs.created_at'},
|
|
{data: 'time', name: 'user_access_logs.created_at'},
|
|
{data: 'event', name: 'user_access_logs.event'},
|
|
{data: 'description', name: 'user_access_logs.description'},
|
|
{data: 'status', name: 'user_access_logs.status'},
|
|
],
|
|
order: [[1, "desc"]],
|
|
searchDelay: 500,
|
|
"language": {
|
|
"paginate": {
|
|
"next": ">", // Text for the "Next" page button
|
|
"previous": "<" // Text for the "Previous" page button
|
|
},
|
|
"emptyTable": '{{ __("No data available in table") }}'
|
|
// Add more text customizations if needed
|
|
}
|
|
});
|
|
}
|
|
} );
|
|
</script>
|
|
@endsection |