| Server IP : 46.105.57.169 / Your IP : 216.73.216.67 Web Server : Apache System : Linux webm002.cluster120.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64 User : verseaumee ( 152031) PHP Version : 8.5.7 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/verseaumee/quaadraa/admin/views/ |
Upload File : |
<div class="admin-breadcrumb">
<a href="/admin/news">← Toutes les actualités</a>
<span>/ Modifier</span>
</div>
<?php if (!empty($success)): ?>
<div class="alert alert-success">✅ Article mis à jour avec succès.</div>
<?php endif; ?>
<?php if (!empty($errors)): ?>
<div class="alert alert-error">
<?php foreach ($errors as $err): ?><p>❌ <?= htmlspecialchars($err) ?></p><?php endforeach; ?>
</div>
<?php endif; ?>
<form method="POST" action="/admin/news/<?= (int)$article['id'] ?>/edit" class="admin-form" enctype="multipart/form-data">
<input type="hidden" name="_csrf" value="<?= htmlspecialchars($csrf) ?>">
<input type="hidden" name="action" value="update">
<div class="form-cols">
<div class="form-col-main">
<div class="adm-field <?= isset($errors['title']) ? 'has-error' : '' ?>">
<label for="title">Titre *</label>
<input type="text" id="title" name="title" required
value="<?= htmlspecialchars($article['title'] ?? '') ?>"
placeholder="Titre de l'actualité">
<?php if (isset($errors['title'])): ?>
<span class="field-error"><?= htmlspecialchars($errors['title']) ?></span>
<?php endif; ?>
</div>
<div class="adm-field">
<label for="slug">Slug (URL)</label>
<input type="text" id="slug" name="slug"
value="<?= htmlspecialchars($article['slug'] ?? '') ?>"
placeholder="slug-de-l-article"
style="font-family:monospace;font-size:.85rem">
<small style="color:#5e5e5e;font-size:.72rem;margin-top:.25rem;display:block">
URL : /fr/actualites/<strong><?= htmlspecialchars($article['slug'] ?? '') ?></strong>
</small>
</div>
<div class="adm-field">
<label for="excerpt">Extrait <span style="color:#5e5e5e;font-weight:400">(affiché dans les listes)</span></label>
<textarea id="excerpt" name="excerpt" rows="3"
placeholder="Résumé court de l'article…"><?= htmlspecialchars($article['excerpt'] ?? '') ?></textarea>
</div>
<div class="adm-field <?= isset($errors['content']) ? 'has-error' : '' ?>">
<label for="content">
Contenu *
<span style="color:#5e5e5e;font-weight:400">(HTML accepté)</span>
</label>
<div class="editor-toolbar" aria-label="Outils de formatage rapide">
<button type="button" class="ed-btn" data-tag="strong" title="Gras"><b>B</b></button>
<button type="button" class="ed-btn" data-tag="em" title="Italique"><i>I</i></button>
<button type="button" class="ed-btn" data-tag="h2" title="Titre H2">H2</button>
<button type="button" class="ed-btn" data-tag="h3" title="Titre H3">H3</button>
<button type="button" class="ed-btn" data-tag="p" title="Paragraphe">¶</button>
<button type="button" class="ed-btn" data-tag="ul" title="Liste">☰</button>
<button type="button" class="ed-btn" data-tag="a" title="Lien">🔗</button>
<button type="button" class="ed-btn" data-tag="blockquote" title="Citation">❝</button>
</div>
<textarea id="content" name="content" rows="18"
placeholder="<p>Contenu de l'article…</p>"><?= htmlspecialchars($article['content'] ?? '') ?></textarea>
<?php if (isset($errors['content'])): ?>
<span class="field-error"><?= htmlspecialchars($errors['content']) ?></span>
<?php endif; ?>
</div>
<div class="adm-field">
<label>Aperçu du contenu</label>
<div class="content-preview" id="content-preview">
<?= $article['content'] ?? '<p style="color:#5e5e5e;font-style:italic">L\'aperçu apparaîtra ici…</p>' ?>
</div>
</div>
</div>
<div class="form-col-aside">
<div class="aside-card">
<h3 class="aside-card-title">Publication</h3>
<div class="adm-field">
<label class="checkbox-label">
<input type="checkbox" name="is_published" value="1"
<?= !empty($article['is_published']) ? 'checked' : '' ?>>
<span>Publié</span>
</label>
</div>
<div class="adm-field">
<label class="checkbox-label">
<input type="checkbox" name="is_featured" value="1"
<?= !empty($article['is_featured']) ? 'checked' : '' ?>>
<span>À la une (bannière accueil)</span>
</label>
</div>
<div class="adm-field" style="margin-top:1rem">
<label for="published_at">Date de publication</label>
<input type="datetime-local" id="published_at" name="published_at"
value="<?= !empty($article['published_at'])
? date('Y-m-d\TH:i', strtotime($article['published_at']))
: date('Y-m-d\TH:i') ?>">
</div>
<div class="adm-actions">
<button type="submit" class="adm-btn adm-btn-primary">
💾 Enregistrer les modifications
</button>
<a href="/fr/actualites/<?= htmlspecialchars($article['slug'] ?? '') ?>"
target="_blank" class="adm-btn" style="text-align:center">
👁 Voir l'article
</a>
</div>
</div>
<div class="aside-card" style="margin-top:1rem">
<h3 class="aside-card-title">Paramètres</h3>
<div class="adm-field">
<label for="lang">Langue</label>
<select id="lang" name="lang">
<option value="fr" <?= ($article['lang'] ?? 'fr') === 'fr' ? 'selected' : '' ?>>🇫🇷 Français</option>
<option value="en" <?= ($article['lang'] ?? '') === 'en' ? 'selected' : '' ?>>🇬🇧 English</option>
</select>
</div>
<div class="adm-field">
<label for="subsidiary_id">Filiale concernée</label>
<select id="subsidiary_id" name="subsidiary_id">
<option value="">— Aucune —</option>
<?php foreach ($subs as $s): ?>
<option value="<?= $s['id'] ?>"
<?= ($article['subsidiary_id'] ?? '') == $s['id'] ? 'selected' : '' ?>>
<?= htmlspecialchars($s['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="adm-field">
<label for="cover_image">Image de couverture (remplacer)</label>
<input type="file" id="cover_image" name="cover_image" accept="image/*">
<input type="hidden" name="current_cover_image" value="<?= htmlspecialchars($article['cover_image'] ?? '') ?>">
<input type="hidden" name="cover_image_url" value="<?= htmlspecialchars($article['cover_image'] ?? '') ?>">
</div>
<?php if (!empty($article['cover_image'])): ?>
<div class="current-cover" style="margin-bottom:1rem">
<p style="font-size:0.7rem; color:#8e8e8e; margin-bottom:.5rem;">Image actuelle :</p>
<img src="<?= htmlspecialchars($article['cover_image']) ?>"
alt="Image actuelle" style="max-width:100%;height:120px;object-fit:cover;border:1px solid #3a3a3a;">
<label class="checkbox-label" style="margin-top:.5rem">
<input type="checkbox" name="remove_cover" value="1">
<span style="color:#e74c3c">Supprimer l'image</span>
</label>
</div>
<?php endif; ?>
<div class="aside-card danger-card" style="margin-top:1rem">
<h3 class="aside-card-title" style="color:#e74c3c">Zone dangereuse</h3>
<p style="font-size:.78rem;color:#5e5e5e;margin-bottom:1rem">
La suppression est irréversible.
</p>
<button type="button" class="adm-btn adm-btn-danger" id="delete-btn"
data-id="<?= (int)$article['id'] ?>"
data-title="<?= htmlspecialchars($article['title'] ?? '') ?>">
🗑 Supprimer cet article
</button>
</div>
</div>
</div>
</form>
<div class="delete-modal" id="delete-modal" hidden>
<div class="delete-modal-box">
<h3>Confirmer la suppression</h3>
<p>Supprimer définitivement :<br><strong id="delete-modal-title"></strong></p>
<div class="delete-modal-actions">
<button type="button" id="delete-confirm" class="adm-btn adm-btn-danger">Oui, supprimer</button>
<button type="button" id="delete-cancel" class="adm-btn">Annuler</button>
</div>
</div>
</div>
<div class="delete-modal-backdrop" id="delete-modal-backdrop" hidden></div>
<style>
.admin-breadcrumb {
margin-bottom: 1.5rem; font-size: .82rem; color: #5e5e5e;
}
.admin-breadcrumb a { color: #C9A84C; }
.admin-breadcrumb span { margin-left: .5rem; }
.form-cols { display: grid; grid-template-columns: 1fr 280px; gap: 2rem; align-items: start; }
@media(max-width:900px){ .form-cols{grid-template-columns:1fr;} }
.adm-field { margin-bottom: 1.25rem; }
.adm-field label {
display: block; font-size: .72rem; font-weight: 700;
letter-spacing: .1em; text-transform: uppercase; color: #8e8e8e; margin-bottom: .4rem;
}
.adm-field input[type="text"],
.adm-field input[type="url"],
.adm-field input[type="datetime-local"],
.adm-field textarea,
.adm-field select {
width: 100%; padding: .7rem 1rem;
background: #1c1c1c; border: 1px solid #3a3a3a;
color: #f0ece4; font-family: inherit; font-size: .9rem;
transition: border-color .2s; resize: vertical;
}
.adm-field input:focus, .adm-field textarea:focus, .adm-field select:focus {
outline: none; border-color: #C9A84C;
}
.adm-field.has-error input,
.adm-field.has-error textarea { border-color: #c0392b; }
.field-error { font-size: .75rem; color: #c0392b; display: block; margin-top: .25rem; }
.checkbox-label { display: flex; align-items: center; gap: .6rem; cursor: pointer; color: #8e8e8e; font-size: .88rem; }
.checkbox-label input { accent-color: #C9A84C; width: 15px; height: 15px; }
.editor-toolbar {
display: flex; flex-wrap: wrap; gap: .4rem;
padding: .5rem; background: #111; border: 1px solid #3a3a3a;
border-bottom: none;
}
.ed-btn {
padding: .3rem .65rem; background: #1c1c1c; border: 1px solid #3a3a3a;
color: #8e8e8e; font-size: .78rem; font-weight: 700; cursor: pointer;
transition: all .2s; font-family: monospace;
}
.ed-btn:hover { background: #C9A84C; border-color: #C9A84C; color: #000; }
#content { border-top: none; }
.content-preview {
padding: 1.25rem; background: #111; border: 1px solid #2a2a2a;
min-height: 80px; font-size: .88rem; line-height: 1.7; color: #8e8e8e;
max-height: 300px; overflow-y: auto;
}
.content-preview h2, .content-preview h3 { color: #f0ece4; margin: 1rem 0 .5rem; }
.content-preview p { margin-bottom: .75rem; }
.content-preview a { color: #C9A84C; }
.content-preview blockquote {
border-left: 3px solid #C9A84C; padding-left: 1rem; color: #5e5e5e; font-style: italic;
}
.aside-card {
background: #1c1c1c; border: 1px solid #2a2a2a; padding: 1.25rem;
}
.aside-card-title {
font-size: .72rem; font-weight: 700; letter-spacing: .15em;
text-transform: uppercase; color: #8e8e8e;
margin: 0 0 1rem; padding-bottom: .6rem; border-bottom: 1px solid #2a2a2a;
}
.adm-actions { display: flex; flex-direction: column; gap: .6rem; margin-top: 1.25rem; }
.adm-btn {
display: block; width: 100%; padding: .75rem; text-align: center;
font-size: .8rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
border: 1px solid #3a3a3a; color: #8e8e8e; cursor: pointer;
background: none; transition: all .2s; text-decoration: none;
}
.adm-btn:hover { border-color: #5e5e5e; color: #f0ece4; }
.adm-btn-primary { background: #C9A84C; border-color: #C9A84C; color: #0d0d0d; }
.adm-btn-primary:hover { background: #e0c47a; border-color: #e0c47a; color: #0d0d0d; }
.adm-btn-danger { border-color: #c0392b; color: #c0392b; }
.adm-btn-danger:hover { background: #c0392b; color: #fff; }
.danger-card { border-color: rgba(192,57,43,.25); }
.alert { padding: .85rem 1.25rem; margin-bottom: 1.5rem; font-size: .88rem; border-radius: 0; }
.alert-success { background: rgba(39,174,96,.1); border: 1px solid rgba(39,174,96,.3); color: #27ae60; }
.alert-error { background: rgba(192,57,43,.1); border: 1px solid rgba(192,57,43,.3); color: #e74c3c; }
.delete-modal {
position: fixed; inset: 0; z-index: 2000;
display: flex; align-items: center; justify-content: center;
}
.delete-modal[hidden] { display: none; }
.delete-modal-box {
background: #1c1c1c; border: 1px solid #c0392b;
padding: 2rem; max-width: 400px; width: 90%; position: relative; z-index: 2001;
text-align: center;
}
.delete-modal-box h3 { color: #e74c3c; margin-bottom: 1rem; font-size: 1rem; }
.delete-modal-box p { color: #8e8e8e; font-size: .88rem; line-height: 1.6; margin-bottom: 1.5rem; }
.delete-modal-box strong { color: #f0ece4; }
.delete-modal-actions { display: flex; gap: .75rem; justify-content: center; }
.delete-modal-actions .adm-btn { flex: 1; }
.delete-modal-backdrop {
position: fixed; inset: 0; z-index: 2000;
background: rgba(0,0,0,.75);
}
.delete-modal-backdrop[hidden] { display: none; }
</style>
<script>
(function () {
const contentArea = document.getElementById('content');
const preview = document.getElementById('content-preview');
if (contentArea && preview) {
const updatePreview = () => {
const html = contentArea.value.trim();
preview.innerHTML = html || '<p style="color:#5e5e5e;font-style:italic">L\'aperçu apparaîtra ici…</p>';
};
contentArea.addEventListener('input', updatePreview);
updatePreview();
}
document.querySelectorAll('.ed-btn').forEach(btn => {
btn.addEventListener('click', () => {
const tag = btn.dataset.tag;
const start = contentArea.selectionStart;
const end = contentArea.selectionEnd;
const sel = contentArea.value.substring(start, end);
let insertion = '';
if (tag === 'a') {
const href = prompt('URL du lien :', 'https://');
if (!href) return;
insertion = `<a href="${href}">${sel || 'Texte du lien'}</a>`;
} else if (tag === 'ul') {
insertion = `<ul>\n <li>${sel || 'Élément 1'}</li>\n <li>Élément 2</li>\n</ul>`;
} else if (tag === 'p') {
insertion = `<p>${sel || 'Votre texte…'}</p>`;
} else {
insertion = `<${tag}>${sel || 'Texte'}</${tag}>`;
}
contentArea.setRangeText(insertion, start, end, 'end');
contentArea.dispatchEvent(new Event('input'));
contentArea.focus();
});
});
const deleteBtn = document.getElementById('delete-btn');
const deleteModal = document.getElementById('delete-modal');
const deleteBackdrop = document.getElementById('delete-modal-backdrop');
const deleteConfirm = document.getElementById('delete-confirm');
const deleteCancel = document.getElementById('delete-cancel');
const modalTitle = document.getElementById('delete-modal-title');
deleteBtn?.addEventListener('click', () => {
modalTitle.textContent = deleteBtn.dataset.title;
deleteModal.hidden = false;
deleteBackdrop.hidden = false;
});
const closeModal = () => {
deleteModal.hidden = true;
deleteBackdrop.hidden = true;
};
deleteCancel?.addEventListener('click', closeModal);
deleteBackdrop?.addEventListener('click', closeModal);
deleteConfirm?.addEventListener('click', () => {
const id = deleteBtn.dataset.id;
const form = document.createElement('form');
form.method = 'POST';
form.action = `/admin/news/${id}/delete`;
form.innerHTML = `
<input type="hidden" name="_csrf" value="${document.querySelector('[name="_csrf"]').value}">
<input type="hidden" name="action" value="delete">
`;
document.body.appendChild(form);
form.submit();
});
document.addEventListener('keydown', e => {
if (e.key === 'Escape') closeModal();
});
})();
</script>