mirror of
https://github.com/Pandipipas/scoreko-dev.git
synced 2026-06-06 03:32:06 +00:00
Mejorar override de jugadores y guardado rápido (#37)
This commit is contained in:
@@ -14,6 +14,8 @@ const rightInput = ref('');
|
|||||||
const leftFocused = ref(false);
|
const leftFocused = ref(false);
|
||||||
const rightFocused = ref(false);
|
const rightFocused = ref(false);
|
||||||
|
|
||||||
|
const normalizeName = (value: string) => value.trim().toLowerCase();
|
||||||
|
|
||||||
const filterOptions = (
|
const filterOptions = (
|
||||||
options: { label: string; value: string }[],
|
options: { label: string; value: string }[],
|
||||||
needle: string,
|
needle: string,
|
||||||
@@ -40,6 +42,27 @@ const getPlayerLabel = (playerId: string) => {
|
|||||||
return match ? match.label : '';
|
return match ? match.label : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const playerExistsByGamertag = (name: string) => {
|
||||||
|
const normalized = normalizeName(name);
|
||||||
|
if (!normalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Object.values(playersStore.players).some((player) => normalizeName(player.gamertag || '') === normalized);
|
||||||
|
};
|
||||||
|
|
||||||
|
const leftDisplayName = computed(() => scoreboardStore.scoreboard.leftNameOverride || getPlayerLabel(scoreboardStore.scoreboard.leftPlayerId));
|
||||||
|
const rightDisplayName = computed(() => scoreboardStore.scoreboard.rightNameOverride || getPlayerLabel(scoreboardStore.scoreboard.rightPlayerId));
|
||||||
|
|
||||||
|
const leftCanSave = computed(
|
||||||
|
() => Boolean(scoreboardStore.scoreboard.leftNameOverride.trim())
|
||||||
|
&& !playerExistsByGamertag(scoreboardStore.scoreboard.leftNameOverride),
|
||||||
|
);
|
||||||
|
|
||||||
|
const rightCanSave = computed(
|
||||||
|
() => Boolean(scoreboardStore.scoreboard.rightNameOverride.trim())
|
||||||
|
&& !playerExistsByGamertag(scoreboardStore.scoreboard.rightNameOverride),
|
||||||
|
);
|
||||||
|
|
||||||
const leftPlayerOptions = computed(() => filterOptions(playerOptions.value, leftFilter.value));
|
const leftPlayerOptions = computed(() => filterOptions(playerOptions.value, leftFilter.value));
|
||||||
const rightPlayerOptions = computed(() => filterOptions(playerOptions.value, rightFilter.value));
|
const rightPlayerOptions = computed(() => filterOptions(playerOptions.value, rightFilter.value));
|
||||||
|
|
||||||
@@ -47,6 +70,7 @@ const onLeftFilter = (val: string, update: (fn: () => void) => void) => {
|
|||||||
update(() => {
|
update(() => {
|
||||||
leftFilter.value = val;
|
leftFilter.value = val;
|
||||||
leftInput.value = val;
|
leftInput.value = val;
|
||||||
|
scoreboardStore.scoreboard.leftNameOverride = val;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,6 +78,7 @@ const onRightFilter = (val: string, update: (fn: () => void) => void) => {
|
|||||||
update(() => {
|
update(() => {
|
||||||
rightFilter.value = val;
|
rightFilter.value = val;
|
||||||
rightInput.value = val;
|
rightInput.value = val;
|
||||||
|
scoreboardStore.scoreboard.rightNameOverride = val;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,7 +90,7 @@ const onLeftFocus = () => {
|
|||||||
const onLeftBlur = () => {
|
const onLeftBlur = () => {
|
||||||
leftFocused.value = false;
|
leftFocused.value = false;
|
||||||
leftFilter.value = '';
|
leftFilter.value = '';
|
||||||
leftInput.value = getPlayerLabel(scoreboardStore.scoreboard.leftPlayerId);
|
leftInput.value = leftDisplayName.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRightFocus = () => {
|
const onRightFocus = () => {
|
||||||
@@ -76,28 +101,85 @@ const onRightFocus = () => {
|
|||||||
const onRightBlur = () => {
|
const onRightBlur = () => {
|
||||||
rightFocused.value = false;
|
rightFocused.value = false;
|
||||||
rightFilter.value = '';
|
rightFilter.value = '';
|
||||||
rightInput.value = getPlayerLabel(scoreboardStore.scoreboard.rightPlayerId);
|
rightInput.value = rightDisplayName.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLeftSelect = () => {
|
const onLeftSelect = () => {
|
||||||
|
scoreboardStore.scoreboard.leftNameOverride = '';
|
||||||
leftFilter.value = '';
|
leftFilter.value = '';
|
||||||
leftInput.value = getPlayerLabel(scoreboardStore.scoreboard.leftPlayerId);
|
leftInput.value = getPlayerLabel(scoreboardStore.scoreboard.leftPlayerId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRightSelect = () => {
|
const onRightSelect = () => {
|
||||||
|
scoreboardStore.scoreboard.rightNameOverride = '';
|
||||||
rightFilter.value = '';
|
rightFilter.value = '';
|
||||||
rightInput.value = getPlayerLabel(scoreboardStore.scoreboard.rightPlayerId);
|
rightInput.value = getPlayerLabel(scoreboardStore.scoreboard.rightPlayerId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createPlayerId = (name: string) => {
|
||||||
|
const base = name
|
||||||
|
.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
.normalize('NFD')
|
||||||
|
.replace(/[^\w\s-]/g, '')
|
||||||
|
.replace(/[\u0300-\u036f]/g, '')
|
||||||
|
.replace(/\s+/g, '-');
|
||||||
|
|
||||||
|
const seed = base || 'player';
|
||||||
|
let index = 1;
|
||||||
|
let candidate = seed;
|
||||||
|
while (playersStore.players[candidate]) {
|
||||||
|
index += 1;
|
||||||
|
candidate = `${seed}-${index}`;
|
||||||
|
}
|
||||||
|
return candidate;
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveLeftPlayer = () => {
|
||||||
|
const gamertag = scoreboardStore.scoreboard.leftNameOverride.trim();
|
||||||
|
if (!gamertag || playerExistsByGamertag(gamertag)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const id = createPlayerId(gamertag);
|
||||||
|
playersStore.upsertPlayer(id, {
|
||||||
|
gamertag,
|
||||||
|
name: '',
|
||||||
|
team: '',
|
||||||
|
country: '',
|
||||||
|
twitter: '',
|
||||||
|
});
|
||||||
|
scoreboardStore.scoreboard.leftPlayerId = id;
|
||||||
|
scoreboardStore.scoreboard.leftNameOverride = '';
|
||||||
|
leftInput.value = gamertag;
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveRightPlayer = () => {
|
||||||
|
const gamertag = scoreboardStore.scoreboard.rightNameOverride.trim();
|
||||||
|
if (!gamertag || playerExistsByGamertag(gamertag)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const id = createPlayerId(gamertag);
|
||||||
|
playersStore.upsertPlayer(id, {
|
||||||
|
gamertag,
|
||||||
|
name: '',
|
||||||
|
team: '',
|
||||||
|
country: '',
|
||||||
|
twitter: '',
|
||||||
|
});
|
||||||
|
scoreboardStore.scoreboard.rightPlayerId = id;
|
||||||
|
scoreboardStore.scoreboard.rightNameOverride = '';
|
||||||
|
rightInput.value = gamertag;
|
||||||
|
};
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (!leftFocused.value) {
|
if (!leftFocused.value) {
|
||||||
leftInput.value = getPlayerLabel(scoreboardStore.scoreboard.leftPlayerId);
|
leftInput.value = leftDisplayName.value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (!rightFocused.value) {
|
if (!rightFocused.value) {
|
||||||
rightInput.value = getPlayerLabel(scoreboardStore.scoreboard.rightPlayerId);
|
rightInput.value = rightDisplayName.value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -158,12 +240,13 @@ watchEffect(() => {
|
|||||||
@blur="onLeftBlur"
|
@blur="onLeftBlur"
|
||||||
@update:model-value="onLeftSelect"
|
@update:model-value="onLeftSelect"
|
||||||
/>
|
/>
|
||||||
<QInput
|
<QBtn
|
||||||
v-model="scoreboardStore.scoreboard.leftNameOverride"
|
v-if="leftCanSave"
|
||||||
label="Nombre override"
|
color="primary"
|
||||||
dense
|
icon="save"
|
||||||
outlined
|
label="Guardar jugador"
|
||||||
class="q-mt-md"
|
class="q-mt-sm"
|
||||||
|
@click="saveLeftPlayer"
|
||||||
/>
|
/>
|
||||||
<QInput
|
<QInput
|
||||||
v-model.number="scoreboardStore.leftScore"
|
v-model.number="scoreboardStore.leftScore"
|
||||||
@@ -208,12 +291,13 @@ watchEffect(() => {
|
|||||||
@blur="onRightBlur"
|
@blur="onRightBlur"
|
||||||
@update:model-value="onRightSelect"
|
@update:model-value="onRightSelect"
|
||||||
/>
|
/>
|
||||||
<QInput
|
<QBtn
|
||||||
v-model="scoreboardStore.scoreboard.rightNameOverride"
|
v-if="rightCanSave"
|
||||||
label="Nombre override"
|
color="primary"
|
||||||
dense
|
icon="save"
|
||||||
outlined
|
label="Guardar jugador"
|
||||||
class="q-mt-md"
|
class="q-mt-sm"
|
||||||
|
@click="saveRightPlayer"
|
||||||
/>
|
/>
|
||||||
<QInput
|
<QInput
|
||||||
v-model.number="scoreboardStore.rightScore"
|
v-model.number="scoreboardStore.rightScore"
|
||||||
|
|||||||
Reference in New Issue
Block a user