Make score and sport settings fully account-specific
This commit is contained in:
@@ -1174,6 +1174,41 @@ input[type="range"] {
|
||||
gap: 0.9rem;
|
||||
}
|
||||
|
||||
.preset-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.65rem;
|
||||
margin-bottom: 0.95rem;
|
||||
}
|
||||
|
||||
.preset-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
padding: 0.65rem 0.9rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(138, 210, 235, 0.22);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: var(--text);
|
||||
backdrop-filter: blur(20px);
|
||||
transition: transform 180ms ease, border-color 180ms ease, background 180ms ease;
|
||||
}
|
||||
|
||||
.preset-pill:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: rgba(139, 228, 255, 0.4);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.preset-pill img {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.preset-pill[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sport-type-card {
|
||||
gap: 0.9rem;
|
||||
}
|
||||
|
||||
+71
-19
@@ -752,11 +752,14 @@
|
||||
const list = document.querySelector("[data-sport-type-list]");
|
||||
const addButton = document.querySelector("[data-add-sport-type]");
|
||||
const template = document.querySelector("#sport-type-row-template");
|
||||
const presetButtons = [...document.querySelectorAll("[data-sport-preset]")];
|
||||
|
||||
if (!list || !addButton || !template) {
|
||||
return;
|
||||
}
|
||||
|
||||
const getRows = () => [...list.querySelectorAll("[data-sport-type-row]")];
|
||||
|
||||
const syncPreview = row => {
|
||||
const labelInput = row.querySelector('input[data-name-template$="[label]"]');
|
||||
const iconSelect = row.querySelector('select[data-name-template$="[icon]"]');
|
||||
@@ -781,9 +784,72 @@
|
||||
});
|
||||
};
|
||||
|
||||
addButton.addEventListener("click", () => {
|
||||
const syncPresets = () => {
|
||||
const selectedIds = new Set(
|
||||
getRows()
|
||||
.map(row => row.querySelector('input[data-name-template$="[id]"]'))
|
||||
.filter(Boolean)
|
||||
.map(input => String(input.value || "").trim())
|
||||
.filter(Boolean)
|
||||
);
|
||||
|
||||
presetButtons.forEach(button => {
|
||||
button.hidden = selectedIds.has(button.dataset.id || "");
|
||||
});
|
||||
};
|
||||
|
||||
const createRow = values => {
|
||||
list.append(template.content.cloneNode(true));
|
||||
const row = list.querySelector("[data-sport-type-row]:last-child");
|
||||
if (!row) {
|
||||
return;
|
||||
}
|
||||
|
||||
const idInput = row.querySelector('input[data-name-template$="[id]"]');
|
||||
const labelInput = row.querySelector('input[data-name-template$="[label]"]');
|
||||
const iconSelect = row.querySelector('select[data-name-template$="[icon]"]');
|
||||
const groupInput = row.querySelector('input[data-name-template$="[recovery_group]"]');
|
||||
const bonusInput = row.querySelector('input[data-name-template$="[bonus_points]"]');
|
||||
const consecutiveInput = row.querySelector('input[data-name-template$="[allow_consecutive]"]');
|
||||
|
||||
if (idInput) {
|
||||
idInput.value = values.id || "";
|
||||
}
|
||||
if (labelInput) {
|
||||
labelInput.value = values.label || "";
|
||||
}
|
||||
if (iconSelect) {
|
||||
iconSelect.value = values.icon || "run";
|
||||
}
|
||||
if (groupInput) {
|
||||
groupInput.value = values.recovery_group || "";
|
||||
}
|
||||
if (bonusInput) {
|
||||
bonusInput.value = values.bonus_points || "2";
|
||||
}
|
||||
if (consecutiveInput) {
|
||||
consecutiveInput.checked = Boolean(values.allow_consecutive);
|
||||
}
|
||||
|
||||
renumber();
|
||||
syncPresets();
|
||||
};
|
||||
|
||||
addButton.addEventListener("click", () => {
|
||||
createRow({});
|
||||
});
|
||||
|
||||
presetButtons.forEach(button => {
|
||||
button.addEventListener("click", () => {
|
||||
createRow({
|
||||
id: button.dataset.id || "",
|
||||
label: button.dataset.label || "",
|
||||
icon: button.dataset.icon || "run",
|
||||
recovery_group: button.dataset.recoveryGroup || "",
|
||||
bonus_points: button.dataset.bonusPoints || "2",
|
||||
allow_consecutive: button.dataset.allowConsecutive === "1",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
list.addEventListener("click", event => {
|
||||
@@ -797,32 +863,16 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const rows = list.querySelectorAll("[data-sport-type-row]");
|
||||
if (rows.length <= 1) {
|
||||
row.querySelectorAll("input[type='text'], input[type='hidden']").forEach(input => {
|
||||
input.value = "";
|
||||
});
|
||||
row.querySelectorAll("input[type='number']").forEach(input => {
|
||||
input.value = "2";
|
||||
});
|
||||
row.querySelectorAll("input[type='checkbox']").forEach(input => {
|
||||
input.checked = false;
|
||||
});
|
||||
row.querySelectorAll("select").forEach(select => {
|
||||
select.value = "run";
|
||||
});
|
||||
syncPreview(row);
|
||||
return;
|
||||
}
|
||||
|
||||
row.remove();
|
||||
renumber();
|
||||
syncPresets();
|
||||
});
|
||||
|
||||
list.addEventListener("input", event => {
|
||||
const row = event.target.closest("[data-sport-type-row]");
|
||||
if (row) {
|
||||
syncPreview(row);
|
||||
syncPresets();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -830,10 +880,12 @@
|
||||
const row = event.target.closest("[data-sport-type-row]");
|
||||
if (row) {
|
||||
syncPreview(row);
|
||||
syncPresets();
|
||||
}
|
||||
});
|
||||
|
||||
renumber();
|
||||
syncPresets();
|
||||
}
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
|
||||
Reference in New Issue
Block a user