Improve readability
parent
a509c797ff
commit
45ac071a7f
|
@ -76,6 +76,17 @@ i.bi.margin {
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.checkbox, button.checkbox.icon {
|
||||||
|
outline: 1px solid var(--overlay-0);
|
||||||
|
font-size: 1rem;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
background-color: var(--surface-0);
|
background-color: var(--surface-0);
|
||||||
}
|
}
|
||||||
|
@ -206,7 +217,7 @@ main {
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input, textarea {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
|
@ -233,6 +244,10 @@ input {
|
||||||
sans-serif;
|
sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -312,6 +327,7 @@ hr {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
animation: smooth-appear 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
[role="dialog"] {
|
[role="dialog"] {
|
||||||
|
@ -321,6 +337,16 @@ hr {
|
||||||
transform: translateX(-50%) translateY(-50%);
|
transform: translateX(-50%) translateY(-50%);
|
||||||
background-color: var(--base);
|
background-color: var(--base);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
animation: smooth-appear 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes smooth-appear {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.banner {
|
div.banner {
|
||||||
|
|
|
@ -1,16 +1,40 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useEventForm } from "@/composables/event-form";
|
import { useEventForm } from "@/composables/event-form";
|
||||||
|
import { useTeamDetails } from "@/composables/team-details";
|
||||||
import { useRosterStore } from "@/stores/roster";
|
import { useRosterStore } from "@/stores/roster";
|
||||||
|
import { useTeamsStore } from "@/stores/teams";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import { computed, onMounted } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const rosterStore = useRosterStore();
|
const rosterStore = useRosterStore();
|
||||||
|
const teamsStore = useTeamsStore();
|
||||||
|
|
||||||
const { eventId } = useEventForm();
|
const { eventId } = useEventForm();
|
||||||
|
|
||||||
|
const { team, teamId } = useTeamDetails();
|
||||||
|
|
||||||
|
const startTime = computed(() => {
|
||||||
|
if (rosterStore.startTime) {
|
||||||
|
return moment.unix(rosterStore.startTime).format("LL LT z");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const startTimeTeamTz = computed(() => {
|
||||||
|
if (rosterStore.startTime) {
|
||||||
|
// if team timezone is the same as ours, then do nothing
|
||||||
|
if (team.value?.tzTimezone === moment.tz.guess()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return moment.unix(rosterStore.startTime)
|
||||||
|
.tz(team.value?.tzTimezone)
|
||||||
|
.format("LL LT z");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function saveRoster() {
|
function saveRoster() {
|
||||||
if (eventId.value) {
|
if (eventId.value) {
|
||||||
rosterStore.updateRoster(eventId.value);
|
rosterStore.updateRoster(eventId.value);
|
||||||
|
@ -26,16 +50,26 @@ function saveRoster() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!team.value) {
|
||||||
|
teamsStore.fetchTeam(teamId.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="event-scheduler-container">
|
<div class="event-scheduler-container">
|
||||||
<h1 class="roster-title">
|
<h1 class="roster-title">
|
||||||
Roster for Snus Brotherhood
|
Roster for {{ team?.teamName }}
|
||||||
</h1>
|
</h1>
|
||||||
<div v-if="rosterStore.startTime">
|
<div v-if="rosterStore.startTime">
|
||||||
<span class="aside date">
|
<span class="aside date">
|
||||||
{{ moment.unix(rosterStore.startTime).format("LL LT") }}
|
{{ startTime }}
|
||||||
|
</span>
|
||||||
|
<br v-if="startTimeTeamTz">
|
||||||
|
<span class="aside date">
|
||||||
|
{{ startTimeTeamTz }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group margin">
|
<div class="form-group margin">
|
||||||
|
|
|
@ -13,7 +13,7 @@ onMounted(() => {
|
||||||
<template>
|
<template>
|
||||||
<div class="commit-history">
|
<div class="commit-history">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h2>Commit History</h2>
|
<h2>Changelog/Commit History</h2>
|
||||||
<a
|
<a
|
||||||
class="icon"
|
class="icon"
|
||||||
href="https://github.com/HumanoidSandvichDispenser/availabili.tf/commits"
|
href="https://github.com/HumanoidSandvichDispenser/availabili.tf/commits"
|
||||||
|
|
|
@ -76,13 +76,15 @@ const isUnavailable = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const nextHour = computed(() => {
|
const nextHour = computed(() => {
|
||||||
const now = moment().utc();
|
const now = moment();
|
||||||
const time = now.clone().tz(props.team.tzTimezone);
|
const time = now.clone().tz(props.team.tzTimezone);
|
||||||
|
|
||||||
if (time.minute() >= props.team.minuteOffset) {
|
let minute = time.minute();
|
||||||
|
let minuteOffset = props.team.minuteOffset;
|
||||||
|
if (minute >= minuteOffset) {
|
||||||
time.add(1, "hour");
|
time.add(1, "hour");
|
||||||
time.minute(props.team.minuteOffset);
|
|
||||||
}
|
}
|
||||||
|
time.minute(minuteOffset);
|
||||||
|
|
||||||
const diff = time.utc().diff(now, "minutes", false);
|
const diff = time.utc().diff(now, "minutes", false);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { useScheduleStore } from "../stores/schedule";
|
import { useScheduleStore } from "../stores/schedule";
|
||||||
import { computed, type PropType } from "vue";
|
import { computed, type PropType } from "vue";
|
||||||
import { type AvailabilitySchema } from "@/client";
|
import { type AvailabilitySchema } from "@/client";
|
||||||
|
import { CheckboxIndicator, CheckboxRoot } from "radix-vue";
|
||||||
|
|
||||||
const scheduleStore = useScheduleStore();
|
const scheduleStore = useScheduleStore();
|
||||||
|
|
||||||
|
@ -21,10 +22,21 @@ const availabilityAtHoveredIndex = computed(() => {
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
const props = defineProps({
|
const selectedMember = computed({
|
||||||
player: Object as PropType<AvailabilitySchema>,
|
get: () => scheduleStore.selectedMembers[props.player.steamId] ?? false,
|
||||||
|
set: (value: boolean) => {
|
||||||
|
console.log("set", value);
|
||||||
|
scheduleStore.selectedMembers[props.player.steamId] = value;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
player: AvailabilitySchema;
|
||||||
|
}>();
|
||||||
|
//const props = defineProps({
|
||||||
|
// player: Object as PropType<AvailabilitySchema>,
|
||||||
|
//});
|
||||||
|
|
||||||
function onMouseOver() {
|
function onMouseOver() {
|
||||||
if (props.player) {
|
if (props.player) {
|
||||||
scheduleStore.hoveredMember = props.player;
|
scheduleStore.hoveredMember = props.player;
|
||||||
|
@ -45,16 +57,25 @@ function onMouseLeave() {
|
||||||
@mouseover="onMouseOver"
|
@mouseover="onMouseOver"
|
||||||
@mouseleave="onMouseLeave"
|
@mouseleave="onMouseLeave"
|
||||||
>
|
>
|
||||||
<input
|
<!--input
|
||||||
class="player-checkbox"
|
class="player-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="scheduleStore.selectedMembers[player.steamId]"
|
v-model="scheduleStore.selectedMembers[player.steamId]"
|
||||||
:value="player"
|
:value="player"
|
||||||
:id="player.steamId"
|
:id="player.steamId"
|
||||||
/>
|
/-->
|
||||||
<label
|
<label
|
||||||
:for="player.steamId"
|
:for="player.steamId"
|
||||||
>
|
>
|
||||||
|
<!-- checkbox for pinning players -->
|
||||||
|
<CheckboxRoot
|
||||||
|
v-model:checked="selectedMember"
|
||||||
|
class="checkbox icon"
|
||||||
|
>
|
||||||
|
<CheckboxIndicator>
|
||||||
|
<i class="bi bi-pin-fill"></i>
|
||||||
|
</CheckboxIndicator>
|
||||||
|
</CheckboxRoot>
|
||||||
<span v-if="availabilityAtHoveredIndex ?? 0 > 0">
|
<span v-if="availabilityAtHoveredIndex ?? 0 > 0">
|
||||||
<span v-if="availabilityAtHoveredIndex == 1" class="can-be-available">
|
<span v-if="availabilityAtHoveredIndex == 1" class="can-be-available">
|
||||||
{{ player.username }}
|
{{ player.username }}
|
||||||
|
@ -105,4 +126,15 @@ input {
|
||||||
.player s {
|
.player s {
|
||||||
color: var(--overlay-0);
|
color: var(--overlay-0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.player-checkbox.icon i.bi {
|
||||||
|
/* dont take up space */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,7 +8,7 @@ export function useTeamDetails() {
|
||||||
const teamsStore = useTeamsStore();
|
const teamsStore = useTeamsStore();
|
||||||
const invitesStore = useInvitesStore();
|
const invitesStore = useInvitesStore();
|
||||||
|
|
||||||
const teamId = computed(() => Number(route.params.id));
|
const teamId = computed(() => Number(route.params.id ?? route.params.teamId));
|
||||||
|
|
||||||
const team = computed(() => {
|
const team = computed(() => {
|
||||||
return teamsStore.teams[teamId.value];
|
return teamsStore.teams[teamId.value];
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import PlayerCard from "../components/PlayerCard.vue";
|
import PlayerCard from "../components/PlayerCard.vue";
|
||||||
import { computed, reactive, onMounted, ref } from "vue";
|
import { computed, reactive, onMounted, ref } from "vue";
|
||||||
import { useRosterStore } from "../stores/roster";
|
import { useRosterStore } from "../stores/roster";
|
||||||
import { useRoute } from "vue-router";
|
import { RouterLink, useRoute } from "vue-router";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { useEventsStore } from "@/stores/events";
|
import { useEventsStore } from "@/stores/events";
|
||||||
import EventSchedulerForm from "@/components/EventSchedulerForm.vue";
|
import EventSchedulerForm from "@/components/EventSchedulerForm.vue";
|
||||||
|
@ -60,10 +60,6 @@ onMounted(async () => {
|
||||||
</main>
|
</main>
|
||||||
<main v-else>
|
<main v-else>
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<a>
|
|
||||||
<i class="bi bi-arrow-left" />
|
|
||||||
Back
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="form-group margin column">
|
<div class="form-group margin column">
|
||||||
|
|
|
@ -138,6 +138,12 @@ onMounted(() => {
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="button-group" v-if="isEditing">
|
||||||
|
<span class="subtext">
|
||||||
|
CTRL + Click to fill entire visible column,
|
||||||
|
Shift + Click to fill entire row
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
|
Loading…
Reference in New Issue