This commit is contained in:
pbao9
2026-02-06 20:52:59 +07:00
parent d7aadf7544
commit e7b9ce7485
17 changed files with 570 additions and 36 deletions
@@ -21,11 +21,13 @@
</div>
</main>
<footer class="modal__footer">
<x-button-crm type="button" variant="secondary" size="sm" icon="x" data-micromodal-close>Cancel</x-button-crm>
<x-button-crm type="button" variant="secondary" size="sm" icon="x"
data-micromodal-close>Cancel</x-button-crm>
<form id="deleteForm" method="POST" class="d-inline">
@csrf
@method('DELETE')
<x-button-crm type="submit" variant="danger" size="sm" icon="trash-2">Confirm Delete</x-button-crm>
<x-button-crm type="submit" variant="danger" size="sm" icon="trash-2">Confirm
Delete</x-button-crm>
</form>
</footer>
</div>
@@ -34,10 +36,10 @@
@push('custom-scripts')
<script>
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('DOMContentLoaded', function() {
function initializeModal() {
if (typeof ModalManager !== 'undefined') {
window.showDeleteModal = function (id, name) {
window.showDeleteModal = function(id, name) {
// Update modal content
const nameElement = document.getElementById('deleteItemName');
const formElement = document.getElementById('deleteForm');
@@ -60,4 +62,4 @@
setTimeout(initializeModal, 50);
});
</script>
@endpush
@endpush
@@ -1,2 +1,13 @@
<x-button-crm type="button" variant="primary" size="sm" route="products.group.edit" :params="['id' => $row->id]" icon="pencil">Edit</x-button-crm>
<x-button-crm type="button" variant="danger" size="sm" route="products.group.destroy" :params="['id' => $row->id]" icon="trash">Delete</x-button-crm>
<div class="d-flex gap-2">
<x-button-crm type="button" variant="primary" size="sm" route="products.group.edit" :params="['id' => $row->id]" icon="pencil">Edit</x-button-crm>
<x-button-crm type="button" variant="danger" size="sm" icon="trash" data-micromodal-trigger="deleteModal-{{ $row->id }}">Delete</x-button-crm>
</div>
@include('administrator.pages.product.categories.datatable.modal', [
'deleteRoute' => 'products.group.destroy',
'itemLabel' => 'Product Group',
'itemId' => $row->id,
'itemName' => $row->name,
'modalId' => 'deleteModal-' . $row->id
])
@@ -0,0 +1,34 @@
<!-- Delete Confirmation Modal -->
<div class="modal micromodal-slide" id="{{ $modalId ?? '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-{{ $modalId ?? 'deleteModal' }}">
<header class="modal__header bg-primary text-white">
<h6 class="modal__title" id="deleteModalLabel-{{ $modalId ?? 'deleteModal' }}">
<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 {{ $itemLabel }}:</p>
<p class="fw-bold mb-2">{{ $itemName ?? '' }}</p>
<p class="text-danger small mb-0">This action cannot be undone!</p>
</div>
</main>
<footer class="modal__footer">
<x-button-crm type="button" variant="secondary" size="sm" icon="x" data-micromodal-close>Cancel</x-button-crm>
<form action="{{ route($deleteRoute, ['id' => $itemId ?? 0]) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<x-button-crm type="submit" variant="danger" size="sm" icon="trash-2">Confirm Delete</x-button-crm>
</form>
</footer>
</div>
</div>
</div>
@@ -59,4 +59,40 @@
@foreach (config('assets.datatable.js') as $datatable)
<script src="{{ asset($datatable) }}"></script>
@endforeach
@endpush
@endpush
@push('custom-scripts')
<script>
document.addEventListener('DOMContentLoaded', function () {
// Function to initialize MicroModal
function initMicroModal() {
if (typeof MicroModal !== 'undefined') {
MicroModal.init({
onShow: modal => console.info(`${modal.id} is shown`),
onClose: modal => console.info(`${modal.id} is hidden`),
openTrigger: 'data-micromodal-trigger',
closeTrigger: 'data-micromodal-close',
disableScroll: true,
disableFocus: false,
awaitOpenAnimation: false,
awaitCloseAnimation: false,
debugMode: true
});
}
}
// Initialize on page load
initMicroModal();
// Re-initialize after DataTable draws (when action column renders)
$('#productTable').on('draw.dt', function() {
setTimeout(function() {
initMicroModal();
// Re-initialize Lucide icons for modal content
if (typeof lucide !== 'undefined') {
lucide.createIcons();
}
}, 100);
});
});
</script>
@endpush
@@ -136,8 +136,7 @@
<div class="input-group input-group-sm">
<span class="input-group-text">$</span>
<input type="number" step="0.01" class="form-control"
name="pricing[{{ $cycle->value }}][price_sale]"
placeholder="0.00">
name="pricing[{{ $cycle->value }}][price_sale]" placeholder="0.00">
</div>
</td>
</tr>
@@ -221,20 +220,6 @@
@endforeach
</select>
</div>
{{-- Operating System --}}
<div class="form-group mb-3">
<label for="os_ids" class="mb-2">Operating System</label>
<select class="form-control select2" name="os_ids[]" id="os_ids" multiple data-placeholder="-- Select OS versions --">
@foreach ($osVersions as $osVersion)
<option value="{{ $osVersion->id }}" {{ in_array($osVersion->id, old('os_ids', [])) ? 'selected' : '' }}>
{{ $osVersion->osGroup->name ?? 'Unknown' }} - {{ $osVersion->version }}
</option>
@endforeach
</select>
<small class="text-muted">Select multiple OS versions supported by this product</small>
</div>
{{-- Product Type --}}
<div class="form-group mb-3">
<label for="product_type" class="mb-2">Product Type</label>
@@ -248,6 +233,59 @@
@endforeach
</select>
</div>
{{-- Operating System (for VPS) --}}
<div class="form-group mb-3" id="os-section">
<label for="os_ids" class="mb-2">Operating System</label>
<select class="form-control select2" name="os_ids[]" id="os_ids" multiple
data-placeholder="-- Select OS versions --">
@foreach ($osVersions as $osVersion)
<option value="{{ $osVersion->id }}"
{{ in_array($osVersion->id, old('os_ids', [])) ? 'selected' : '' }}>
{{ $osVersion->osGroup->name ?? 'Unknown' }} - {{ $osVersion->version }}
</option>
@endforeach
</select>
<small class="text-muted">Select multiple OS versions supported by this product</small>
</div>
{{-- Control Panels (for Hosting) --}}
<div class="form-group mb-3" id="control-panel-section">
<label for="control_panel_ids" class="mb-2">Control Panels</label>
<select class="form-control select2" name="control_panel_ids[]" id="control_panel_ids"
multiple data-placeholder="-- Select Control Panels --">
@foreach ($controlPanels as $panel)
<option value="{{ $panel->id }}"
{{ in_array($panel->id, old('control_panel_ids', [])) ? 'selected' : '' }}>
{{ $panel->name }}
</option>
@endforeach
</select>
<small class="text-muted">Select control panels available for this hosting product</small>
{{-- Price modifiers for each panel --}}
<div id="panel-price-modifiers" class="mt-3">
@foreach ($controlPanels as $panel)
<div class="panel-price-row mb-2" id="panel-price-{{ $panel->id }}"
style="display: none;">
<label class="form-label">{{ $panel->name }} - Phụ phí (VNĐ)</label>
<div class="input-group">
<input type="number" class="form-control"
name="control_panel_price_modifiers[{{ $panel->id }}]" placeholder="0"
min="0" step="1000"
value="{{ old('control_panel_price_modifiers.' . $panel->id, 0) }}">
<div class="input-group-append">
<div class="input-group-text">
<input type="radio" name="control_panel_default"
value="{{ $panel->id }}"
{{ old('control_panel_default') == $panel->id ? 'checked' : '' }}>
<span class="ms-1">Mặc định</span>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
{{-- Status --}}
<div class="form-group mb-3">
@@ -316,6 +354,51 @@
if ($(".select2").length) {
$(".select2").select2();
}
// Toggle OS/Control Panel sections based on Product Type
function toggleProductSections() {
const productType = $('#product_type').val();
if (productType === 'hosting') {
$('#os-section').hide();
$('#control-panel-section').show();
} else if (productType === 'vps') {
$('#os-section').show();
$('#control-panel-section').hide();
} else {
// For addon, domain, or empty
$('#os-section').hide();
$('#control-panel-section').hide();
}
}
// Show/hide price modifier inputs when panels are selected
$('#control_panel_ids').on('change', function() {
const selectedPanels = $(this).val() || [];
$('.panel-price-row').hide();
selectedPanels.forEach(function(panelId) {
$('#panel-price-' + panelId).show();
});
// Clear unselected panels
$('.panel-price-row').each(function() {
const panelId = $(this).attr('id').replace('panel-price-', '');
if (!selectedPanels.includes(panelId)) {
$(this).find('input[type="number"]').val(0);
$(this).find('input[type="radio"]').prop('checked', false);
}
});
});
// Initial toggle on page load
toggleProductSections();
// Toggle when product type changes
$('#product_type').on('change', toggleProductSections);
// Trigger initial panel price display
$('#control_panel_ids').trigger('change');
});
</script>
<script src="{{ asset('lib/ckeditor/ckeditor.js') }}"></script>
@@ -220,8 +220,8 @@
</select>
</div>
{{-- Operating System --}}
<div class="form-group mb-3">
{{-- Operating System (for VPS) --}}
<div class="form-group mb-3" id="os-section">
<label for="os_ids" class="mb-2">Operating System</label>
@php
$selectedOsIds = old('os_ids', $product->osVersions->pluck('id')->toArray());
@@ -237,6 +237,54 @@
</select>
<small class="text-muted">Select multiple OS versions supported by this product</small>
</div>
{{-- Control Panels (for Hosting) --}}
<div class="form-group mb-3" id="control-panel-section" style="display: none;">
<label for="control_panel_ids" class="mb-2">Control Panels</label>
@php
$selectedPanelIds = old('control_panel_ids', $product->controlPanels->pluck('id')->toArray());
$panelPriceModifiers = old('control_panel_price_modifiers',
$product->controlPanels->pluck('pivot.price_modifier', 'id')->toArray());
$defaultPanel = old('control_panel_default',
$product->controlPanels->where('pivot.is_default', true)->first()?->id);
@endphp
<select class="form-control select2" name="control_panel_ids[]" id="control_panel_ids" multiple data-placeholder="-- Select Control Panels --">
@foreach ($controlPanels as $panel)
<option value="{{ $panel->id }}" {{ in_array($panel->id, $selectedPanelIds) ? 'selected' : '' }}>
{{ $panel->name }}
</option>
@endforeach
</select>
<small class="text-muted">Select control panels available for this hosting product</small>
{{-- Price modifiers for each panel --}}
<div id="panel-price-modifiers" class="mt-3">
@foreach ($controlPanels as $panel)
<div class="panel-price-row mb-2" id="panel-price-{{ $panel->id }}"
style="display: {{ in_array($panel->id, $selectedPanelIds) ? 'block' : 'none' }};">
<label class="form-label">{{ $panel->name }} - Phụ phí (VNĐ)</label>
<div class="input-group">
<input type="number"
class="form-control"
name="control_panel_price_modifiers[{{ $panel->id }}]"
placeholder="0"
min="0"
step="1000"
value="{{ $panelPriceModifiers[$panel->id] ?? 0 }}">
<div class="input-group-append">
<div class="input-group-text">
<input type="radio"
name="control_panel_default"
value="{{ $panel->id }}"
{{ $defaultPanel == $panel->id ? 'checked' : '' }}>
<span class="ms-1">Mặc định</span>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
{{-- Product Type --}}
<div class="form-group mb-3">
@@ -320,6 +368,51 @@
if ($(".select2").length) {
$(".select2").select2();
}
// Toggle OS/Control Panel sections based on Product Type
function toggleProductSections() {
const productType = $('#product_type').val();
if (productType === 'hosting') {
$('#os-section').hide();
$('#control-panel-section').show();
} else if (productType === 'vps') {
$('#os-section').show();
$('#control-panel-section').hide();
} else {
// For addon, domain, or empty
$('#os-section').hide();
$('#control-panel-section').hide();
}
}
// Show/hide price modifier inputs when panels are selected
$('#control_panel_ids').on('change', function() {
const selectedPanels = $(this).val() || [];
$('.panel-price-row').hide();
selectedPanels.forEach(function(panelId) {
$('#panel-price-' + panelId).show();
});
// Clear unselected panels
$('.panel-price-row').each(function() {
const panelId = $(this).attr('id').replace('panel-price-', '');
if (!selectedPanels.includes(panelId)) {
$(this).find('input[type="number"]').val(0);
$(this).find('input[type="radio"]').prop('checked', false);
}
});
});
// Initial toggle on page load
toggleProductSections();
// Toggle when product type changes
$('#product_type').on('change', toggleProductSections);
// Trigger initial panel price display
$('#control_panel_ids').trigger('change');
});
</script>
<script src="{{ asset('lib/ckeditor/ckeditor.js') }}"></script>