update
This commit is contained in:
@@ -13,7 +13,7 @@ class LoginController extends Controller
|
||||
//
|
||||
public function index()
|
||||
{
|
||||
return view("administrator.pages.s.auth.login");
|
||||
return view("administrator.pages.auth.login");
|
||||
}
|
||||
public function store(Request $request)
|
||||
{
|
||||
|
||||
@@ -147,7 +147,7 @@ class MainController extends Controller
|
||||
);
|
||||
$title = 'System Activity Log';
|
||||
|
||||
return view('administrator.pages.s.log', compact('title', 'logs'));
|
||||
return view('administrator.pages.log', compact('title', 'logs'));
|
||||
}
|
||||
|
||||
public function ClearCache()
|
||||
|
||||
@@ -23,14 +23,14 @@ class SettingController extends Controller
|
||||
{
|
||||
$title = 'General Setting';
|
||||
|
||||
return view('administrator.pages.setting', compact('title'));
|
||||
return view('administrator.pagesetting', compact('title'));
|
||||
}
|
||||
|
||||
public function smtp()
|
||||
{
|
||||
$title = 'SMTP Setting';
|
||||
|
||||
return view('administrator.pages.smtp', compact('title'));
|
||||
return view('administrator.pagesmtp', compact('title'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
|
||||
@@ -23,7 +23,7 @@ class SupportController extends Controller
|
||||
|
||||
$tickets = $this->ticketRepository->filter($request->merge(['page' => $request->get('1') ?? 1])->all());
|
||||
$title = "All Support Ticket";
|
||||
return view('administrator.pages.support.index', compact('title', 'tickets'));
|
||||
return view('administrator.pagesupport.index', compact('title', 'tickets'));
|
||||
}
|
||||
|
||||
public function edit(int $ticket_num = 0)
|
||||
@@ -40,7 +40,7 @@ class SupportController extends Controller
|
||||
|
||||
$title = "Ticket #" . $ticket_num;
|
||||
|
||||
return view("administrator.pages.support.view", compact('title', 'ticket'));
|
||||
return view("administrator.pagesupport.view", compact('title', 'ticket'));
|
||||
}
|
||||
|
||||
public function reply(int $id = 0, TicketReplyRequest $request)
|
||||
|
||||
@@ -43,7 +43,7 @@ class Network extends Controller
|
||||
{
|
||||
$title = 'Add Network';
|
||||
|
||||
return view('administrator.pages.s.package.network.add', compact('title'));
|
||||
return view('administrator.pages.package.network.add', compact('title'));
|
||||
}
|
||||
public function store(NetworkRequest $request)
|
||||
{
|
||||
|
||||
@@ -42,8 +42,7 @@ class OsVersion extends Controller
|
||||
{
|
||||
$validatedData = $request->validated();
|
||||
|
||||
// Remove unnecessary fields
|
||||
unset($validatedData['vcenter_id'], $validatedData['module_datacenter_id']);
|
||||
unset($validatedData['module_datacenter_id']);
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
@@ -88,22 +87,21 @@ class OsVersion extends Controller
|
||||
}
|
||||
return redirect()->route('package.version.index')->with('success', 'Update successfully');
|
||||
}
|
||||
public function destroy(Request $request)
|
||||
public function destroy($id)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'oid' => 'numeric'
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator->getMessageBag());
|
||||
}
|
||||
try {
|
||||
$version = $this->osRepository->find($id);
|
||||
if (!$version) {
|
||||
return back()->withErrors('Can\'t find version os by ID #' . $id);
|
||||
}
|
||||
|
||||
$version = Os::find($request->oid);
|
||||
if (! $version) {
|
||||
return back()->withErrors('Can\'t find version os by ID #' . $request->oid);
|
||||
}
|
||||
$version->delete();
|
||||
$version->delete();
|
||||
|
||||
return back()->with('success', 'Delete success');
|
||||
return redirect()->route('package.version.index')
|
||||
->with('success', 'OS Version deleted successfully');
|
||||
} catch (\Exception $error) {
|
||||
return back()->withErrors('Failed to delete OS Version: ' . $error->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function datatable(Request $request)
|
||||
@@ -124,10 +122,18 @@ class OsVersion extends Controller
|
||||
return $d->getStatus();
|
||||
})
|
||||
->addColumn('action', function ($d) {
|
||||
return '<a href="' . route('package.version.edit', $d->id) . '"
|
||||
class="btn btn-primary btn-sm">
|
||||
Edit
|
||||
$editBtn = '<a href="' . route('package.version.edit', $d->id) . '"
|
||||
class="btn btn-primary">
|
||||
<i data-lucide="edit" class="w-12px h-12px"></i>
|
||||
</a>';
|
||||
|
||||
$deleteBtn = '<button type="button"
|
||||
class="btn btn-danger"
|
||||
onclick="showDeleteModal(' . $d->id . ', \'' . addslashes($d->version) . '\')">
|
||||
<i data-lucide="trash-2" class="w-12px h-12px"></i>
|
||||
</button>';
|
||||
|
||||
return '<div class="btn-group" role="group">' . $editBtn . $deleteBtn . '</div>';
|
||||
})
|
||||
->filterColumn('host', function ($query, $keyword) {
|
||||
$query->whereHas('host', function ($q) use ($keyword) {
|
||||
|
||||
@@ -23,9 +23,7 @@ class OsVersionRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'version' => 'required',
|
||||
'module_host_id' => 'required',
|
||||
'os_group_id' => 'required',
|
||||
'os_id' => 'required',
|
||||
'template_id' => 'nullable',
|
||||
'status' => 'required'
|
||||
];
|
||||
|
||||
@@ -13,11 +13,8 @@ class Os extends Model
|
||||
|
||||
protected $fillable = [
|
||||
'version',
|
||||
'os_id',
|
||||
'module_host_id',
|
||||
'os_group_id',
|
||||
'template_id',
|
||||
'vcenter_id',
|
||||
'status'
|
||||
];
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"animate.css": "^4.1.1",
|
||||
"flyonui": "^2.1.0",
|
||||
"laravel-echo": "^1.16.1",
|
||||
"micromodal": "^0.6.1",
|
||||
"socket.io-client": "^4.7.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/* MicroModal Global Styles */
|
||||
.modal {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal.is-open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.modal__overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1050;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.modal__container {
|
||||
background-color: #fff;
|
||||
border-radius: 0.75rem;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
|
||||
position: relative;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
/* Modal Sizes */
|
||||
.modal--xs {
|
||||
max-width: 300px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.modal--sm {
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.modal--md {
|
||||
max-width: 600px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.modal--lg {
|
||||
max-width: 800px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.modal--xl {
|
||||
max-width: 1000px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
/* Modal Header */
|
||||
.modal__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 1.25rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.modal__title {
|
||||
margin: 0;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal__close {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.375rem;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
|
||||
.modal__close:focus {
|
||||
outline: 2px solid rgba(255, 255, 255, 0.5);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Modal Content */
|
||||
.modal__content {
|
||||
padding: 1.5rem;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.modal__content::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.modal__content::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.modal__content::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.modal__content::-webkit-scrollbar-thumb:hover {
|
||||
background: #a1a1a1;
|
||||
}
|
||||
|
||||
/* Modal Footer */
|
||||
.modal__footer {
|
||||
padding: 1rem 1.25rem;
|
||||
border-top: 1px solid #dee2e6;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0 0 0.75rem 0.75rem;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.modal__footer.justify-content-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal__footer.justify-content-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
.micromodal-slide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.micromodal-slide.is-open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.micromodal-slide .modal__overlay {
|
||||
animation: mmfadeIn 0.3s cubic-bezier(0.0, 0.0, 0.2, 1);
|
||||
}
|
||||
|
||||
.micromodal-slide .modal__container {
|
||||
animation: mmslideIn 0.3s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.micromodal-slide.is-closing .modal__overlay {
|
||||
animation: mmfadeOut 0.3s cubic-bezier(0.0, 0.0, 0.2, 1);
|
||||
}
|
||||
|
||||
.micromodal-slide.is-closing .modal__container {
|
||||
animation: mmslideOut 0.3s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* Keyframes */
|
||||
@keyframes mmfadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes mmfadeOut {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes mmslideIn {
|
||||
from {
|
||||
transform: translateY(-15%) scale(0.95);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0) scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mmslideOut {
|
||||
from {
|
||||
transform: translateY(0) scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: translateY(-15%) scale(0.95);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.modal__container {
|
||||
margin: 0.5rem;
|
||||
max-height: 95vh;
|
||||
}
|
||||
|
||||
.modal__header {
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.modal__content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.modal__footer {
|
||||
padding: 0.75rem 1rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.modal__footer .btn {
|
||||
width: 100%;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.modal__footer .btn:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark mode support */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.modal__container {
|
||||
background-color: #2d3748;
|
||||
color: #f7fafc;;
|
||||
}
|
||||
|
||||
.modal__footer {
|
||||
background-color: #1a202c;
|
||||
border-color: #4a5568;
|
||||
}
|
||||
}
|
||||
Vendored
+4
@@ -6,6 +6,10 @@ window.axios = axios;
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
// Import MicroModal
|
||||
import MicroModal from 'micromodal';
|
||||
window.MicroModal = MicroModal;
|
||||
|
||||
import Echo from 'laravel-echo';
|
||||
import Pusher from 'pusher-js';
|
||||
window.Pusher = Pusher;
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* MicroModal Global Utilities
|
||||
* Provides helper functions for MicroModal management
|
||||
*/
|
||||
|
||||
class ModalManager {
|
||||
constructor() {
|
||||
this.initialized = false;
|
||||
this.modals = new Map();
|
||||
this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize MicroModal with default settings
|
||||
*/
|
||||
init() {
|
||||
if (typeof MicroModal === 'undefined') {
|
||||
console.warn('MicroModal is not loaded');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
MicroModal.init({
|
||||
onShow: (modal) => {
|
||||
this.onModalShow(modal);
|
||||
},
|
||||
onClose: (modal) => {
|
||||
this.onModalClose(modal);
|
||||
},
|
||||
openTrigger: 'data-micromodal-trigger',
|
||||
closeTrigger: 'data-micromodal-close',
|
||||
openClass: 'is-open',
|
||||
disableScroll: true,
|
||||
disableFocus: false,
|
||||
awaitOpenAnimation: false,
|
||||
awaitCloseAnimation: false,
|
||||
debugMode: false
|
||||
});
|
||||
|
||||
this.initialized = true;
|
||||
console.log('MicroModal initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when modal is shown
|
||||
*/
|
||||
onModalShow(modal) {
|
||||
// Re-initialize Lucide icons when modal opens
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
// Add body class to prevent scrolling
|
||||
document.body.classList.add('modal-open');
|
||||
|
||||
// Execute custom show callback if exists
|
||||
if (modal && this.modals.has(modal.id)) {
|
||||
const config = this.modals.get(modal.id);
|
||||
if (config.onShow && typeof config.onShow === 'function') {
|
||||
config.onShow(modal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when modal is closed
|
||||
*/
|
||||
onModalClose(modal) {
|
||||
// Remove body class
|
||||
document.body.classList.remove('modal-open');
|
||||
|
||||
// Execute custom close callback if exists
|
||||
if (modal && this.modals.has(modal.id)) {
|
||||
const config = this.modals.get(modal.id);
|
||||
if (config.onClose && typeof config.onClose === 'function') {
|
||||
config.onClose(modal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show modal with optional data
|
||||
*/
|
||||
show(modalId, data = {}) {
|
||||
if (typeof MicroModal === 'undefined') {
|
||||
console.error('MicroModal is not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update modal content if data is provided
|
||||
if (Object.keys(data).length > 0) {
|
||||
this.updateModalContent(modalId, data);
|
||||
}
|
||||
|
||||
MicroModal.show(modalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close modal
|
||||
*/
|
||||
close(modalId) {
|
||||
if (typeof MicroModal === 'undefined') {
|
||||
console.error('MicroModal is not available');
|
||||
return;
|
||||
}
|
||||
|
||||
MicroModal.close(modalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a modal with custom configuration
|
||||
*/
|
||||
register(modalId, config = {}) {
|
||||
this.modals.set(modalId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update modal content dynamically
|
||||
*/
|
||||
updateModalContent(modalId, data) {
|
||||
const modal = document.getElementById(modalId);
|
||||
if (!modal) {
|
||||
console.error(`Modal ${modalId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update text content for elements with data-modal-* attributes
|
||||
Object.keys(data).forEach(key => {
|
||||
const element = modal.querySelector(`[data-modal-${key}]`);
|
||||
if (element) {
|
||||
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
|
||||
element.value = data[key];
|
||||
} else {
|
||||
element.textContent = data[key];
|
||||
}
|
||||
}
|
||||
|
||||
// Also support getElementById for backward compatibility
|
||||
const elementById = modal.querySelector(`#${key}`);
|
||||
if (elementById) {
|
||||
if (elementById.tagName === 'INPUT' || elementById.tagName === 'TEXTAREA') {
|
||||
elementById.value = data[key];
|
||||
} else {
|
||||
elementById.textContent = data[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update form action if provided
|
||||
if (data.formAction) {
|
||||
const form = modal.querySelector('form');
|
||||
if (form) {
|
||||
form.action = data.formAction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a confirmation modal dynamically
|
||||
*/
|
||||
showConfirmation(options = {}) {
|
||||
const defaults = {
|
||||
modalId: 'confirmationModal',
|
||||
title: 'Confirm Action',
|
||||
message: 'Are you sure?',
|
||||
confirmText: 'Confirm',
|
||||
cancelText: 'Cancel',
|
||||
confirmClass: 'btn btn-primary btn-sm',
|
||||
cancelClass: 'btn btn-outline-secondary btn-sm',
|
||||
onConfirm: null,
|
||||
onCancel: null
|
||||
};
|
||||
|
||||
const config = { ...defaults, ...options };
|
||||
|
||||
// Create modal HTML if it doesn't exist
|
||||
let modal = document.getElementById(config.modalId);
|
||||
if (!modal) {
|
||||
modal = this.createConfirmationModal(config);
|
||||
document.body.appendChild(modal);
|
||||
} else {
|
||||
// Update existing modal
|
||||
this.updateConfirmationModal(modal, config);
|
||||
}
|
||||
|
||||
// Register callbacks
|
||||
this.register(config.modalId, {
|
||||
onShow: () => {
|
||||
const confirmBtn = modal.querySelector('.modal__confirm');
|
||||
const cancelBtn = modal.querySelector('.modal__cancel');
|
||||
|
||||
// Remove existing event listeners
|
||||
confirmBtn.replaceWith(confirmBtn.cloneNode(true));
|
||||
cancelBtn.replaceWith(cancelBtn.cloneNode(true));
|
||||
|
||||
// Add new event listeners
|
||||
modal.querySelector('.modal__confirm').addEventListener('click', (e) => {
|
||||
if (config.onConfirm && typeof config.onConfirm === 'function') {
|
||||
config.onConfirm(e);
|
||||
}
|
||||
this.close(config.modalId);
|
||||
});
|
||||
|
||||
modal.querySelector('.modal__cancel').addEventListener('click', (e) => {
|
||||
if (config.onCancel && typeof config.onCancel === 'function') {
|
||||
config.onCancel(e);
|
||||
}
|
||||
this.close(config.modalId);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.show(config.modalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create confirmation modal HTML
|
||||
*/
|
||||
createConfirmationModal(config) {
|
||||
const modalHtml = `
|
||||
<div class="modal micromodal-slide" id="${config.modalId}" aria-hidden="true">
|
||||
<div class="modal__overlay" tabindex="-1" data-micromodal-close>
|
||||
<div class="modal__container modal--sm" role="dialog" aria-modal="true">
|
||||
<header class="modal__header bg-primary text-white">
|
||||
<h6 class="modal__title">${config.title}</h6>
|
||||
<button class="modal__close" aria-label="Close modal" data-micromodal-close>
|
||||
<i data-lucide="x"></i>
|
||||
</button>
|
||||
</header>
|
||||
<main class="modal__content">
|
||||
<div class="text-center">
|
||||
<p class="mb-0">${config.message}</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="modal__footer justify-content-center">
|
||||
<button type="button" class="modal__cancel ${config.cancelClass}" data-micromodal-close>
|
||||
${config.cancelText}
|
||||
</button>
|
||||
<button type="button" class="modal__confirm ${config.confirmClass}">
|
||||
${config.confirmText}
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = modalHtml;
|
||||
return div.firstElementChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update existing confirmation modal
|
||||
*/
|
||||
updateConfirmationModal(modal, config) {
|
||||
modal.querySelector('.modal__title').textContent = config.title;
|
||||
modal.querySelector('.modal__content p').textContent = config.message;
|
||||
modal.querySelector('.modal__confirm').textContent = config.confirmText;
|
||||
modal.querySelector('.modal__cancel').textContent = config.cancelText;
|
||||
|
||||
// Update button classes
|
||||
modal.querySelector('.modal__confirm').className = `modal__confirm ${config.confirmClass}`;
|
||||
modal.querySelector('.modal__cancel').className = `modal__cancel ${config.cancelClass}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Global instance
|
||||
window.ModalManager = new ModalManager();
|
||||
|
||||
// Helper functions for backward compatibility
|
||||
window.showModal = (modalId, data = {}) => {
|
||||
window.ModalManager.show(modalId, data);
|
||||
};
|
||||
|
||||
window.closeModal = (modalId) => {
|
||||
window.ModalManager.close(modalId);
|
||||
};
|
||||
|
||||
window.showConfirmation = (options) => {
|
||||
window.ModalManager.showConfirmation(options);
|
||||
};
|
||||
|
||||
// Auto-initialize when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize Lucide icons
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
console.log('Modal utilities loaded');
|
||||
});
|
||||
|
||||
// Export for ES modules
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = ModalManager;
|
||||
}
|
||||
@@ -44,6 +44,9 @@
|
||||
|
||||
<!-- CSS for LTR layout-->
|
||||
@vite(['resources/sass/app.scss'])
|
||||
|
||||
<!-- Global Modal CSS -->
|
||||
@vite(['resources/css/components/micromodal.css'])
|
||||
|
||||
<!-- CSS for RTL layout-->
|
||||
|
||||
@@ -77,6 +80,9 @@
|
||||
|
||||
<!-- common js -->
|
||||
@vite(['resources/js/pages/template.js'])
|
||||
|
||||
<!-- Global Modal JS -->
|
||||
@vite(['resources/js/components/micromodal.js'])
|
||||
<!-- end common js -->
|
||||
|
||||
<!-- Global Select2 initialization -->
|
||||
@@ -88,6 +94,16 @@
|
||||
height: "100%",
|
||||
});
|
||||
};
|
||||
|
||||
// Global ModalManager initialization
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
if (typeof ModalManager !== 'undefined') {
|
||||
ModalManager.init();
|
||||
console.log('ModalManager initialized globally');
|
||||
} else {
|
||||
console.warn('ModalManager not loaded');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@include('administrator.layout.partials.toast')
|
||||
|
||||
@@ -13,61 +13,64 @@
|
||||
<h4 class="title">Clients Information</h4>
|
||||
<!--Box info-->
|
||||
<div class="summary__box">
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">First Name</th>
|
||||
<td>{{ $customer->firstname }}</td>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-borderless table-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">First Name</th>
|
||||
<td>{{ $customer->firstname }}</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Last Name</th>
|
||||
<td>{{ $customer->lastname }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Company</th>
|
||||
<td>{{ $customer->company }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Email</th>
|
||||
<td>{{ $customer->email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Address</th>
|
||||
<td>{{ $customer->address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">City</th>
|
||||
<td>{{ $customer->city }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Country</th>
|
||||
<td>{{ $customer->country }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Phone Number</th>
|
||||
<td>{{ $customer->phone }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Last Name</th>
|
||||
<td>{{ $customer->lastname }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Company</th>
|
||||
<td>{{ $customer->company }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Email</th>
|
||||
<td>{{ $customer->email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Address</th>
|
||||
<td>{{ $customer->address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">City</th>
|
||||
<td>{{ $customer->city }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Country</th>
|
||||
<td>{{ $customer->country }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Phone Number</th>
|
||||
<td>{{ $customer->phone }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!--Box Action-->
|
||||
<div class="summary--box__action mt-2">
|
||||
<ul class="list-unstyled">
|
||||
<li>
|
||||
<a id="summary-reset-password"
|
||||
<div class="summary--box__action mt-3">
|
||||
<div class="list-group list-group-flush">
|
||||
<div class="list-group-item border-0 px-0">
|
||||
<a class="btn btn-outline-warning btn-sm btn-block" id="summary-reset-password"
|
||||
href="{{ route('customer.PasswordReset', ['userid' => $customer->id]) }}">
|
||||
<img src="{{ asset('images/resetpw.png') }}">
|
||||
<i data-lucide="key" class="mr-2"></i>
|
||||
Reset & Send Password
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" id="summary-login-as-client"
|
||||
</div>
|
||||
<div class="list-group-item border-0 px-0">
|
||||
<a class="btn btn-outline-info btn-sm btn-block" target="_blank" id="summary-login-as-client"
|
||||
href="{{ route('customer.Login', ['userid' => $customer->id]) }}">
|
||||
<img src="{{ asset('images/clientlogin.png') }}"> Login as Client
|
||||
<i data-lucide="log-in" class="mr-2"></i>
|
||||
Login as Client
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,50 +80,61 @@
|
||||
<h4 class="title">Invoices/Billing</h4>
|
||||
<!--Box info-->
|
||||
<div class="summary__box">
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Invoice Paid</th>
|
||||
<td>{{ $customer->invoices_status_count_1 }}
|
||||
(@money($customer->invoices_status_1)
|
||||
đ)
|
||||
</td>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-borderless table-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Invoice Paid</th>
|
||||
<td class="text-success font-weight-bold">
|
||||
<span class="badge badge-success">{{ $customer->invoices_status_count_1 }}</span>
|
||||
(@money($customer->invoices_status_1) đ)
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Invoice UnPaid</th>
|
||||
<td>{{ $customer->invoices_status_count_0 }}
|
||||
(@money($customer->invoices_status_0)
|
||||
đ)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Total</th>
|
||||
<td>@money($customer->invoices_status_0 + $customer->invoices_status_1) đ</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Invoice UnPaid</th>
|
||||
<td class="text-warning font-weight-bold">
|
||||
<span class="badge badge-warning">{{ $customer->invoices_status_count_0 }}</span>
|
||||
(@money($customer->invoices_status_0) đ)
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-top">
|
||||
<th scope="row" class="font-weight-bold">Total</th>
|
||||
<td class="font-weight-bold text-primary">@money($customer->invoices_status_0 + $customer->invoices_status_1) đ</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clients-summary__box">
|
||||
<h4 class="title">Recent Emails</h4>
|
||||
<div class="summary__box">
|
||||
@if($customer->mail->count())
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
@foreach($customer->mail->take(4)->all() as $item)
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ route('customer.email', ['userid' => $userid, 'email_id' => $item->id]) }}"
|
||||
target="_blank">{{ $item->created_at }}
|
||||
- {{ $item->subject }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-borderless table-sm table-hover">
|
||||
<tbody>
|
||||
@foreach($customer->mail->take(4)->all() as $item)
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-decoration-none" href="{{ route('customer.email', ['userid' => $userid, 'email_id' => $item->id]) }}"
|
||||
target="_blank">
|
||||
<div class="d-flex flex-column">
|
||||
<small class="text-muted">{{ $item->created_at }}</small>
|
||||
<span class="text-dark">{{ $item->subject }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<p class="text-center m-0">No recent Email</p>
|
||||
<div class="text-center py-3">
|
||||
<i data-lucide="mail-open" class="text-muted mb-2" style="width: 48px; height: 48px;"></i>
|
||||
<p class="text-muted mb-0">No recent Email</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@@ -132,26 +146,36 @@
|
||||
<h4 class="title">Products/Services</h4>
|
||||
<!--Box info-->
|
||||
<div class="summary__box">
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">VPS/Server</th>
|
||||
<td>{{ $customer->vps_count}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Hosting</th>
|
||||
<td>{{ $customer->hosting_count }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Domain</th>
|
||||
<td>{{ $customer->domain_count }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Support Tickets</th>
|
||||
<td>{{ $customer->ticket_count }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-borderless table-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">VPS/Server</th>
|
||||
<td>
|
||||
<span class="badge badge-primary">{{ $customer->vps_count}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Hosting</th>
|
||||
<td>
|
||||
<span class="badge badge-info">{{ $customer->hosting_count }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Domain</th>
|
||||
<td>
|
||||
<span class="badge badge-success">{{ $customer->domain_count }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Support Tickets</th>
|
||||
<td>
|
||||
<span class="badge badge-warning">{{ $customer->ticket_count }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--File-->
|
||||
@@ -159,46 +183,58 @@
|
||||
<h4 class="title">Files</h4>
|
||||
<div class="summary__box">
|
||||
@if($customer->file->count())
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
@foreach($customer->file->all() as $item)
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ $item->file_url }}" download
|
||||
target="_blank">{{ $item->filename }}</a>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<button data-id="{{ $item->id }}"
|
||||
class="btn btn-outline-secondary p-1 border-0 btn-remove__file">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-borderless table-sm table-hover">
|
||||
<tbody>
|
||||
@foreach($customer->file->all() as $item)
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-decoration-none d-flex align-items-center" href="{{ $item->file_url }}" download target="_blank">
|
||||
<i data-lucide="file" class="mr-2 text-primary"></i>
|
||||
<span>{{ $item->filename }}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<button data-id="{{ $item->id }}"
|
||||
class="btn btn-outline-danger btn-sm p-1 btn-remove__file">
|
||||
<i data-lucide="trash-2"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<p class="text-center m-0">No files uploaded</p>
|
||||
<div class="text-center py-3">
|
||||
<i data-lucide="file-text" class="text-muted mb-2" style="width: 48px; height: 48px;"></i>
|
||||
<p class="text-muted mb-0">No files uploaded</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="box-add__file mt-2">
|
||||
<a onclick="$('.box-add__input').removeClass('d-none')" class="cursor-point pointer-event">
|
||||
<img alt="Add File" src="{{ asset('images/add.png') }}"> Add File
|
||||
</a>
|
||||
<div class="box-add__input d-none mt-2">
|
||||
<div class="summary__box p-2">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label for="input-file">File:</label>
|
||||
<input type="text" class="form-control mt-2" id="input-file" name="file">
|
||||
<div class="box-add__file mt-3">
|
||||
<button type="button" class="btn btn-outline-success btn-sm" onclick="$('.box-add__input').toggleClass('d-none')">
|
||||
<i data-lucide="plus" class="mr-2"></i>
|
||||
Add File
|
||||
</button>
|
||||
<div class="box-add__input d-none mt-3">
|
||||
<div class="card border-light">
|
||||
<div class="card-body p-3">
|
||||
<div class="form-group mb-3">
|
||||
<label for="input-file" class="form-label">File:</label>
|
||||
<input type="text" class="form-control form-control-sm" id="input-file" name="file" placeholder="Select a file...">
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button" class="btn btn-outline-primary btn-open__ckfinder">
|
||||
<i data-lucide="folder-open" class="mr-1"></i>
|
||||
Choose File
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-save__data">
|
||||
<i data-lucide="save" class="mr-1"></i>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn mt-2 btn-open__ckfinder btn-outline-secondary">
|
||||
Choose File
|
||||
</button>
|
||||
<button class="btn mt-2 btn-save__data btn-outline-secondary">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -213,13 +249,20 @@
|
||||
</div>
|
||||
@else
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<h5 class="mb-0"><i class="icon fas fa-ban"></i> Access Denied - You are not assigned to any Customer
|
||||
<h5 class="mb-0"><i data-lucide="ban" class="icon mr-2"></i> Access Denied - You are not assigned to any Customer
|
||||
management department</h5>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
// Initialize Lucide icons
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
});
|
||||
|
||||
$('.btn-open__ckfinder').click(function () {
|
||||
CKFinder.popup({
|
||||
chooseFiles: true,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<div class="card card-primary card-outline">
|
||||
<div class="card-header">
|
||||
@include("administrator.pages.s.block.Sync.Folder")
|
||||
@include("administrator.pages.block.Sync.Folder")
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<x-datatable id="folderTable" ajax="{{ route('package.folder.datatable') }}" :columns="[
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@if (auth()->guard('admins')->user()->can('manager package module'))
|
||||
<div class="card card-primary card-outline">
|
||||
<div class="card-header">
|
||||
@include('administrator.pages.s.block.Group')
|
||||
@include('administrator.pages.block.Group')
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<x-datatable id="groupTable" ajax="{{ route('package.group.datatable') }}" :columns="[
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@if(auth()->guard('admins')->user()->can("manager package module"))
|
||||
<div class="card card-primary card-outline">
|
||||
<div class="card-header">
|
||||
@include("administrator.pages.s.block.Sync.Network")
|
||||
@include("administrator.pages.block.Sync.Network")
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<x-datatable id="networkTable" ajax="{{ route('package.network.datatable') }}" :columns="[
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<!-- Delete Confirmation Modal -->
|
||||
<div class="modal micromodal-slide" id="deleteModal" aria-hidden="true">
|
||||
<div class="modal__overlay" tabindex="-1" data-micromodal-close>
|
||||
<div class="modal__container modal--sm" role="dialog" aria-modal="true" aria-labelledby="deleteModalLabel">
|
||||
<header class="modal__header bg-primary text-white">
|
||||
<h6 class="modal__title" id="deleteModalLabel">
|
||||
<i data-lucide="trash-2" class="w-15px h-15px me-2"></i>
|
||||
Confirm Delete
|
||||
</h6>
|
||||
<button class="modal__close" aria-label="Close modal" data-micromodal-close>
|
||||
<i data-lucide="x"></i>
|
||||
</button>
|
||||
</header>
|
||||
<main class="modal__content">
|
||||
<div class="text-center">
|
||||
<i data-lucide="alert-triangle" class="text-warning mb-3" style="width: 48px; height: 48px;"></i>
|
||||
<h6 class="mb-2">Are you sure?</h6>
|
||||
<p class="text-muted small mb-1">Delete OS Version:</p>
|
||||
<p class="fw-bold mb-2"><span id="deleteItemName"></span></p>
|
||||
<p class="text-danger small mb-0">This action cannot be undone!</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="modal__footer">
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm me-2" data-micromodal-close>
|
||||
<i data-lucide="x" class="me-1"></i>
|
||||
Cancel
|
||||
</button>
|
||||
<form id="deleteForm" method="POST" class="d-inline">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i data-lucide="trash-2" class="me-1"></i>
|
||||
Delete
|
||||
</button>
|
||||
</form>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('custom-scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
function initializeModal() {
|
||||
if (typeof ModalManager !== 'undefined') {
|
||||
window.showDeleteModal = function(id, name) {
|
||||
// Update modal content
|
||||
const nameElement = document.getElementById('deleteItemName');
|
||||
const formElement = document.getElementById('deleteForm');
|
||||
|
||||
if (nameElement && formElement) {
|
||||
nameElement.textContent = name;
|
||||
formElement.action = `/administrator/package/version/remove-os-version/${id}`;
|
||||
ModalManager.show('deleteModal');
|
||||
} else {
|
||||
console.error('Modal elements not found');
|
||||
}
|
||||
};
|
||||
|
||||
} else {
|
||||
console.warn('ModalManager not available, retrying...');
|
||||
setTimeout(initializeModal, 100);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(initializeModal, 50);
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -17,14 +17,15 @@
|
||||
@if (auth()->guard('admins')->user()->can('manager package module'))
|
||||
<div class="card card-primary card-outline">
|
||||
<div class="card-header">
|
||||
<a href="{{ route('package.version.create') }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-plus"></i> Add New Version OS
|
||||
<a href="{{ route('package.version.create') }}" class="btn btn-outline-primary">
|
||||
<i data-lucide="plus" class="mr-2"></i> Add New Version OS
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<x-datatable id="osVerisionTable" ajax="{{ route('package.version.datatable') }}" :columns="[
|
||||
['key' => 'version', 'label' => 'Version'],
|
||||
['key' => 'os_group', 'label' => 'OS Group'],
|
||||
['key' => 'template_id', 'label' => 'Template'],
|
||||
['key' => 'status', 'label' => 'Status'],
|
||||
['key' => 'action', 'label' => 'Action'],
|
||||
]" />
|
||||
@@ -33,12 +34,33 @@
|
||||
</div>
|
||||
@else
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<h5 class="mb-0"><i class="icon fas fa-ban"></i> Access Denied - You are not assigned to any Module Package
|
||||
<h5 class="mb-0"><i data-lucide="ban" class="icon mr-2"></i> Access Denied - You are not assigned to any Module Package
|
||||
management department</h5>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Include Delete Modal -->
|
||||
@include('administrator.pages.package.version.datatable.modal')
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
// Initialize Lucide icons
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
// Re-initialize icons when DataTable draws
|
||||
$('#osVerisionTable').on('draw.dt', function() {
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@push('plugin-scripts')
|
||||
<script src="{{ asset('build/plugins/jquery/jquery.min.js') }}"></script>
|
||||
<script src="{{ asset('build/plugins/select2/select2.min.js') }}"></script>
|
||||
|
||||
@@ -9,6 +9,6 @@ Route::prefix('administrator-v2')->group(function () {
|
||||
|
||||
|
||||
Route::get('/login', function () {
|
||||
return view('administrator.pages.s.auth.login');
|
||||
return view('administrator.pages.auth.login');
|
||||
});
|
||||
});
|
||||
+169
-203
@@ -6,248 +6,219 @@ export default defineConfig({
|
||||
plugins: [
|
||||
laravel({
|
||||
input: [
|
||||
"resources/sass/app.scss",
|
||||
"resources/css/custom.css",
|
||||
"resources/rtl-css/app-rtl.css",
|
||||
"resources/rtl-css/custom-rtl.css",
|
||||
"resources/js/app-vite.js", // Using app-vite.js
|
||||
"resources/js/pages/template.js",
|
||||
"resources/js/pages/ace.js",
|
||||
"resources/js/pages/apexcharts.js",
|
||||
"resources/js/pages/bootstrap-maxlength.js",
|
||||
"resources/js/pages/chartjs.js",
|
||||
"resources/js/pages/chat.js",
|
||||
"resources/js/pages/color-modes.js",
|
||||
"resources/js/pages/cropper.js",
|
||||
"resources/js/pages/dashboard.js",
|
||||
"resources/js/pages/data-table.js",
|
||||
"resources/js/pages/demo.js",
|
||||
"resources/js/pages/dropify.js",
|
||||
"resources/js/pages/dropzone.js",
|
||||
"resources/js/pages/easymde.js",
|
||||
"resources/js/pages/email.js",
|
||||
"resources/js/pages/flatpickr.js",
|
||||
"resources/js/pages/form-validation.js",
|
||||
"resources/js/pages/fullcalendar.js",
|
||||
"resources/js/pages/inputmask.js",
|
||||
"resources/js/pages/jquery-steps.js",
|
||||
"resources/js/pages/jquery.flot.js",
|
||||
"resources/js/pages/owl-carousel.js",
|
||||
"resources/js/pages/peity.js",
|
||||
"resources/js/pages/pickr.js",
|
||||
"resources/js/pages/select2.js",
|
||||
"resources/js/pages/sortablejs.js",
|
||||
"resources/js/pages/sparkline.js",
|
||||
"resources/js/pages/sweet-alert.js",
|
||||
"resources/js/pages/tags-input.js",
|
||||
"resources/js/pages/tinymce.js",
|
||||
"resources/js/pages/typeahead.js",
|
||||
'resources/sass/app.scss',
|
||||
'resources/css/custom.css',
|
||||
'resources/css/components/micromodal.css',
|
||||
'resources/rtl-css/app-rtl.css',
|
||||
'resources/rtl-css/custom-rtl.css',
|
||||
'resources/js/app-vite.js', // Using app-vite.js
|
||||
'resources/js/components/micromodal.js',
|
||||
'resources/js/pages/template.js',
|
||||
'resources/js/pages/ace.js',
|
||||
'resources/js/pages/apexcharts.js',
|
||||
'resources/js/pages/bootstrap-maxlength.js',
|
||||
'resources/js/pages/chartjs.js',
|
||||
'resources/js/pages/chat.js',
|
||||
'resources/js/pages/color-modes.js',
|
||||
'resources/js/pages/cropper.js',
|
||||
'resources/js/pages/dashboard.js',
|
||||
'resources/js/pages/data-table.js',
|
||||
'resources/js/pages/demo.js',
|
||||
'resources/js/pages/dropify.js',
|
||||
'resources/js/pages/dropzone.js',
|
||||
'resources/js/pages/easymde.js',
|
||||
'resources/js/pages/email.js',
|
||||
'resources/js/pages/flatpickr.js',
|
||||
'resources/js/pages/form-validation.js',
|
||||
'resources/js/pages/fullcalendar.js',
|
||||
'resources/js/pages/inputmask.js',
|
||||
'resources/js/pages/jquery-steps.js',
|
||||
'resources/js/pages/jquery.flot.js',
|
||||
'resources/js/pages/owl-carousel.js',
|
||||
'resources/js/pages/peity.js',
|
||||
'resources/js/pages/pickr.js',
|
||||
'resources/js/pages/select2.js',
|
||||
'resources/js/pages/sortablejs.js',
|
||||
'resources/js/pages/sparkline.js',
|
||||
'resources/js/pages/sweet-alert.js',
|
||||
'resources/js/pages/tags-input.js',
|
||||
'resources/js/pages/tinymce.js',
|
||||
'resources/js/pages/typeahead.js',
|
||||
],
|
||||
refresh: true,
|
||||
}),
|
||||
viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
src: "resources/images",
|
||||
dest: "",
|
||||
src: 'resources/images',
|
||||
dest: '',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/@mdi/font/*"],
|
||||
dest: "plugins/@mdi",
|
||||
src: ['node_modules/@mdi/font/*'],
|
||||
dest: 'plugins/@mdi',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/ace-builds/src-min/*"],
|
||||
dest: "plugins/ace-builds",
|
||||
src: ['node_modules/ace-builds/src-min/*'],
|
||||
dest: 'plugins/ace-builds',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/animate.css/animate.min.css"],
|
||||
dest: "plugins/animate-css",
|
||||
src: ['node_modules/animate.css/animate.min.css'],
|
||||
dest: 'plugins/animate-css',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/apexcharts/dist/apexcharts.min.js"],
|
||||
dest: "plugins/apexcharts",
|
||||
src: ['node_modules/apexcharts/dist/apexcharts.min.js'],
|
||||
dest: 'plugins/apexcharts',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'],
|
||||
dest: 'plugins/bootstrap',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/bootstrap-maxlength/dist/bootstrap-maxlength.min.js'],
|
||||
dest: 'plugins/bootstrap-maxlength',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/chart.js/dist/chart.umd.js'],
|
||||
dest: 'plugins/chartjs',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/clipboard/dist/clipboard.min.js'],
|
||||
dest: 'plugins/clipboard',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/cropperjs/dist/cropper.min.js', 'node_modules/cropperjs/dist/cropper.min.css'],
|
||||
dest: 'plugins/cropperjs',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/datatables.net/js/dataTables.min.js'],
|
||||
dest: 'plugins/datatables.net',
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js",
|
||||
'node_modules/datatables.net-bs5/js/dataTables.bootstrap5.min.js',
|
||||
'node_modules/datatables.net-bs5/css/dataTables.bootstrap5.min.css',
|
||||
],
|
||||
dest: "plugins/bootstrap",
|
||||
dest: 'plugins/datatables.net-bs5',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/dropify/dist/*'],
|
||||
dest: 'plugins/dropify',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/dropzone/dist/dropzone-min.js', 'node_modules/dropzone/dist/dropzone.css'],
|
||||
dest: 'plugins/dropzone',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/easymde/dist/easymde.min.js', 'node_modules/easymde/dist/easymde.min.css'],
|
||||
dest: 'plugins/easymde',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/flag-icons/css', 'node_modules/flag-icons/flags'],
|
||||
dest: 'plugins/flag-icons',
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/bootstrap-maxlength/dist/bootstrap-maxlength.min.js",
|
||||
'node_modules/flatpickr/dist/flatpickr.min.js',
|
||||
'node_modules/flatpickr/dist/flatpickr.min.css',
|
||||
],
|
||||
dest: "plugins/bootstrap-maxlength",
|
||||
dest: 'plugins/flatpickr',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/chart.js/dist/chart.umd.js"],
|
||||
dest: "plugins/chartjs",
|
||||
src: ['node_modules/fullcalendar/index.global.min.js'],
|
||||
dest: 'plugins/fullcalendar',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/clipboard/dist/clipboard.min.js"],
|
||||
dest: "plugins/clipboard",
|
||||
src: ['node_modules/inputmask/dist/jquery.inputmask.min.js'],
|
||||
dest: 'plugins/inputmask',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/jquery-mousewheel/jquery.mousewheel.js'],
|
||||
dest: 'plugins/jquery-mousewheel',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/jquery/dist/jquery.min.js'],
|
||||
dest: 'plugins/jquery',
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/cropperjs/dist/cropper.min.js",
|
||||
"node_modules/cropperjs/dist/cropper.min.css",
|
||||
'node_modules/jquery-steps/build/jquery.steps.min.js',
|
||||
'node_modules/jquery-steps/demo/css/jquery.steps.css',
|
||||
],
|
||||
dest: "plugins/cropperjs",
|
||||
dest: 'plugins/jquery-steps',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/datatables.net/js/dataTables.min.js"],
|
||||
dest: "plugins/datatables.net",
|
||||
src: ['node_modules/jquery-tags-input/dist/*'],
|
||||
dest: 'plugins/jquery-tags-input',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/jquery-validation/dist/jquery.validate.min.js'],
|
||||
dest: 'plugins/jquery-validation',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/jquery.flot/*'],
|
||||
dest: 'plugins/jquery.flot',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/jquery-sparkline/jquery.sparkline.min.js'],
|
||||
dest: 'plugins/jquery-sparkline',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/lucide/dist/umd/lucide.min.js'],
|
||||
dest: 'plugins/lucide',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/moment/min/moment.min.js'],
|
||||
dest: 'plugins/moment',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/owl.carousel/dist/*'],
|
||||
dest: 'plugins/owl-carousel',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/peity/jquery.peity.min.js'],
|
||||
dest: 'plugins/peity',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/perfect-scrollbar/dist/*', 'node_modules/perfect-scrollbar/css/*'],
|
||||
dest: 'plugins/perfect-scrollbar',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/@simonwep/pickr/dist/*'],
|
||||
dest: 'plugins/pickr',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/prismjs/prism.js'],
|
||||
dest: 'plugins/prismjs',
|
||||
},
|
||||
{
|
||||
src: ['node_modules/prism-themes/themes/prism-coldark-dark.css'],
|
||||
dest: 'plugins/prism-themes',
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/datatables.net-bs5/js/dataTables.bootstrap5.min.js",
|
||||
"node_modules/datatables.net-bs5/css/dataTables.bootstrap5.min.css",
|
||||
'node_modules/select2/dist/js/select2.min.js',
|
||||
'node_modules/select2/dist/css/select2.min.css',
|
||||
],
|
||||
dest: "plugins/datatables.net-bs5",
|
||||
dest: 'plugins/select2',
|
||||
},
|
||||
{
|
||||
src: ["node_modules/dropify/dist/*"],
|
||||
dest: "plugins/dropify",
|
||||
src: ['node_modules/sortablejs/Sortable.min.js'],
|
||||
dest: 'plugins/sortablejs',
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/dropzone/dist/dropzone-min.js",
|
||||
"node_modules/dropzone/dist/dropzone.css",
|
||||
'node_modules/sweetalert2/dist/sweetalert2.min.js',
|
||||
'node_modules/sweetalert2/dist/sweetalert2.min.css',
|
||||
],
|
||||
dest: "plugins/dropzone",
|
||||
dest: 'plugins/sweetalert2',
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/easymde/dist/easymde.min.js",
|
||||
"node_modules/easymde/dist/easymde.min.css",
|
||||
],
|
||||
dest: "plugins/easymde",
|
||||
src: ['node_modules/tinymce/*'],
|
||||
dest: 'plugins/tinymce',
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/flag-icons/css",
|
||||
"node_modules/flag-icons/flags",
|
||||
],
|
||||
dest: "plugins/flag-icons",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/flatpickr/dist/flatpickr.min.js",
|
||||
"node_modules/flatpickr/dist/flatpickr.min.css",
|
||||
],
|
||||
dest: "plugins/flatpickr",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/fullcalendar/index.global.min.js"],
|
||||
dest: "plugins/fullcalendar",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/inputmask/dist/jquery.inputmask.min.js",
|
||||
],
|
||||
dest: "plugins/inputmask",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/jquery-mousewheel/jquery.mousewheel.js",
|
||||
],
|
||||
dest: "plugins/jquery-mousewheel",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/jquery/dist/jquery.min.js"],
|
||||
dest: "plugins/jquery",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/jquery-steps/build/jquery.steps.min.js",
|
||||
"node_modules/jquery-steps/demo/css/jquery.steps.css",
|
||||
],
|
||||
dest: "plugins/jquery-steps",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/jquery-tags-input/dist/*"],
|
||||
dest: "plugins/jquery-tags-input",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/jquery-validation/dist/jquery.validate.min.js",
|
||||
],
|
||||
dest: "plugins/jquery-validation",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/jquery.flot/*"],
|
||||
dest: "plugins/jquery.flot",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/jquery-sparkline/jquery.sparkline.min.js",
|
||||
],
|
||||
dest: "plugins/jquery-sparkline",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/lucide/dist/umd/lucide.min.js"],
|
||||
dest: "plugins/lucide",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/moment/min/moment.min.js"],
|
||||
dest: "plugins/moment",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/owl.carousel/dist/*"],
|
||||
dest: "plugins/owl-carousel",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/peity/jquery.peity.min.js"],
|
||||
dest: "plugins/peity",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/perfect-scrollbar/dist/*",
|
||||
"node_modules/perfect-scrollbar/css/*",
|
||||
],
|
||||
dest: "plugins/perfect-scrollbar",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/@simonwep/pickr/dist/*"],
|
||||
dest: "plugins/pickr",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/prismjs/prism.js"],
|
||||
dest: "plugins/prismjs",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/prism-themes/themes/prism-coldark-dark.css",
|
||||
],
|
||||
dest: "plugins/prism-themes",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/select2/dist/js/select2.min.js",
|
||||
"node_modules/select2/dist/css/select2.min.css",
|
||||
],
|
||||
dest: "plugins/select2",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/sortablejs/Sortable.min.js"],
|
||||
dest: "plugins/sortablejs",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/sweetalert2/dist/sweetalert2.min.js",
|
||||
"node_modules/sweetalert2/dist/sweetalert2.min.css",
|
||||
],
|
||||
dest: "plugins/sweetalert2",
|
||||
},
|
||||
{
|
||||
src: ["node_modules/tinymce/*"],
|
||||
dest: "plugins/tinymce",
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"node_modules/typeahead.js/dist/typeahead.bundle.min.js",
|
||||
],
|
||||
dest: "plugins/typeahead-js",
|
||||
src: ['node_modules/typeahead.js/dist/typeahead.bundle.min.js'],
|
||||
dest: 'plugins/typeahead-js',
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -256,13 +227,8 @@ export default defineConfig({
|
||||
devSourcemap: true,
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
silenceDeprecations: [
|
||||
"mixed-decls",
|
||||
"color-functions",
|
||||
"global-builtin",
|
||||
"import",
|
||||
],
|
||||
api: "modern-compiler",
|
||||
silenceDeprecations: ['mixed-decls', 'color-functions', 'global-builtin', 'import'],
|
||||
api: 'modern-compiler',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4829,6 +4829,11 @@ micromatch@^4.0.2, micromatch@^4.0.8:
|
||||
braces "^3.0.3"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
micromodal@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/micromodal/-/micromodal-0.6.1.tgz#2558c1802317a53e89f7913652a1eb8b91454738"
|
||||
integrity sha512-rw1fOptxQe3XGDm9xil9hBC2ylPb1kKZyYv4FlK54R/7L+KG+D8SQxPL5L8OlEXAhBDHckeoULYxWSYU9rg/RA==
|
||||
|
||||
miller-rabin@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz"
|
||||
|
||||
Reference in New Issue
Block a user