Compare commits

..

No commits in common. "54daa904be455559db212476af736fd5d06e1307" and "88969111adb09b078f254fbadbbdfed9fcd5e5dd" have entirely different histories.

23 changed files with 127 additions and 281 deletions

View File

@ -34,7 +34,7 @@
--surface-0: #ccd0da; --surface-0: #ccd0da;
--base: #eff1f5; --base: #eff1f5;
--base-0: #fcfdfe; --base-extra: #f5f6f7;
--mantle: #e6e9ef; --mantle: #e6e9ef;
--crust: #dce0e8; --crust: #dce0e8;
@ -58,7 +58,6 @@
--lavender: #7287fd; --lavender: #7287fd;
--accent: var(--lavender); --accent: var(--lavender);
--accent-0: color-mix(in srgb, var(--accent), var(--text) 50%);
--lavender-transparent: color-mix(in srgb, var(--lavender), transparent 80%); --lavender-transparent: color-mix(in srgb, var(--lavender), transparent 80%);
--accent-transparent-80: color-mix(in srgb, var(--accent), transparent 80%); --accent-transparent-80: color-mix(in srgb, var(--accent), transparent 80%);
--accent-transparent-50: color-mix(in srgb, var(--accent), transparent 50%); --accent-transparent-50: color-mix(in srgb, var(--accent), transparent 50%);
@ -85,19 +84,18 @@
--sapphire: #7dc4e4; --sapphire: #7dc4e4;
--blue: #8aadf4; --blue: #8aadf4;
--lavender: #b7bdf8; --lavender: #b7bdf8;
--text: #dad3d5; --text: #cad3f5;
--subtext-1: #bec0c0; --subtext-1: #b8c0e0;
--subtext-0: #abada5; --subtext-0: #a5adcb;
--overlay-2: #9a9a9a; --overlay-2: #939ab7;
--overlay-1: #8b8b8b; --overlay-1: #8087a2;
--overlay-0: #717171; --overlay-0: #6e738d;
--surface-2: #575757; --surface-2: #5b6078;
--surface-1: #3f3f3f; --surface-1: #494d64;
--surface-0: #2f2f2f; --surface-0: #363a4f;
--base: #181818; --base: #24273a;
--base-0: #242424; --mantle: #1e2030;
--mantle: #121212; --crust: #181926;
--crust: #0f0f0f;
--destructive: var(--red); --destructive: var(--red);
*/ */
} }

View File

@ -24,8 +24,8 @@ button {
align-items: center; align-items: center;
gap: 4px; gap: 4px;
color: var(--text); color: var(--text);
background-color: var(--base-0); background-color: var(--crust);
border: 1px solid var(--surface-0); border: none;
padding: 6px 20px; padding: 6px 20px;
line-height: 1.6; line-height: 1.6;
border-radius: 4px; border-radius: 4px;
@ -46,10 +46,6 @@ button {
transition-duration: 200ms; transition-duration: 200ms;
} }
button.no-border {
border: none;
}
button.icon-end { button.icon-end {
justify-content: space-between; justify-content: space-between;
} }
@ -57,7 +53,6 @@ button.icon-end {
button.icon { button.icon {
background-color: transparent; background-color: transparent;
padding: 8px; padding: 8px;
border: none;
} }
button.icon:hover { button.icon:hover {
@ -99,7 +94,6 @@ button:hover {
button.accent { button.accent {
background-color: var(--accent); background-color: var(--accent);
color: var(--base); color: var(--base);
border-color: var(--accent-0);
/*text-transform: uppercase;*/ /*text-transform: uppercase;*/
} }
@ -254,11 +248,6 @@ textarea {
resize: vertical; resize: vertical;
} }
input:focus, textarea:focus {
box-shadow: 1px 1px 8px var(--surface-0);
outline: none;
}
.form-group { .form-group {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -292,7 +281,7 @@ hr {
} }
[role="menu"], [role="listbox"] { [role="menu"], [role="listbox"] {
background-color: var(--base-0); background-color: var(--base);
border: 1px solid var(--overlay-0); border: 1px solid var(--overlay-0);
border-radius: 4px; border-radius: 4px;
padding: 4px 0 4px 0; padding: 4px 0 4px 0;
@ -310,10 +299,9 @@ hr {
} }
[role="menu"] button { [role="menu"] button {
background-color: var(--base-0); background-color: var(--base);
width: 100%; width: 100%;
border-radius: 0; border-radius: 0;
border: none;
} }
[role="menu"] button.destructive { [role="menu"] button.destructive {
@ -347,7 +335,7 @@ hr {
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%);
background-color: var(--base-0); background-color: var(--base);
z-index: 10; z-index: 10;
animation: smooth-appear 0.2s ease; animation: smooth-appear 0.2s ease;
} }
@ -375,49 +363,3 @@ div.banner.info {
background-color: var(--lavender-transparent); background-color: var(--lavender-transparent);
color: var(--lavender); color: var(--lavender);
} }
table {
border-collapse: separate;
border-spacing: 0;
}
th:first-child {
border-top-left-radius: 4px;
border-left: 1px solid var(--surface-0);
}
th {
text-align: left;
padding: 0.5rem 1rem;
border-top: 1px solid var(--surface-0);
border-bottom: 1px solid var(--surface-0);
font-size: 10pt;
}
th:last-child {
border-top-right-radius: 4px;
border-right: 1px solid var(--surface-0);
}
td {
padding: 0.5rem 1rem;
border-bottom: 1px solid var(--surface-0);
background-color: var(--base-0);
font-size: 10pt;
}
td:first-child {
border-left: 1px solid var(--surface-0);
}
td:last-child {
border-right: 1px solid var(--surface-0);
}
tr:last-child > td:first-child {
border-bottom-left-radius: 4px;
}
tr:last-child > td:last-child {
border-bottom-right-radius: 4px;
}

View File

@ -8,7 +8,6 @@ const scheduleStore = useScheduleStore();
const model = defineModel<number[]>({ required: true }); const model = defineModel<number[]>({ required: true });
const selectedTime = defineModel("selectedTime"); const selectedTime = defineModel("selectedTime");
const selectedIndex = defineModel("selectedIndex");
const hoveredIndex = defineModel("hoveredIndex"); const hoveredIndex = defineModel("hoveredIndex");
@ -143,20 +142,11 @@ function onSlotMouseUp(_: MouseEvent) {
} }
function onSlotClick(dayIndex: number, hour: number) { function onSlotClick(dayIndex: number, hour: number) {
let index = dayIndex * 24 + hour;
if (isEditing.value) { if (isEditing.value) {
return; return;
} }
if (selectedIndex.value == index) {
selectedIndex.value = -1;
selectedTime.value = undefined;
return;
}
selectedTime.value = getTimeAtCell(dayIndex, hour); selectedTime.value = getTimeAtCell(dayIndex, hour);
selectedIndex.value = index;
scheduleStore.selectIndex(24 * dayIndex + hour); scheduleStore.selectIndex(24 * dayIndex + hour);
} }
@ -245,7 +235,6 @@ function getHour(offset: number, tz?: string) {
:class="{ :class="{
'time-slot': true, 'time-slot': true,
'height-24px': true, 'height-24px': true,
'selected': selectedIndex == 24 * dayIndex + hour,
}" }"
:selection=" :selection="
selectionInside(dayIndex, hour) ? selectionValue selectionInside(dayIndex, hour) ? selectionValue
@ -326,34 +315,9 @@ function getHour(offset: number, tz?: string) {
font-weight: 700; font-weight: 700;
} }
.time-slot:hover, .time-slot.selected {
outline: 2px inset var(--subtext-0);
}
.time-slot.selected {
outline-style: solid;
animation: pulse 1s infinite;
}
.time-slot.selected:hover {
outline-style: solid;
}
@keyframes pulse {
0% {
outline-color: var(--overlay-0);
}
50% {
outline-color: var(--text);
}
100% {
outline-color: var(--overlay-0);
}
}
.time-slot:hover { .time-slot:hover {
background-color: var(--crust); background-color: var(--crust);
outline-style: dashed; outline: 2px inset var(--subtext-0);
} }
.time-slot:nth-child(2n):not(:last-child) { .time-slot:nth-child(2n):not(:last-child) {

View File

@ -109,8 +109,7 @@ h3 {
.event-card { .event-card {
display: flex; display: flex;
align-items: center; align-items: center;
background-color: var(--base-0); /*background-color: white;*/
border-radius: 8px;
align-items: stretch; align-items: stretch;
} }
@ -140,7 +139,7 @@ h3 {
.details { .details {
padding: 1rem; padding: 1rem;
border: 1px solid var(--surface-0); border: 1px solid var(--text);
border-radius: 0 8px 8px 0; border-radius: 0 8px 8px 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -113,12 +113,11 @@ const selectedOption = computed({
<style scoped> <style scoped>
.event-confirm-button { .event-confirm-button {
display: flex; display: flex;
gap: 0px; gap: 2px;
} }
.left { .left {
border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px;
border-right: none;
} }
.right { .right {
@ -129,10 +128,5 @@ const selectedOption = computed({
.confirmed button.recolor { .confirmed button.recolor {
background-color: var(--text); background-color: var(--text);
color: var(--base); color: var(--base);
border-color: var(--text);
}
.confirmed .left.recolor {
border-right: 1px solid var(--surface-0);
} }
</style> </style>

View File

@ -1,36 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { EventWithPlayerSchema, TeamSchema } from "@/client"; import type { EventWithPlayerSchema, TeamSchema } from "@/client";
import EventCard from "./EventCard.vue"; import EventCard from "./EventCard.vue";
import { onMounted, ref } from "vue";
import { useTeamDetails } from "@/composables/team-details";
import { useTeamsStore } from "@/stores/teams";
import { useTeamsEventsStore } from "@/stores/teams/events";
import LoaderContainer from "./LoaderContainer.vue";
import { computed } from "@vue/reactivity";
const { teamId, team } = useTeamDetails(); const props = defineProps<{
events: EventWithPlayerSchema[];
const teamsStore = useTeamsStore(); teamContext: TeamSchema;
const teamsEventsStore = useTeamsEventsStore(); }>();
const isLoading = ref(false);
const events = computed(() => teamsEventsStore.teamEvents[teamId.value]);
onMounted(() => {
isLoading.value = true;
teamsStore.fetchTeam(teamId.value)
.then(() => {
teamsEventsStore.fetchTeamEvents(teamId.value)
.finally(() => isLoading.value = false);
});
});
</script> </script>
<template> <template>
<LoaderContainer v-if="isLoading" height="160"> <div class="events-list" v-if="props.events?.length > 0">
<rect x="0" y="0" rx="4" ry="4" width="100%" height="160" /> <EventCard v-for="event in props.events" :key="event.event.id" :event="event" />
</LoaderContainer>
<div class="events-list" v-else-if="events?.length > 0">
<EventCard v-for="event in events" :key="event.event.id" :event="event" />
</div> </div>
<div class="events-list" v-else> <div class="events-list" v-else>
<em class="subtext"> <em class="subtext">
@ -39,7 +19,7 @@ onMounted(() => {
:to="{ :to="{
name: 'schedule', name: 'schedule',
query: { query: {
teamId, teamId: props.teamContext.id
} }
}" }"
> >

View File

@ -42,16 +42,14 @@ function revokeInvite() {
<td> <td>
{{ createdAt }} {{ createdAt }}
</td> </td>
<td> <td class="buttons">
<div class="buttons">
<button @click="copyLink"> <button @click="copyLink">
<i class="bi bi-link margin" /> <i class="bi bi-link margin" />
Copy Link Copy Link
</button> </button>
<button class="icon" @click="revokeInvite"> <button class="destructive" @click="revokeInvite">
<i class="bi bi-trash" /> <i class="bi bi-trash" />
</button> </button>
</div>
</td> </td>
</tr> </tr>
</template> </template>

View File

@ -1,24 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { ContentLoader } from "vue-content-loader"; import Loader from './Loader.vue';
const props = defineProps<{
width?: string;
height?: string;
speed?: number;
}>();
// get primary color from var(--overlay-0) and secondary from var(--overlay-1)
const primaryColor = getComputedStyle(document.documentElement).getPropertyValue("--surface-0");
const secondaryColor = getComputedStyle(document.documentElement).getPropertyValue("--overlay-0");
</script> </script>
<template> <template>
<!--ContentLoader :width="width" :height="height" :speed="speed"> <div class="loader-container">
</ContentLoader--> <Loader />
<component :is="ContentLoader" v-bind="{ ...props, primaryColor, secondaryColor }"> </div>
<slot></slot>
</component>
</template> </template>
<style scoped> <style scoped>

View File

@ -65,8 +65,7 @@ const props = defineProps<{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 1rem; padding: 1rem;
border: 1px solid var(--surface-0); border: 1px solid var(--text);
background-color: var(--base-0);
border-radius: 8px; border-radius: 8px;
gap: 0.5rem; gap: 0.5rem;
} }

View File

@ -1,10 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTeamsStore } from "../stores/teams"; import { useTeamsStore } from "../stores/teams";
import { useRoute, useRouter, RouterLink } from "vue-router"; import { useRoute, useRouter, RouterLink } from "vue-router";
import { computed, onMounted, ref } from "vue"; import { computed } from "vue";
import { useTeamDetails } from "../composables/team-details"; import { useTeamDetails } from "../composables/team-details";
import PlayerTeamCard from "../components/PlayerTeamCard.vue"; import PlayerTeamCard from "../components/PlayerTeamCard.vue";
import LoaderContainer from "./LoaderContainer.vue";
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@ -16,13 +15,16 @@ const {
availableMembersNextHour, availableMembersNextHour,
teamMembers, teamMembers,
} = useTeamDetails(); } = useTeamDetails();
const isLoading = ref(false);
onMounted(() => { function leaveTeam() {
isLoading.value = true; teamsStore.leaveTeam(team.value.id)
teamsStore.fetchTeamMembers(team.value.id) .then(() => {
.finally(() => isLoading.value = false); teamsStore.fetchTeams()
}); .then(() => {
router.push("/");
})
});
}
</script> </script>
<template> <template>
@ -37,21 +39,7 @@ onMounted(() => {
<div class="team-details-button-group"> <div class="team-details-button-group">
</div> </div>
</div> </div>
<LoaderContainer v-if="isLoading"> <table class="member-table">
<rect x="0" y="10" rx="3" ry="3" width="100%" height="10" />
<rect x="0" y="30" rx="3" ry="3" width="100%" height="10" />
<rect x="0" y="50" rx="3" ry="3" width="100%" height="10" />
<rect x="0" y="70" rx="3" ry="3" width="100%" height="10" />
</LoaderContainer>
<table class="member-table" v-else>
<thead>
<tr>
<th>Username</th>
<th>Roles</th>
<th>Playtime</th>
<th></th>
</tr>
</thead>
<tbody> <tbody>
<PlayerTeamCard <PlayerTeamCard
v-for="member in teamMembers" v-for="member in teamMembers"
@ -79,6 +67,12 @@ table.member-table {
width: 100%; width: 100%;
} }
table.member-table th {
text-align: left;
padding-left: 2em;
font-weight: 700;
}
.team-details-button-group { .team-details-button-group {
flex: 1; flex: 1;
display: flex; display: flex;

View File

@ -82,14 +82,14 @@ const playtime = computed(() => {
<style scoped> <style scoped>
.player-card { .player-card {
background-color: var(--base-0); background-color: white;
padding: 1em; padding: 1em;
border-radius: 8px; border-radius: 8px;
user-select: none; user-select: none;
display: flex; display: flex;
gap: 1em; gap: 1em;
align-items: center; align-items: center;
border: 2px solid var(--surface-0); border: 2px solid white;
box-shadow: 1px 1px 8px var(--surface-0); box-shadow: 1px 1px 8px var(--surface-0);
} }
@ -122,13 +122,13 @@ const playtime = computed(() => {
} }
.player-card.no-player { .player-card.no-player {
border: 2px dashed var(--overlay-0); border: 2px solid var(--overlay-0);
box-shadow: none; box-shadow: none;
} }
.player-card.no-player.selected { .player-card.no-player.selected {
background-color: var(--accent-transparent); background-color: var(--accent-transparent);
border: 2px dashed var(--accent); border: 2px solid var(--accent);
color: var(--accent); color: var(--accent);
} }

View File

@ -180,7 +180,7 @@ const rightIndicator = computed(() => {
No roles No roles
</span> </span>
<div class="edit-group"> <div class="edit-group">
<button v-if="!isEditing" class="icon" @click="isEditing = true"> <button v-if="!isEditing" @click="isEditing = true">
<i class="bi bi-pencil-fill edit-icon" /> <i class="bi bi-pencil-fill edit-icon" />
</button> </button>
</div> </div>
@ -197,10 +197,10 @@ const rightIndicator = computed(() => {
<td> <td>
<div class="edit-group"> <div class="edit-group">
<template v-if="isEditing"> <template v-if="isEditing">
<button class="editing icon" @click="cancelEdit()"> <button class="editing" @click="cancelEdit()">
<i class="bi bi-x-lg" /> <i class="bi bi-x-lg" />
</button> </button>
<button class="editing icon" @click="updateRoles()"> <button class="editing" @click="updateRoles()">
<i class="bi bi-check-lg" /> <i class="bi bi-check-lg" />
</button> </button>
</template> </template>
@ -314,6 +314,10 @@ a.player-name:hover {
opacity: 1; opacity: 1;
} }
.edit-group > button.editing {
opacity: 1;
}
@media (max-width: 1024px) { @media (max-width: 1024px) {
.player-card > td { .player-card > td {
padding: 0.5em 0em; padding: 0.5em 0em;

View File

@ -18,7 +18,7 @@ function logout() {
<template> <template>
<DropdownMenuRoot> <DropdownMenuRoot>
<DropdownMenuTrigger className="profile-button no-border"> <DropdownMenuTrigger className="profile-button">
{{ authStore.username }} {{ authStore.username }}
<i class="bi bi-chevron-down" /> <i class="bi bi-chevron-down" />
</DropdownMenuTrigger> </DropdownMenuTrigger>

View File

@ -47,7 +47,6 @@ function toggle(isMain: boolean) {
</div> </div>
<button <button
:class="{ :class="{
'no-border': true,
'center': true, 'center': true,
'selected': roleObject?.isMain 'selected': roleObject?.isMain
}" }"
@ -57,7 +56,6 @@ function toggle(isMain: boolean) {
</button> </button>
<button <button
:class="{ :class="{
'no-border': true,
'right': true, 'right': true,
'selected': !(roleObject?.isMain ?? true) 'selected': !(roleObject?.isMain ?? true)
}" }"

View File

@ -5,7 +5,6 @@ import { RouterLink } from "vue-router";
import { useAuthStore } from "@/stores/auth"; import { useAuthStore } from "@/stores/auth";
import InviteKeyDialog from "./InviteKeyDialog.vue"; import InviteKeyDialog from "./InviteKeyDialog.vue";
import { ContentLoader } from "vue-content-loader"; import { ContentLoader } from "vue-content-loader";
import LoaderContainer from "./LoaderContainer.vue";
const teams = useTeamsStore(); const teams = useTeamsStore();
const isLoading = ref(false); const isLoading = ref(false);
@ -44,13 +43,17 @@ onMounted(() => {
<div v-if="!authStore.isLoggedIn"> <div v-if="!authStore.isLoggedIn">
Log in to view your teams. Log in to view your teams.
</div> </div>
<div v-else-if="isLoading"> <div v-else-if="isLoading || true">
<LoaderContainer> <ContentLoader :speed="1">
<rect x="0" y="15" rx="5" ry="5" width="220" height="10" /> <circle cx="10" cy="20" r="8" />
<rect x="0" y="45" rx="5" ry="5" width="220" height="10" /> <rect x="25" y="15" rx="5" ry="5" width="220" height="10" />
<rect x="0" y="75" rx="5" ry="5" width="220" height="10" /> <circle cx="10" cy="50" r="8" />
<rect x="0" y="105" rx="5" ry="5" width="220" height="10" /> <rect x="25" y="45" rx="5" ry="5" width="220" height="10" />
</LoaderContainer> <circle cx="10" cy="80" r="8" />
<rect x="25" y="75" rx="5" ry="5" width="220" height="10" />
<circle cx="10" cy="110" r="8" />
<rect x="25" y="105" rx="5" ry="5" width="220" height="10" />
</ContentLoader>
</div> </div>
<div <div
v-else-if="teams.teamsWithRole" v-else-if="teams.teamsWithRole"

View File

@ -21,11 +21,11 @@ function incrementDate(delta: number) {
<template> <template>
<div class="scroll-box"> <div class="scroll-box">
<button class="transparent icon" @click="incrementDate(-1)" :disabled="isDisabled"> <button class="transparent eq" @click="incrementDate(-1)" :disabled="isDisabled">
<i class="bi bi-caret-left-fill"></i> <i class="bi bi-caret-left-fill"></i>
</button> </button>
<span class="date-range">{{ dateStart }} &ndash; {{ dateEnd }}</span> <span class="date-range">{{ dateStart }} &ndash; {{ dateEnd }}</span>
<button class="transparent icon" @click="incrementDate(1)" :disabled="isDisabled"> <button class="transparent eq" @click="incrementDate(1)" :disabled="isDisabled">
<i class="bi bi-caret-right-fill"></i> <i class="bi bi-caret-right-fill"></i>
</button> </button>
</div> </div>

View File

@ -189,6 +189,7 @@ main {
.radio-group { .radio-group {
display: flex; display: flex;
gap: 2px;
} }
button.radio { button.radio {
@ -206,7 +207,6 @@ button.radio.selected {
button.left { button.left {
border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px;
border-right-width: 0px;
} }
button.radio.left.selected { button.radio.left.selected {

View File

@ -11,7 +11,6 @@ import { useTeamsEventsStore } from "@/stores/teams/events";
import MatchCard from "@/components/MatchCard.vue"; import MatchCard from "@/components/MatchCard.vue";
import { useMatchesStore } from "@/stores/matches"; import { useMatchesStore } from "@/stores/matches";
import { ContentLoader } from "vue-content-loader"; import { ContentLoader } from "vue-content-loader";
import LoaderContainer from "@/components/LoaderContainer.vue";
const route = useRoute(); const route = useRoute();
const teamsStore = useTeamsStore(); const teamsStore = useTeamsStore();
@ -37,8 +36,8 @@ onMounted(() => {
let doFetchTeam = () => { let doFetchTeam = () => {
teamsStore.fetchTeam(teamId.value) teamsStore.fetchTeam(teamId.value)
.then(() => { .then(() => {
//teamsStore.fetchTeamMembers(teamId.value); teamsStore.fetchTeamMembers(teamId.value);
//teamsEventsStore.fetchTeamEvents(teamId.value); teamsEventsStore.fetchTeamEvents(teamId.value);
matchesStore.fetchRecentMatchesForTeam(teamId.value, 5); matchesStore.fetchRecentMatchesForTeam(teamId.value, 5);
isLoading.value = false; isLoading.value = false;
}); });
@ -60,10 +59,10 @@ onMounted(() => {
<div class="left"> <div class="left">
<center class="margin"> <center class="margin">
<h1> <h1>
<template v-if="isLoading"> <template v-if="isLoading || true">
<LoaderContainer view-box="0 0 250 10"> <content-loader view-box="0 0 250 10">
<rect x="0" y="0" rx="3" ry="3" width="250" height="10" /> <rect x="0" y="0" rx="3" ry="3" width="250" height="10" />
</LoaderContainer> </content-loader>
</template> </template>
<template v-else> <template v-else>
{{ team.teamName }} {{ team.teamName }}
@ -89,7 +88,7 @@ onMounted(() => {
</div> </div>
<div class="right"> <div class="right">
<h2>Upcoming Events</h2> <h2>Upcoming Events</h2>
<EventList /> <EventList :events="events" :team-context="team" />
<h2 id="recent-matches-header"> <h2 id="recent-matches-header">
Recent Matches Recent Matches
<RouterLink class="button" :to="{ name: 'team-settings/matches' }"> <RouterLink class="button" :to="{ name: 'team-settings/matches' }">
@ -98,15 +97,15 @@ onMounted(() => {
</button> </button>
</RouterLink> </RouterLink>
</h2> </h2>
<em class="subtext" v-if="!matches">
No recent matches.
</em>
<MatchCard <MatchCard
v-if="matches?.length > 0" v-else
v-for="match in matches" v-for="match in matches"
:team-match="match" :team-match="match"
:team="team" :team="team"
/> />
<em class="subtext" v-else>
No recent matches.
</em>
</div> </div>
</div> </div>
</template> </template>
@ -123,7 +122,6 @@ onMounted(() => {
.content-container { .content-container {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 1rem;
} }
.content-container > div.left { .content-container > div.left {
@ -165,7 +163,6 @@ onMounted(() => {
@media (max-width: 1024px) { @media (max-width: 1024px) {
.content-container { .content-container {
flex-direction: column; flex-direction: column;
gap: unset;
} }
} }
</style> </style>

View File

@ -5,7 +5,6 @@ import { onMounted, ref } from "vue";
import { useTeamsStore } from "@/stores/teams"; import { useTeamsStore } from "@/stores/teams";
import { useTeamDetails } from "@/composables/team-details"; import { useTeamDetails } from "@/composables/team-details";
import { computed } from "@vue/reactivity"; import { computed } from "@vue/reactivity";
import LoaderContainer from "@/components/LoaderContainer.vue";
const { const {
teamName, teamName,
@ -52,20 +51,20 @@ const hasChangedTimeDetails = computed(() => {
); );
}); });
const isLoading = ref(false); const isLoaded = ref(false);
const teamsStore = useTeamsStore(); const teamsStore = useTeamsStore();
const team = computed(() => teamsStore.teams[teamId.value]); const team = computed(() => teamsStore.teams[teamId.value]);
onMounted(() => { onMounted(() => {
isLoading.value = true; isLoaded.value = true;
teamsStore.fetchTeam(teamId.value) teamsStore.fetchTeam(teamId.value)
.then((response) => { .then((response) => {
teamName.value = response.team.teamName; teamName.value = response.team.teamName;
timezone.value = response.team.tzTimezone; timezone.value = response.team.tzTimezone;
minuteOffset.value = response.team.minuteOffset; minuteOffset.value = response.team.minuteOffset;
isLoading.value = false; isLoaded.value = false;
}); });
}) })
</script> </script>
@ -73,15 +72,7 @@ onMounted(() => {
<template> <template>
<div class="team-general-settings"> <div class="team-general-settings">
<h2>Overview</h2> <h2>Overview</h2>
<LoaderContainer v-if="isLoading"> <div>
<rect x="0" y="10" rx="5" width="40" height="10" />
<rect x="0" y="30" rx="5" width="100%" height="10" />
<rect x="0" y="50" rx="5" width="80" height="10" />
<rect x="250" y="50" rx="5" width="40" height="10" />
<rect x="0" y="70" rx="5" width="240" height="10" />
<rect x="250" y="70" rx="5" width="100" height="10" />
</LoaderContainer>
<div v-else>
<div class="form-group margin"> <div class="form-group margin">
<h3 class="closer">Team Name</h3> <h3 class="closer">Team Name</h3>
<input v-model="teamName" /> <input v-model="teamName" />

View File

@ -6,6 +6,7 @@ import { useTeamDetails } from "@/composables/team-details";
import { useTeamsStore } from "@/stores/teams"; import { useTeamsStore } from "@/stores/teams";
import { useIntegrationsStore } from "@/stores/teams/integrations"; import { useIntegrationsStore } from "@/stores/teams/integrations";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import { ContentLoader } from "vue-content-loader";
const teamsStore = useTeamsStore(); const teamsStore = useTeamsStore();
const integrationsStore = useIntegrationsStore(); const integrationsStore = useIntegrationsStore();
@ -32,14 +33,14 @@ onMounted(() => {
<template> <template>
<div class="team-integrations"> <div class="team-integrations">
<div v-if="isLoading"> <div v-if="isLoading">
<LoaderContainer> <ContentLoader>
<rect x="0" y="0" rx="5" ry="5" width="250" height="10" /> <rect x="0" y="0" rx="3" ry="3" width="250" height="10" />
<rect x="20" y="20" rx="5" ry="5" width="220" height="10" /> <rect x="20" y="20" rx="3" ry="3" width="220" height="10" />
<rect x="20" y="40" rx="5" ry="5" width="170" height="10" /> <rect x="20" y="40" rx="3" ry="3" width="170" height="10" />
<rect x="0" y="60" rx="5" ry="5" width="250" height="10" /> <rect x="0" y="60" rx="3" ry="3" width="250" height="10" />
<rect x="20" y="80" rx="5" ry="5" width="200" height="10" /> <rect x="20" y="80" rx="3" ry="3" width="200" height="10" />
<rect x="20" y="100" rx="5" ry="5" width="80" height="10" /> <rect x="20" y="100" rx="3" ry="3" width="80" height="10" />
</LoaderContainer> </ContentLoader>
</div> </div>
<template v-else> <template v-else>
<DiscordIntegrationForm v-model="integrationsStore.discordIntegration" /> <DiscordIntegrationForm v-model="integrationsStore.discordIntegration" />

View File

@ -27,16 +27,6 @@ onMounted(() => {
<template> <template>
<div class="invites" v-if="team"> <div class="invites" v-if="team">
<h2>Invites</h2> <h2>Invites</h2>
<p class="small aside">
Invite players to your team by creating an invite link.
All invites are usable only once.
</p>
<div class="create-invite-group">
<button class="accent" @click="createInvite">
<i class="bi bi-person-fill-add margin" />
Create Invite
</button>
</div>
<table id="invite-table" v-if="invites?.length > 0"> <table id="invite-table" v-if="invites?.length > 0">
<thead> <thead>
<tr> <tr>
@ -46,8 +36,6 @@ onMounted(() => {
<th> <th>
Creation time Creation time
</th> </th>
<th>
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -57,12 +45,22 @@ onMounted(() => {
/> />
</tbody> </tbody>
</table> </table>
<div class="create-invite-group">
<button class="accent" @click="createInvite">
<i class="bi bi-person-fill-add margin" />
Create Invite
</button>
<span class="small aside">
Invites are usable once and expire after 24 hours.
</span>
</div>
</div> </div>
</template> </template>
<style scoped> <style scoped>
#invite-table { #invite-table {
width: 100%; width: 100%;
border: 1px solid var(--overlay-0);
border-radius: 8px; border-radius: 8px;
margin: 8px 0; margin: 8px 0;
} }
@ -77,6 +75,5 @@ onMounted(() => {
display: flex; display: flex;
gap: 8px; gap: 8px;
align-items: center; align-items: center;
justify-content: end;
} }
</style> </style>

View File

@ -25,10 +25,10 @@ onMounted(() => {
<i class="bi bi-trophy-fill margin"></i> <i class="bi bi-trophy-fill margin"></i>
Matches Matches
</h2> </h2>
</div>
<div class="button-group"> <div class="button-group">
<AddMatchDialog /> <AddMatchDialog />
</div> </div>
</div>
<table> <table>
<thead> <thead>
<tr> <tr>
@ -71,4 +71,9 @@ onMounted(() => {
table { table {
width: 100%; width: 100%;
} }
th {
text-align: left;
font-weight: 800;
}
</style> </style>

View File

@ -46,7 +46,7 @@ onMounted(() => {
Matches Matches
</RouterLink> </RouterLink>
<hr> <hr>
<button class="destructive-on-hover icon-end no-border" @click="leaveTeam"> <button class="destructive-on-hover icon-end" @click="leaveTeam">
Leave team Leave team
<i class="bi bi-box-arrow-left" /> <i class="bi bi-box-arrow-left" />
</button> </button>
@ -122,9 +122,4 @@ nav.sidebar button:hover {
background-color: var(--crust); background-color: var(--crust);
color: var(--text); color: var(--text);
} }
nav.sidebar button.destructive-on-hover:hover {
background-color: var(--destructive);
color: var(--base);
}
</style> </style>