feat: Add banner management functionality
- Implemented a new Banner model to represent banner data. - Created a BannerRepository for database interactions related to banners. - Developed a BannerService to handle business logic for banners. - Added admin views for listing and adding banners. - Integrated banner hooks for frontend rendering and click tracking. - Created frontend styles and scripts for banner display and interaction. - Updated database migrations to include a new banners table. - Enhanced AdminController to manage banner actions and pages.
This commit is contained in:
75
admin/js/banner-admin.js
Normal file
75
admin/js/banner-admin.js
Normal file
@@ -0,0 +1,75 @@
|
||||
(function () {
|
||||
const contentTypeRadios = document.querySelectorAll('.sodino-banner-content-type');
|
||||
const contentGroups = document.querySelectorAll('.sodino-banner-content-group');
|
||||
const mediaButton = document.getElementById('sodino-banner-image-upload');
|
||||
const imageInput = document.getElementById('content_value_image');
|
||||
const presetButtons = document.querySelectorAll('.sodino-banner-preset');
|
||||
const startInput = document.getElementById('start_time');
|
||||
const endInput = document.getElementById('end_time');
|
||||
|
||||
function toggleFields() {
|
||||
const selectedType = document.querySelector('.sodino-banner-content-type:checked');
|
||||
const type = selectedType ? selectedType.value : 'image';
|
||||
contentGroups.forEach((group) => {
|
||||
group.style.display = group.dataset.type === type ? 'block' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
if (contentTypeRadios.length) {
|
||||
contentTypeRadios.forEach((radio) => radio.addEventListener('change', toggleFields));
|
||||
toggleFields();
|
||||
}
|
||||
|
||||
if (mediaButton && imageInput && window.wp && wp.media) {
|
||||
mediaButton.addEventListener('click', function () {
|
||||
const mediaFrame = wp.media({
|
||||
title: 'انتخاب تصویر بنر',
|
||||
button: { text: 'انتخاب' },
|
||||
multiple: false,
|
||||
});
|
||||
|
||||
mediaFrame.on('select', function () {
|
||||
const attachment = mediaFrame.state().get('selection').first().toJSON();
|
||||
imageInput.value = attachment.url;
|
||||
});
|
||||
|
||||
mediaFrame.open();
|
||||
});
|
||||
}
|
||||
|
||||
const setDatetimeLocal = (element, date) => {
|
||||
if (!element) return;
|
||||
const tzOffset = date.getTimezoneOffset() * 60000;
|
||||
const localISO = new Date(date - tzOffset).toISOString().slice(0, 16);
|
||||
element.value = localISO;
|
||||
};
|
||||
|
||||
if (presetButtons.length) {
|
||||
presetButtons.forEach((button) => {
|
||||
button.addEventListener('click', function () {
|
||||
const preset = this.dataset.preset;
|
||||
const now = new Date();
|
||||
if (preset === 'today') {
|
||||
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0);
|
||||
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59);
|
||||
setDatetimeLocal(startInput, start);
|
||||
setDatetimeLocal(endInput, end);
|
||||
}
|
||||
if (preset === 'weekend') {
|
||||
const friday = new Date(now);
|
||||
friday.setDate(friday.getDate() + ((5 - friday.getDay() + 7) % 7));
|
||||
const saturday = new Date(friday);
|
||||
saturday.setDate(friday.getDate() + 1);
|
||||
setDatetimeLocal(startInput, new Date(friday.getFullYear(), friday.getMonth(), friday.getDate(), 0, 0));
|
||||
setDatetimeLocal(endInput, new Date(saturday.getFullYear(), saturday.getMonth(), saturday.getDate(), 23, 59));
|
||||
}
|
||||
if (preset === 'hourly') {
|
||||
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 18, 0);
|
||||
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 0);
|
||||
setDatetimeLocal(startInput, start);
|
||||
setDatetimeLocal(endInput, end);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user