mirror of
https://github.com/nfonteyne/octane-website.git
synced 2026-09-03 23:24:48 +02:00
update: different colors for suggested rehersal and validated rehersal
This commit is contained in:
parent
b056af78ac
commit
a3d62200ce
10 changed files with 102 additions and 24 deletions
|
|
@ -179,7 +179,14 @@ async function onRemoveFeed(feedId) {
|
|||
}
|
||||
}
|
||||
|
||||
async function loadSlotSettingsForm() {
|
||||
function hostOptionsHtml(users, selectedId) {
|
||||
const options = users.map(
|
||||
(u) => `<option value="${u.id}"${u.id === selectedId ? ' selected' : ''}>${escapeHtml(u.name)}</option>`
|
||||
);
|
||||
return `<option value=""${selectedId ? '' : ' selected'}>(aucun)</option>${options.join('')}`;
|
||||
}
|
||||
|
||||
async function loadSlotSettingsForm(users) {
|
||||
const settings = await api.get('/api/calendar/settings');
|
||||
const form = document.getElementById('slot-settings-form');
|
||||
form.weekdayStart.value = settings.weekdayStart;
|
||||
|
|
@ -190,6 +197,7 @@ async function loadSlotSettingsForm() {
|
|||
form.concertStart.value = settings.concertStart;
|
||||
form.concertEnd.value = settings.concertEnd;
|
||||
form.rehearsalConfirmThreshold.value = settings.rehearsalConfirmThreshold;
|
||||
form.rehearsalHostUserId.innerHTML = hostOptionsHtml(users, settings.rehearsalHostUserId);
|
||||
}
|
||||
|
||||
async function onSaveSlotSettings(e) {
|
||||
|
|
@ -207,6 +215,7 @@ async function onSaveSlotSettings(e) {
|
|||
concertStart: form.concertStart.value,
|
||||
concertEnd: form.concertEnd.value,
|
||||
rehearsalConfirmThreshold: parseInt(form.rehearsalConfirmThreshold.value, 10),
|
||||
rehearsalHostUserId: form.rehearsalHostUserId.value || null,
|
||||
});
|
||||
statusEl.textContent = 'Horaires enregistrés.';
|
||||
} catch (err) {
|
||||
|
|
@ -277,6 +286,14 @@ async function onSaveSlotSettings(e) {
|
|||
n'est pas atteint ; elle passe ensuite en répétition confirmée (dans l'application et dans le
|
||||
flux ICS).
|
||||
</p>
|
||||
<label>Hôte des répétitions (⭐)
|
||||
<select name="rehearsalHostUserId"></select>
|
||||
</label>
|
||||
<p class="note">
|
||||
Si un hôte est désigné, une répétition ne peut être confirmée que si cette personne a elle-même
|
||||
accepté le créneau — sans elle, pas de lieu pour répéter. Choisissez « (aucun) » pour désactiver
|
||||
cette contrainte.
|
||||
</p>
|
||||
<p class="note" id="slot-settings-status"></p>
|
||||
<button type="submit">Enregistrer</button>
|
||||
</form>
|
||||
|
|
@ -310,7 +327,7 @@ async function onSaveSlotSettings(e) {
|
|||
`;
|
||||
document.getElementById('slot-settings-form').addEventListener('submit', onSaveSlotSettings);
|
||||
document.getElementById('add-discord-webhook-form').addEventListener('submit', onAddDiscordWebhook);
|
||||
await loadSlotSettingsForm();
|
||||
await loadSlotSettingsForm(stats.users);
|
||||
await loadCalendarUsers();
|
||||
await loadDiscordWebhooks();
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -216,9 +216,10 @@ function renderCalendar() {
|
|||
|
||||
const rehearsal = rehearsalsByDate.get(isoDate(date));
|
||||
if (rehearsal) {
|
||||
cell.classList.add('has-rehearsal');
|
||||
const isConfirmed = rehearsal.status === 'confirmed';
|
||||
cell.classList.add('has-rehearsal', isConfirmed ? 'rehearsal-confirmed' : 'rehearsal-suggested');
|
||||
const badge = document.createElement('span');
|
||||
badge.title = 'Répétition proposée';
|
||||
badge.title = isConfirmed ? 'Répétition confirmée' : 'Répétition proposée (en attente de votes)';
|
||||
badge.textContent = '🎸';
|
||||
badges.appendChild(badge);
|
||||
}
|
||||
|
|
@ -488,13 +489,29 @@ function rehearsalVoteActionsHtml(r) {
|
|||
`;
|
||||
}
|
||||
|
||||
function rehearsalVoterHtml(v, r) {
|
||||
const isHost = r.hostUserId && v.userId === r.hostUserId;
|
||||
const name = isHost ? `${v.name} ⭐` : v.name;
|
||||
return `${avatarHtml({ name: v.name, avatarUrl: v.avatarUrl }, 'avatar-sm')}<span>${escapeHtml(name)}</span>`;
|
||||
}
|
||||
|
||||
function rehearsalAcceptedByHtml(r) {
|
||||
const accepted = r.votes.filter((v) => v.vote === 'accept');
|
||||
if (!accepted.length) return '';
|
||||
const refused = r.votes.filter((v) => v.vote === 'reject');
|
||||
if (!accepted.length && !refused.length) return '';
|
||||
return `
|
||||
<div class="rehearsal-accepted-by">
|
||||
${accepted.map((v) => `${avatarHtml({ name: v.name, avatarUrl: v.avatarUrl }, 'avatar-sm')}<span>${escapeHtml(v.name)}</span>`).join('')}
|
||||
</div>
|
||||
${accepted.length ? `
|
||||
<div class="rehearsal-accepted-by">
|
||||
<span class="note">Ont accepté :</span>
|
||||
${accepted.map((v) => rehearsalVoterHtml(v, r)).join('')}
|
||||
</div>
|
||||
` : ''}
|
||||
${refused.length ? `
|
||||
<div class="rehearsal-accepted-by rehearsal-refused-by">
|
||||
<span class="note">Ont refusé :</span>
|
||||
${refused.map((v) => rehearsalVoterHtml(v, r)).join('')}
|
||||
</div>
|
||||
` : ''}
|
||||
`;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue