Améliore l'édition du site public
This commit is contained in:
parent
e786756f22
commit
81f259ea6e
11 changed files with 123 additions and 26 deletions
|
|
@ -11,20 +11,20 @@
|
|||
<div class="card mb-3">
|
||||
<div class="card-header"><h3 class="card-title">🖼️ <?= h(t('public_site.image_library')) ?></h3></div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="/settings/public-site/image" enctype="multipart/form-data" class="row g-2 align-items-end mb-3">
|
||||
<form id="public-image-upload" method="post" action="/settings/public-site/image" enctype="multipart/form-data" class="row g-2 align-items-end mb-3">
|
||||
<input type="hidden" name="csrf" value="<?= h(Auth::csrf()) ?>">
|
||||
<div class="col-md"><label class="form-label"><?= h(t('public_site.image_file')) ?></label><input class="form-control" type="file" name="public_site_image" accept="image/jpeg,image/png,image/webp" required></div>
|
||||
<div class="col-md-auto"><button class="btn btn-outline-primary"><?= h(t('public_site.image_upload')) ?></button></div>
|
||||
</form>
|
||||
<div class="form-hint mb-3"><?= h(t('public_site.image_help')) ?></div>
|
||||
<?php if (!$images): ?><div class="text-muted"><?= h(t('public_site.image_none')) ?></div><?php else: ?>
|
||||
<div class="row g-3">
|
||||
<div class="form-hint mb-3" id="public-image-help"><?= h(t('public_site.image_help')) ?></div>
|
||||
<div class="text-muted<?= $images ? ' d-none' : '' ?>" id="public-image-empty"><?= h(t('public_site.image_none')) ?></div>
|
||||
<div class="row g-3" id="public-image-library">
|
||||
<?php foreach ($images as $image): ?><div class="col-6 col-md-3 col-xl-2">
|
||||
<div class="card h-100"><img src="<?= h($image['url']) ?>" alt="" class="card-img-top" style="height:110px;object-fit:cover">
|
||||
<div class="card-body p-2"><button type="button" class="btn btn-sm btn-outline-secondary w-100 public-image-insert" data-markup="<?= h('') ?>"><?= h(t('public_site.image_insert')) ?></button></div>
|
||||
<div class="card-body p-2"><button type="button" class="btn btn-sm btn-outline-secondary w-100 public-image-insert" data-url="<?= h($image['url']) ?>"><?= h(t('public_site.image_insert')) ?></button></div>
|
||||
</div>
|
||||
</div><?php endforeach; ?>
|
||||
</div><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post" action="/settings/public-site/save"><input type="hidden" name="csrf" value="<?= h(Auth::csrf()) ?>">
|
||||
|
|
@ -162,6 +162,17 @@
|
|||
</form>
|
||||
<script>
|
||||
let activePublicEditor = null;
|
||||
const imageLibrary = document.getElementById('public-image-library');
|
||||
const imageHelp = document.getElementById('public-image-help');
|
||||
const insertImage = (button) => {
|
||||
const textarea = activePublicEditor || document.querySelector('.public-rich-text');
|
||||
if (!textarea) return;
|
||||
const alt = window.prompt(<?= json_encode(t('public_site.image_alt_prompt'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>, '');
|
||||
if (alt === null) return;
|
||||
const safeAlt = alt.replace(/[\[\]]/g, '').trim() || <?= json_encode(t('public_site.image_default_alt'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
||||
textarea.setRangeText(`\n`, textarea.selectionStart, textarea.selectionEnd, 'end');
|
||||
textarea.focus();
|
||||
};
|
||||
document.querySelectorAll('.public-rich-text').forEach((textarea) => {
|
||||
textarea.addEventListener('focus', () => { activePublicEditor = textarea; });
|
||||
const toolbar = document.createElement('div');
|
||||
|
|
@ -181,15 +192,47 @@ document.querySelectorAll('.public-rich-text').forEach((textarea) => {
|
|||
});
|
||||
toolbar.append(button);
|
||||
});
|
||||
const imageButton = document.createElement('button');
|
||||
imageButton.type = 'button';
|
||||
imageButton.className = 'btn btn-sm btn-outline-primary';
|
||||
imageButton.textContent = <?= json_encode('🖼️ ' . t('public_site.image_insert'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
||||
imageButton.addEventListener('click', () => {
|
||||
activePublicEditor = textarea;
|
||||
imageHelp.textContent = <?= json_encode(t('public_site.image_target_selected'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
||||
imageLibrary.scrollIntoView({behavior: 'smooth', block: 'center'});
|
||||
});
|
||||
toolbar.append(imageButton);
|
||||
textarea.before(toolbar);
|
||||
});
|
||||
document.querySelectorAll('.public-image-insert').forEach((button) => {
|
||||
button.addEventListener('click', () => {
|
||||
const textarea = activePublicEditor || document.querySelector('.public-rich-text');
|
||||
if (!textarea) return;
|
||||
const start = textarea.selectionStart;
|
||||
textarea.setRangeText(button.dataset.markup + '\n', start, textarea.selectionEnd, 'end');
|
||||
textarea.focus();
|
||||
});
|
||||
button.addEventListener('click', () => insertImage(button));
|
||||
});
|
||||
document.getElementById('public-image-upload').addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
const form = event.currentTarget;
|
||||
const submit = form.querySelector('button');
|
||||
submit.disabled = true;
|
||||
try {
|
||||
const response = await fetch(form.action, {method: 'POST', headers: {'Accept': 'application/json'}, body: new FormData(form)});
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.error || <?= json_encode(t('public_site.image_invalid'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>);
|
||||
const column = document.createElement('div');
|
||||
column.className = 'col-6 col-md-3 col-xl-2';
|
||||
column.innerHTML = '<div class="card h-100"><img alt="" class="card-img-top" style="height:110px;object-fit:cover"><div class="card-body p-2"><button type="button" class="btn btn-sm btn-outline-secondary w-100 public-image-insert"></button></div></div>';
|
||||
const image = column.querySelector('img');
|
||||
const insert = column.querySelector('button');
|
||||
image.src = data.url;
|
||||
insert.dataset.url = data.url;
|
||||
insert.textContent = <?= json_encode(t('public_site.image_insert'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
||||
insert.addEventListener('click', () => insertImage(insert));
|
||||
imageLibrary.prepend(column);
|
||||
document.getElementById('public-image-empty').classList.add('d-none');
|
||||
form.reset();
|
||||
insert.click();
|
||||
} catch (error) {
|
||||
window.alert(error.message);
|
||||
} finally {
|
||||
submit.disabled = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in a new issue