mirror of
https://github.com/Pandipipas/scoreko-dev.git
synced 2026-06-06 03:32:06 +00:00
Agregar overrides de team/country y guardado desde ScoreboardPanel
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watchEffect } from 'vue';
|
||||
import { computed, ref, watch, watchEffect, type Ref } from 'vue';
|
||||
import type { Schemas } from '../../../types';
|
||||
import { countryOptions, getCountryLabel } from '../../../shared/countries';
|
||||
import { usePlayersStore } from '../stores/players';
|
||||
import { useScoreboardStore } from '../stores/scoreboard';
|
||||
|
||||
@@ -14,6 +15,11 @@ const rightInput = ref('');
|
||||
const leftFocused = ref(false);
|
||||
const rightFocused = ref(false);
|
||||
|
||||
const leftCountryInput = ref('');
|
||||
const rightCountryInput = ref('');
|
||||
const leftCountryOptions = ref(countryOptions);
|
||||
const rightCountryOptions = ref(countryOptions);
|
||||
|
||||
const normalizeName = (value: string) => value.trim().toLowerCase();
|
||||
|
||||
const filterOptions = (
|
||||
@@ -27,6 +33,30 @@ const filterOptions = (
|
||||
return options.filter((option) => option.label.toLowerCase().includes(lowerNeedle));
|
||||
};
|
||||
|
||||
const filterCountries = (
|
||||
value: string,
|
||||
update: (callback: () => void) => void,
|
||||
target: Ref<{ value: string; label: string }[]>,
|
||||
) => {
|
||||
update(() => {
|
||||
const needle = value.toLowerCase().trim();
|
||||
if (!needle) {
|
||||
target.value = countryOptions;
|
||||
return;
|
||||
}
|
||||
target.value = countryOptions.filter((country) => country.label.toLowerCase().includes(needle));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const onLeftCountryFilter = (value: string, update: (callback: () => void) => void) => {
|
||||
filterCountries(value, update, leftCountryOptions);
|
||||
};
|
||||
|
||||
const onRightCountryFilter = (value: string, update: (callback: () => void) => void) => {
|
||||
filterCountries(value, update, rightCountryOptions);
|
||||
};
|
||||
|
||||
const playerOptions = computed(() => {
|
||||
const base = [{ label: '(Sin asignar)', value: '' }];
|
||||
const entries = Object.entries(playersStore.players) as [string, Schemas.Players[string]][];
|
||||
@@ -37,6 +67,9 @@ const playerOptions = computed(() => {
|
||||
return base.concat(options);
|
||||
});
|
||||
|
||||
const leftSelectedPlayer = computed(() => playersStore.players[scoreboardStore.scoreboard.leftPlayerId]);
|
||||
const rightSelectedPlayer = computed(() => playersStore.players[scoreboardStore.scoreboard.rightPlayerId]);
|
||||
|
||||
const getPlayerLabel = (playerId: string) => {
|
||||
const match = playerOptions.value.find((option) => option.value === playerId);
|
||||
return match ? match.label : '';
|
||||
@@ -63,6 +96,42 @@ const rightCanSave = computed(
|
||||
&& !playerExistsByGamertag(scoreboardStore.scoreboard.rightNameOverride),
|
||||
);
|
||||
|
||||
const leftPendingGamertag = computed(() => {
|
||||
const override = scoreboardStore.scoreboard.leftNameOverride.trim();
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
return leftSelectedPlayer.value?.gamertag ?? '';
|
||||
});
|
||||
|
||||
const rightPendingGamertag = computed(() => {
|
||||
const override = scoreboardStore.scoreboard.rightNameOverride.trim();
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
return rightSelectedPlayer.value?.gamertag ?? '';
|
||||
});
|
||||
|
||||
const leftHasSelectedPlayerChanges = computed(() => {
|
||||
const player = leftSelectedPlayer.value;
|
||||
if (!player) {
|
||||
return false;
|
||||
}
|
||||
return player.gamertag !== leftPendingGamertag.value
|
||||
|| player.team !== scoreboardStore.scoreboard.leftTeamOverride
|
||||
|| player.country !== scoreboardStore.scoreboard.leftCountryOverride;
|
||||
});
|
||||
|
||||
const rightHasSelectedPlayerChanges = computed(() => {
|
||||
const player = rightSelectedPlayer.value;
|
||||
if (!player) {
|
||||
return false;
|
||||
}
|
||||
return player.gamertag !== rightPendingGamertag.value
|
||||
|| player.team !== scoreboardStore.scoreboard.rightTeamOverride
|
||||
|| player.country !== scoreboardStore.scoreboard.rightCountryOverride;
|
||||
});
|
||||
|
||||
const leftPlayerOptions = computed(() => filterOptions(playerOptions.value, leftFilter.value));
|
||||
const rightPlayerOptions = computed(() => filterOptions(playerOptions.value, rightFilter.value));
|
||||
|
||||
@@ -104,16 +173,32 @@ const onRightBlur = () => {
|
||||
rightInput.value = rightDisplayName.value;
|
||||
};
|
||||
|
||||
const applyLeftPlayerData = (playerId: string) => {
|
||||
const player = playersStore.players[playerId];
|
||||
scoreboardStore.scoreboard.leftTeamOverride = player?.team ?? '';
|
||||
scoreboardStore.scoreboard.leftCountryOverride = player?.country ?? '';
|
||||
leftCountryInput.value = getCountryLabel(scoreboardStore.scoreboard.leftCountryOverride);
|
||||
};
|
||||
|
||||
const applyRightPlayerData = (playerId: string) => {
|
||||
const player = playersStore.players[playerId];
|
||||
scoreboardStore.scoreboard.rightTeamOverride = player?.team ?? '';
|
||||
scoreboardStore.scoreboard.rightCountryOverride = player?.country ?? '';
|
||||
rightCountryInput.value = getCountryLabel(scoreboardStore.scoreboard.rightCountryOverride);
|
||||
};
|
||||
|
||||
const onLeftSelect = () => {
|
||||
scoreboardStore.scoreboard.leftNameOverride = '';
|
||||
leftFilter.value = '';
|
||||
leftInput.value = getPlayerLabel(scoreboardStore.scoreboard.leftPlayerId);
|
||||
applyLeftPlayerData(scoreboardStore.scoreboard.leftPlayerId);
|
||||
};
|
||||
|
||||
const onRightSelect = () => {
|
||||
scoreboardStore.scoreboard.rightNameOverride = '';
|
||||
rightFilter.value = '';
|
||||
rightInput.value = getPlayerLabel(scoreboardStore.scoreboard.rightPlayerId);
|
||||
applyRightPlayerData(scoreboardStore.scoreboard.rightPlayerId);
|
||||
};
|
||||
|
||||
const createPlayerId = (name: string) => {
|
||||
@@ -144,8 +229,8 @@ const saveLeftPlayer = () => {
|
||||
playersStore.upsertPlayer(id, {
|
||||
gamertag,
|
||||
name: '',
|
||||
team: '',
|
||||
country: '',
|
||||
team: scoreboardStore.scoreboard.leftTeamOverride,
|
||||
country: scoreboardStore.scoreboard.leftCountryOverride,
|
||||
twitter: '',
|
||||
});
|
||||
scoreboardStore.scoreboard.leftPlayerId = id;
|
||||
@@ -162,8 +247,8 @@ const saveRightPlayer = () => {
|
||||
playersStore.upsertPlayer(id, {
|
||||
gamertag,
|
||||
name: '',
|
||||
team: '',
|
||||
country: '',
|
||||
team: scoreboardStore.scoreboard.rightTeamOverride,
|
||||
country: scoreboardStore.scoreboard.rightCountryOverride,
|
||||
twitter: '',
|
||||
});
|
||||
scoreboardStore.scoreboard.rightPlayerId = id;
|
||||
@@ -171,6 +256,68 @@ const saveRightPlayer = () => {
|
||||
rightInput.value = gamertag;
|
||||
};
|
||||
|
||||
const saveLeftSelectedPlayerChanges = () => {
|
||||
const playerId = scoreboardStore.scoreboard.leftPlayerId;
|
||||
const player = playersStore.players[playerId];
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
playersStore.upsertPlayer(playerId, {
|
||||
...player,
|
||||
gamertag: leftPendingGamertag.value,
|
||||
team: scoreboardStore.scoreboard.leftTeamOverride,
|
||||
country: scoreboardStore.scoreboard.leftCountryOverride,
|
||||
});
|
||||
scoreboardStore.scoreboard.leftNameOverride = '';
|
||||
};
|
||||
|
||||
const saveRightSelectedPlayerChanges = () => {
|
||||
const playerId = scoreboardStore.scoreboard.rightPlayerId;
|
||||
const player = playersStore.players[playerId];
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
playersStore.upsertPlayer(playerId, {
|
||||
...player,
|
||||
gamertag: rightPendingGamertag.value,
|
||||
team: scoreboardStore.scoreboard.rightTeamOverride,
|
||||
country: scoreboardStore.scoreboard.rightCountryOverride,
|
||||
});
|
||||
scoreboardStore.scoreboard.rightNameOverride = '';
|
||||
};
|
||||
|
||||
watch(
|
||||
() => scoreboardStore.scoreboard.leftPlayerId,
|
||||
(playerId) => {
|
||||
applyLeftPlayerData(playerId);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => scoreboardStore.scoreboard.rightPlayerId,
|
||||
(playerId) => {
|
||||
applyRightPlayerData(playerId);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => scoreboardStore.scoreboard.leftCountryOverride,
|
||||
(value) => {
|
||||
leftCountryInput.value = getCountryLabel(value);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => scoreboardStore.scoreboard.rightCountryOverride,
|
||||
(value) => {
|
||||
rightCountryInput.value = getCountryLabel(value);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
if (!leftFocused.value) {
|
||||
leftInput.value = leftDisplayName.value;
|
||||
@@ -240,6 +387,32 @@ watchEffect(() => {
|
||||
@blur="onLeftBlur"
|
||||
@update:model-value="onLeftSelect"
|
||||
/>
|
||||
<QInput
|
||||
v-model="scoreboardStore.scoreboard.leftTeamOverride"
|
||||
label="Team"
|
||||
dense
|
||||
outlined
|
||||
class="q-mt-sm"
|
||||
/>
|
||||
<QSelect
|
||||
v-model="scoreboardStore.scoreboard.leftCountryOverride"
|
||||
v-model:input-value="leftCountryInput"
|
||||
:options="leftCountryOptions"
|
||||
option-value="value"
|
||||
option-label="label"
|
||||
emit-value
|
||||
map-options
|
||||
use-input
|
||||
input-debounce="0"
|
||||
hide-selected
|
||||
fill-input
|
||||
clearable
|
||||
label="Country"
|
||||
dense
|
||||
outlined
|
||||
class="q-mt-sm"
|
||||
@filter="onLeftCountryFilter"
|
||||
/>
|
||||
<QBtn
|
||||
v-if="leftCanSave"
|
||||
color="primary"
|
||||
@@ -248,6 +421,14 @@ watchEffect(() => {
|
||||
class="q-mt-sm"
|
||||
@click="saveLeftPlayer"
|
||||
/>
|
||||
<QBtn
|
||||
v-if="leftHasSelectedPlayerChanges"
|
||||
color="primary"
|
||||
icon="save"
|
||||
label="Guardar cambios del jugador"
|
||||
class="q-mt-sm q-ml-sm"
|
||||
@click="saveLeftSelectedPlayerChanges"
|
||||
/>
|
||||
<QInput
|
||||
v-model.number="scoreboardStore.leftScore"
|
||||
type="number"
|
||||
@@ -291,6 +472,32 @@ watchEffect(() => {
|
||||
@blur="onRightBlur"
|
||||
@update:model-value="onRightSelect"
|
||||
/>
|
||||
<QInput
|
||||
v-model="scoreboardStore.scoreboard.rightTeamOverride"
|
||||
label="Team"
|
||||
dense
|
||||
outlined
|
||||
class="q-mt-sm"
|
||||
/>
|
||||
<QSelect
|
||||
v-model="scoreboardStore.scoreboard.rightCountryOverride"
|
||||
v-model:input-value="rightCountryInput"
|
||||
:options="rightCountryOptions"
|
||||
option-value="value"
|
||||
option-label="label"
|
||||
emit-value
|
||||
map-options
|
||||
use-input
|
||||
input-debounce="0"
|
||||
hide-selected
|
||||
fill-input
|
||||
clearable
|
||||
label="Country"
|
||||
dense
|
||||
outlined
|
||||
class="q-mt-sm"
|
||||
@filter="onRightCountryFilter"
|
||||
/>
|
||||
<QBtn
|
||||
v-if="rightCanSave"
|
||||
color="primary"
|
||||
@@ -299,6 +506,14 @@ watchEffect(() => {
|
||||
class="q-mt-sm"
|
||||
@click="saveRightPlayer"
|
||||
/>
|
||||
<QBtn
|
||||
v-if="rightHasSelectedPlayerChanges"
|
||||
color="primary"
|
||||
icon="save"
|
||||
label="Guardar cambios del jugador"
|
||||
class="q-mt-sm q-ml-sm"
|
||||
@click="saveRightSelectedPlayerChanges"
|
||||
/>
|
||||
<QInput
|
||||
v-model.number="scoreboardStore.rightScore"
|
||||
type="number"
|
||||
|
||||
Reference in New Issue
Block a user