Improve team page usability
parent
abc456b7d1
commit
9b2153266a
|
@ -52,6 +52,10 @@ button {
|
|||
transition-duration: 200ms;
|
||||
}
|
||||
|
||||
button.icon-end {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
button.icon {
|
||||
background-color: transparent;
|
||||
padding: 8px;
|
||||
|
@ -98,6 +102,10 @@ button.destructive {
|
|||
color: var(--base);
|
||||
}
|
||||
|
||||
button.destructive-on-hover:hover {
|
||||
background-color: var(--flamingo);
|
||||
color: var(--base);
|
||||
}
|
||||
|
||||
button.accent:hover {
|
||||
background-color: var(--text);
|
||||
|
|
|
@ -203,7 +203,7 @@ function getAvailabilityCell(day: number, hour: number) {
|
|||
const currentTimezone = computed(() =>
|
||||
Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||
|
||||
function getHour(offset, tz) {
|
||||
function getHour(offset, tz?) {
|
||||
let time = props.dateStart.clone()
|
||||
if (tz) {
|
||||
time = time.tz(tz);
|
||||
|
@ -226,9 +226,9 @@ function getHour(offset, tz) {
|
|||
</div>
|
||||
<div class="height-24px hour-marker-container">
|
||||
<span class="hour-marker">
|
||||
{{ getHour(hour + 1).format("HH:mm z") }}
|
||||
{{ getHour(lastHour + 1).format("HH:mm z") }}
|
||||
<span v-if="scheduleStore.team.tzTimezone != currentTimezone">
|
||||
/ {{ getHour(hour + 1, scheduleStore.team.tzTimezone).format("HH:mm z") }}
|
||||
/ {{ getHour(lastHour + 1, scheduleStore.team.tzTimezone).format("HH:mm z") }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@ function scheduleRoster() {
|
|||
<template>
|
||||
<div class="schedule-player-list">
|
||||
<h3>{{ scheduleStore.team?.teamName }}</h3>
|
||||
<div>
|
||||
<div class="list">
|
||||
<SchedulePlayerListItem
|
||||
v-for="record in scheduleStore.playerAvailability"
|
||||
:player="record"
|
||||
|
@ -75,4 +75,9 @@ h4, h4 > div {
|
|||
.player:hover {
|
||||
background-color: var(--mantle);
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -8,8 +8,8 @@ const scheduleStore = useScheduleStore();
|
|||
const hoveredIndex = computed(() => scheduleStore.hoveredIndex);
|
||||
|
||||
const availabilityAtHoveredIndex = computed(() => {
|
||||
if (hoveredIndex.value) {
|
||||
return props.player?.availability[hoveredIndex.value] ?? 0;
|
||||
if (hoveredIndex.value && props.player?.availability) {
|
||||
return props.player.availability[hoveredIndex.value] ?? 0;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
@ -19,12 +19,14 @@ const props = defineProps({
|
|||
});
|
||||
|
||||
function onMouseOver() {
|
||||
scheduleStore.overlay = props.player;
|
||||
if (props.player) {
|
||||
scheduleStore.hoveredMember = props.player;
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseLeave() {
|
||||
if (scheduleStore.overlay == props.player) {
|
||||
scheduleStore.overlay = undefined;
|
||||
if (scheduleStore.hoveredMember == props.player) {
|
||||
scheduleStore.hoveredMember = undefined;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -32,10 +34,21 @@ function onMouseLeave() {
|
|||
<template>
|
||||
<div
|
||||
class="player"
|
||||
@mouseover="onMouseOver(player)"
|
||||
v-if="player"
|
||||
@mouseover="onMouseOver"
|
||||
@mouseleave="onMouseLeave"
|
||||
>
|
||||
<span v-if="availabilityAtHoveredIndex > 0">
|
||||
<input
|
||||
class="player-checkbox"
|
||||
type="checkbox"
|
||||
v-model="scheduleStore.selectedMembers[player.steamId]"
|
||||
:value="player"
|
||||
:id="player.steamId"
|
||||
/>
|
||||
<label
|
||||
:for="player.steamId"
|
||||
>
|
||||
<span v-if="availabilityAtHoveredIndex ?? 0 > 0">
|
||||
<span v-if="availabilityAtHoveredIndex == 1" class="can-be-available">
|
||||
{{ player.username }}
|
||||
</span>
|
||||
|
@ -49,11 +62,28 @@ function onMouseLeave() {
|
|||
<span v-else>
|
||||
{{ player.username }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.player:hover {
|
||||
input {
|
||||
display: inline-block;
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.player {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
padding: 6px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.player label {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.player label:hover {
|
||||
background-color: var(--mantle);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,9 @@ export const useAuthStore = defineStore("auth", () => {
|
|||
getUser.name,
|
||||
() => client.default.getUser(),
|
||||
(response) => {
|
||||
isLoggedIn.value = true;
|
||||
steamId.value = response.steamId;
|
||||
username.value = username.value;
|
||||
username.value = response.username;
|
||||
return response;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -29,9 +29,36 @@ export const useScheduleStore = defineStore("schedule", () => {
|
|||
|
||||
const playerAvailability: Ref<AvailabilitySchema[]> = ref([ ]);
|
||||
|
||||
const overlay: Ref<AvailabilitySchema[] | undefined> = ref();
|
||||
const overlay = computed<number[] | undefined>(() => {
|
||||
let members = Object.keys(selectedMembers)
|
||||
.filter((x) => selectedMembers[x]);
|
||||
if (members.length > 0) {
|
||||
const min = Array(168).fill(0);
|
||||
|
||||
const selectedMembers = ref<AvailabilitySchema[]>();
|
||||
const candidates = playerAvailability.value
|
||||
.filter((x) => members.includes(x.steamId));
|
||||
for (let i = 0; i < 168; i++) {
|
||||
min[i] = Math.min(
|
||||
...candidates.map((c) => c.availability ? c.availability[i] : 0));
|
||||
}
|
||||
//for (const availability of candidates) {
|
||||
//}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
if (hoveredMember.value) {
|
||||
return playerAvailability.value
|
||||
.find((x) => x.steamId == hoveredMember.value?.steamId)
|
||||
?.availability;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const hoveredMember = ref<AvailabilitySchema>();
|
||||
|
||||
const selectedMembers = reactive<{ [id: string]: boolean }>({ });
|
||||
|
||||
const hoveredIndex: Ref<number | undefined> = ref();
|
||||
|
||||
|
@ -115,6 +142,7 @@ export const useScheduleStore = defineStore("schedule", () => {
|
|||
availability,
|
||||
playerAvailability,
|
||||
overlay,
|
||||
hoveredMember,
|
||||
selectedMembers,
|
||||
hoveredIndex,
|
||||
fetchSchedule,
|
||||
|
|
|
@ -28,7 +28,7 @@ const selectionMode = ref(1);
|
|||
|
||||
const selectedTime = ref(undefined);
|
||||
|
||||
const availabilityOverlay = computed(() => schedule.overlay?.availability);
|
||||
const availabilityOverlay = computed(() => schedule.overlay);
|
||||
|
||||
const isEditing = ref(false);
|
||||
|
||||
|
@ -132,7 +132,8 @@ onMounted(() => {
|
|||
Copy previous week
|
||||
</button>
|
||||
<button class="accent" @click="isEditing = true">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
<i class="bi bi-pencil-fill margin"></i>
|
||||
Edit
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,10 @@ const {
|
|||
timezone,
|
||||
minuteOffset,
|
||||
} = useTeamSettings();
|
||||
|
||||
function updateTeamSettings() {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -2,15 +2,21 @@
|
|||
import { useTeamsStore } from "@/stores/teams";
|
||||
import { useTeamDetails } from "@/composables/team-details";
|
||||
import { onMounted } from "vue";
|
||||
import { RouterLink, RouterView } from "vue-router";
|
||||
import { RouterLink, RouterView, useRouter } from "vue-router";
|
||||
|
||||
const teamsStore = useTeamsStore();
|
||||
const router = useRouter();
|
||||
|
||||
const {
|
||||
team,
|
||||
teamId,
|
||||
} = useTeamDetails();
|
||||
|
||||
function leaveTeam() {
|
||||
teamsStore.leaveTeam(teamId.value)
|
||||
.then(() => router.push("/"));
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
teamsStore.fetchTeam(teamId.value);
|
||||
});
|
||||
|
@ -37,6 +43,10 @@ onMounted(() => {
|
|||
Invites
|
||||
</RouterLink>
|
||||
<hr>
|
||||
<button class="destructive-on-hover icon-end" @click="leaveTeam">
|
||||
Leave team
|
||||
<i class="bi bi-box-arrow-left" />
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="view">
|
||||
|
@ -96,4 +106,17 @@ nav.sidebar a.tab.router-link-exact-active {
|
|||
background-color: var(--crust);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
nav.sidebar button {
|
||||
font-size: 11pt;
|
||||
font-weight: 500;
|
||||
padding: 6px 10px;
|
||||
background-color: transparent;
|
||||
color: var(--overlay-0);
|
||||
}
|
||||
|
||||
nav.sidebar button:hover {
|
||||
background-color: var(--crust);
|
||||
color: var(--text);
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue