Add CAM tagging to movies
Store a CAM flag in the movie model and expose it via the admin add/edit flow, then render a CAM badge on movie posters in the films page.
This commit is contained in:
@@ -653,6 +653,12 @@
|
||||
<label for="category" class="form-label">Catégorie</label>
|
||||
<input type="text" class="form-control" id="category" placeholder="Best Picture, etc." required>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 d-flex align-items-end">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="cam_flag">
|
||||
<label class="form-check-label" for="cam_flag">Tag CAM</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="accordion" id="adminAddMovieAccordion">
|
||||
@@ -1314,6 +1320,12 @@
|
||||
<label for="edit_rating" class="form-label">Rating (imdbRating)</label>
|
||||
<input type="text" class="form-control" id="edit_rating" placeholder="7.9">
|
||||
</div>
|
||||
<div class="col-md-6 d-flex align-items-end">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="edit_cam_flag">
|
||||
<label class="form-check-label" for="edit_cam_flag">Tag CAM</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
|
||||
@@ -220,6 +220,10 @@ footer {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.cam-badge {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Stats → "Films regardés" modal */
|
||||
.stats-movies-grid {
|
||||
display: grid;
|
||||
|
||||
@@ -118,6 +118,7 @@ window.onload = async function () {
|
||||
const editRatingEl = document.getElementById('edit_rating');
|
||||
const editPosterEl = document.getElementById('edit_poster');
|
||||
const editDescriptionEl = document.getElementById('edit_description');
|
||||
const editCamFlagEl = document.getElementById('edit_cam_flag');
|
||||
|
||||
let moviesById = new Map();
|
||||
let activeYear = null;
|
||||
@@ -1921,6 +1922,7 @@ window.onload = async function () {
|
||||
const year = parseYear(yearInput.value);
|
||||
const imdb_id = document.getElementById('imdb_id').value.trim();
|
||||
const category = document.getElementById('category').value.trim();
|
||||
const cam = !!document.getElementById('cam_flag')?.checked;
|
||||
const vod_link = document.getElementById('vod_link').value.trim();
|
||||
const player_mode = (document.getElementById('player_mode')?.value || 'auto').trim();
|
||||
const video_src = document.getElementById('video_src')?.value?.trim() || '';
|
||||
@@ -1944,7 +1946,7 @@ window.onload = async function () {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ year, imdb_id, category, vod_link, player_mode, video_src, video_file, embed_src })
|
||||
body: JSON.stringify({ year, imdb_id, category, vod_link, player_mode, video_src, video_file, embed_src, cam })
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
@@ -2199,6 +2201,7 @@ window.onload = async function () {
|
||||
editRatingEl.value = movie.rating || '';
|
||||
editPosterEl.value = movie.poster || '';
|
||||
editDescriptionEl.value = movie.description || '';
|
||||
if (editCamFlagEl) editCamFlagEl.checked = !!movie.cam;
|
||||
|
||||
if (editMovieModalTitleEl) {
|
||||
const label = movie.title ? `Modifier: ${movie.title}` : 'Modifier le film';
|
||||
@@ -2221,6 +2224,7 @@ window.onload = async function () {
|
||||
const video_file = (editVideoFileEl?.value || '').trim();
|
||||
const embed_src = (editEmbedSrcEl?.value || '').trim();
|
||||
const refreshOmdb = !!editRefreshOmdbEl.checked;
|
||||
const cam = !!editCamFlagEl?.checked;
|
||||
|
||||
const title = editTitleEl.value;
|
||||
const rating = editRatingEl.value;
|
||||
@@ -2255,7 +2259,8 @@ window.onload = async function () {
|
||||
video_src,
|
||||
video_file,
|
||||
embed_src,
|
||||
refreshOmdb
|
||||
refreshOmdb,
|
||||
cam
|
||||
};
|
||||
|
||||
// Only send manual fields if we're not refreshing from OMDb
|
||||
|
||||
+10
-6
@@ -448,6 +448,14 @@ window.addEventListener('DOMContentLoaded', async function () {
|
||||
}
|
||||
}
|
||||
|
||||
const camBadge = movie?.cam ? '<span class="badge bg-warning text-dark position-absolute top-0 end-0 m-2 cam-badge">CAM</span>' : '';
|
||||
const posterBlock = `
|
||||
<div class="text-center pt-3 px-3 position-relative movie-poster-wrap">
|
||||
${camBadge}
|
||||
<img src="${movie.poster}" class="img-fluid rounded movie-poster" alt="${movie.title}">
|
||||
</div>
|
||||
`;
|
||||
|
||||
const movieDiv = document.createElement('div');
|
||||
movieDiv.classList.add('col-12', 'col-sm-6', 'col-lg-4', 'movie-card');
|
||||
movieDiv.setAttribute('data-imdb-id', movie.imdb_id);
|
||||
@@ -457,13 +465,9 @@ window.addEventListener('DOMContentLoaded', async function () {
|
||||
${
|
||||
isClickable
|
||||
? `<a href="${playerUrl}" target="_self" rel="noopener noreferrer" class="text-decoration-none">
|
||||
<div class="text-center pt-3 px-3">
|
||||
<img src="${movie.poster}" class="img-fluid rounded movie-poster" alt="${movie.title}">
|
||||
</div>
|
||||
${posterBlock}
|
||||
</a>`
|
||||
: `<div class="text-center pt-3 px-3">
|
||||
<img src="${movie.poster}" class="img-fluid rounded movie-poster" alt="${movie.title}">
|
||||
</div>`
|
||||
: `${posterBlock}`
|
||||
}
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="d-flex justify-content-between align-items-start gap-2">
|
||||
|
||||
Reference in New Issue
Block a user