Compare commits
	
		
			2 Commits 
		
	
	
		
			88969111ad
			...
			54daa904be
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						54daa904be | |
| 
							
							
								
									
								
								 | 
						95efd01eef | 
| 
						 | 
					@ -34,7 +34,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  --surface-0: #ccd0da;
 | 
					  --surface-0: #ccd0da;
 | 
				
			||||||
  --base: #eff1f5;
 | 
					  --base: #eff1f5;
 | 
				
			||||||
  --base-extra: #f5f6f7;
 | 
					  --base-0: #fcfdfe;
 | 
				
			||||||
  --mantle: #e6e9ef;
 | 
					  --mantle: #e6e9ef;
 | 
				
			||||||
  --crust: #dce0e8;
 | 
					  --crust: #dce0e8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  --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%);
 | 
				
			||||||
| 
						 | 
					@ -84,18 +85,19 @@
 | 
				
			||||||
  --sapphire: #7dc4e4;
 | 
					  --sapphire: #7dc4e4;
 | 
				
			||||||
  --blue: #8aadf4;
 | 
					  --blue: #8aadf4;
 | 
				
			||||||
  --lavender: #b7bdf8;
 | 
					  --lavender: #b7bdf8;
 | 
				
			||||||
  --text: #cad3f5;
 | 
					  --text: #dad3d5;
 | 
				
			||||||
  --subtext-1: #b8c0e0;
 | 
					  --subtext-1: #bec0c0;
 | 
				
			||||||
  --subtext-0: #a5adcb;
 | 
					  --subtext-0: #abada5;
 | 
				
			||||||
  --overlay-2: #939ab7;
 | 
					  --overlay-2: #9a9a9a;
 | 
				
			||||||
  --overlay-1: #8087a2;
 | 
					  --overlay-1: #8b8b8b;
 | 
				
			||||||
  --overlay-0: #6e738d;
 | 
					  --overlay-0: #717171;
 | 
				
			||||||
  --surface-2: #5b6078;
 | 
					  --surface-2: #575757;
 | 
				
			||||||
  --surface-1: #494d64;
 | 
					  --surface-1: #3f3f3f;
 | 
				
			||||||
  --surface-0: #363a4f;
 | 
					  --surface-0: #2f2f2f;
 | 
				
			||||||
  --base: #24273a;
 | 
					  --base: #181818;
 | 
				
			||||||
  --mantle: #1e2030;
 | 
					  --base-0: #242424;
 | 
				
			||||||
  --crust: #181926;
 | 
					  --mantle: #121212;
 | 
				
			||||||
 | 
					  --crust: #0f0f0f;
 | 
				
			||||||
  --destructive: var(--red);
 | 
					  --destructive: var(--red);
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,8 +24,8 @@ button {
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  gap: 4px;
 | 
					  gap: 4px;
 | 
				
			||||||
  color: var(--text);
 | 
					  color: var(--text);
 | 
				
			||||||
  background-color: var(--crust);
 | 
					  background-color: var(--base-0);
 | 
				
			||||||
  border: none;
 | 
					  border: 1px solid var(--surface-0);
 | 
				
			||||||
  padding: 6px 20px;
 | 
					  padding: 6px 20px;
 | 
				
			||||||
  line-height: 1.6;
 | 
					  line-height: 1.6;
 | 
				
			||||||
  border-radius: 4px;
 | 
					  border-radius: 4px;
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,10 @@ 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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -53,6 +57,7 @@ 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 {
 | 
				
			||||||
| 
						 | 
					@ -94,6 +99,7 @@ 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;*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -248,6 +254,11 @@ 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;
 | 
				
			||||||
| 
						 | 
					@ -281,7 +292,7 @@ hr {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[role="menu"], [role="listbox"] {
 | 
					[role="menu"], [role="listbox"] {
 | 
				
			||||||
  background-color: var(--base);
 | 
					  background-color: var(--base-0);
 | 
				
			||||||
  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;
 | 
				
			||||||
| 
						 | 
					@ -299,9 +310,10 @@ hr {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[role="menu"] button {
 | 
					[role="menu"] button {
 | 
				
			||||||
  background-color: var(--base);
 | 
					  background-color: var(--base-0);
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  border-radius: 0;
 | 
					  border-radius: 0;
 | 
				
			||||||
 | 
					  border: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[role="menu"] button.destructive {
 | 
					[role="menu"] button.destructive {
 | 
				
			||||||
| 
						 | 
					@ -335,7 +347,7 @@ hr {
 | 
				
			||||||
  top: 50%;
 | 
					  top: 50%;
 | 
				
			||||||
  left: 50%;
 | 
					  left: 50%;
 | 
				
			||||||
  transform: translateX(-50%) translateY(-50%);
 | 
					  transform: translateX(-50%) translateY(-50%);
 | 
				
			||||||
  background-color: var(--base);
 | 
					  background-color: var(--base-0);
 | 
				
			||||||
  z-index: 10;
 | 
					  z-index: 10;
 | 
				
			||||||
  animation: smooth-appear 0.2s ease;
 | 
					  animation: smooth-appear 0.2s ease;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -363,3 +375,49 @@ 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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ 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");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,11 +143,20 @@ 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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -235,6 +245,7 @@ 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
 | 
				
			||||||
| 
						 | 
					@ -315,9 +326,34 @@ 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: 2px inset var(--subtext-0);
 | 
					  outline-style: dashed;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.time-slot:nth-child(2n):not(:last-child) {
 | 
					.time-slot:nth-child(2n):not(:last-child) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,7 +109,8 @@ h3 {
 | 
				
			||||||
.event-card {
 | 
					.event-card {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  /*background-color: white;*/
 | 
					  background-color: var(--base-0);
 | 
				
			||||||
 | 
					  border-radius: 8px;
 | 
				
			||||||
  align-items: stretch;
 | 
					  align-items: stretch;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,7 +140,7 @@ h3 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.details {
 | 
					.details {
 | 
				
			||||||
  padding: 1rem;
 | 
					  padding: 1rem;
 | 
				
			||||||
  border: 1px solid var(--text);
 | 
					  border: 1px solid var(--surface-0);
 | 
				
			||||||
  border-radius: 0 8px 8px 0;
 | 
					  border-radius: 0 8px 8px 0;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,11 +113,12 @@ const selectedOption = computed({
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
.event-confirm-button {
 | 
					.event-confirm-button {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  gap: 2px;
 | 
					  gap: 0px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.left {
 | 
					.left {
 | 
				
			||||||
  border-radius: 4px 0 0 4px;
 | 
					  border-radius: 4px 0 0 4px;
 | 
				
			||||||
 | 
					  border-right: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.right {
 | 
					.right {
 | 
				
			||||||
| 
						 | 
					@ -128,5 +129,10 @@ 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>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,16 +1,36 @@
 | 
				
			||||||
<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 props = defineProps<{
 | 
					const { teamId, team } = useTeamDetails();
 | 
				
			||||||
  events: EventWithPlayerSchema[];
 | 
					
 | 
				
			||||||
  teamContext: TeamSchema;
 | 
					const teamsStore = useTeamsStore();
 | 
				
			||||||
}>();
 | 
					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>
 | 
				
			||||||
  <div class="events-list" v-if="props.events?.length > 0">
 | 
					  <LoaderContainer v-if="isLoading" height="160">
 | 
				
			||||||
    <EventCard v-for="event in props.events" :key="event.event.id" :event="event" />
 | 
					    <rect x="0" y="0" rx="4" ry="4" width="100%" height="160" />
 | 
				
			||||||
 | 
					  </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">
 | 
				
			||||||
| 
						 | 
					@ -19,7 +39,7 @@ const props = defineProps<{
 | 
				
			||||||
        :to="{
 | 
					        :to="{
 | 
				
			||||||
          name: 'schedule',
 | 
					          name: 'schedule',
 | 
				
			||||||
          query: {
 | 
					          query: {
 | 
				
			||||||
            teamId: props.teamContext.id
 | 
					            teamId,
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }"
 | 
					        }"
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,14 +42,16 @@ function revokeInvite() {
 | 
				
			||||||
    <td>
 | 
					    <td>
 | 
				
			||||||
      {{ createdAt }}
 | 
					      {{ createdAt }}
 | 
				
			||||||
    </td>
 | 
					    </td>
 | 
				
			||||||
    <td class="buttons">
 | 
					    <td>
 | 
				
			||||||
 | 
					      <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="destructive" @click="revokeInvite">
 | 
					        <button class="icon" @click="revokeInvite">
 | 
				
			||||||
          <i class="bi bi-trash" />
 | 
					          <i class="bi bi-trash" />
 | 
				
			||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
    </td>
 | 
					    </td>
 | 
				
			||||||
  </tr>
 | 
					  </tr>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,24 @@
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import Loader from './Loader.vue';
 | 
					import { ContentLoader } from "vue-content-loader";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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>
 | 
				
			||||||
  <div class="loader-container">
 | 
					  <!--ContentLoader :width="width" :height="height" :speed="speed">
 | 
				
			||||||
    <Loader />
 | 
					  </ContentLoader-->
 | 
				
			||||||
  </div>
 | 
					  <component :is="ContentLoader" v-bind="{ ...props, primaryColor, secondaryColor }">
 | 
				
			||||||
 | 
					    <slot></slot>
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,8 @@ const props = defineProps<{
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  padding: 1rem;
 | 
					  padding: 1rem;
 | 
				
			||||||
  border: 1px solid var(--text);
 | 
					  border: 1px solid var(--surface-0);
 | 
				
			||||||
 | 
					  background-color: var(--base-0);
 | 
				
			||||||
  border-radius: 8px;
 | 
					  border-radius: 8px;
 | 
				
			||||||
  gap: 0.5rem;
 | 
					  gap: 0.5rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,10 @@
 | 
				
			||||||
<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 } from "vue";
 | 
					import { computed, onMounted, ref } 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();
 | 
				
			||||||
| 
						 | 
					@ -15,16 +16,13 @@ const {
 | 
				
			||||||
  availableMembersNextHour,
 | 
					  availableMembersNextHour,
 | 
				
			||||||
  teamMembers,
 | 
					  teamMembers,
 | 
				
			||||||
} = useTeamDetails();
 | 
					} = useTeamDetails();
 | 
				
			||||||
 | 
					const isLoading = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function leaveTeam() {
 | 
					onMounted(() => {
 | 
				
			||||||
  teamsStore.leaveTeam(team.value.id)
 | 
					  isLoading.value = true;
 | 
				
			||||||
    .then(() => {
 | 
					  teamsStore.fetchTeamMembers(team.value.id)
 | 
				
			||||||
      teamsStore.fetchTeams()
 | 
					    .finally(() => isLoading.value = false);
 | 
				
			||||||
        .then(() => {
 | 
					 | 
				
			||||||
          router.push("/");
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
| 
						 | 
					@ -39,7 +37,21 @@ function leaveTeam() {
 | 
				
			||||||
    <div class="team-details-button-group">
 | 
					    <div class="team-details-button-group">
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <table class="member-table">
 | 
					  <LoaderContainer v-if="isLoading">
 | 
				
			||||||
 | 
					    <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"
 | 
				
			||||||
| 
						 | 
					@ -67,12 +79,6 @@ 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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,14 +82,14 @@ const playtime = computed(() => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
.player-card {
 | 
					.player-card {
 | 
				
			||||||
  background-color: white;
 | 
					  background-color: var(--base-0);
 | 
				
			||||||
  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 white;
 | 
					  border: 2px solid var(--surface-0);
 | 
				
			||||||
  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 solid var(--overlay-0);
 | 
					  border: 2px dashed 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 solid var(--accent);
 | 
					  border: 2px dashed var(--accent);
 | 
				
			||||||
  color: var(--accent);
 | 
					  color: var(--accent);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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" @click="isEditing = true">
 | 
					          <button v-if="!isEditing" class="icon" @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" @click="cancelEdit()">
 | 
					          <button class="editing icon" @click="cancelEdit()">
 | 
				
			||||||
            <i class="bi bi-x-lg" />
 | 
					            <i class="bi bi-x-lg" />
 | 
				
			||||||
          </button>
 | 
					          </button>
 | 
				
			||||||
          <button class="editing" @click="updateRoles()">
 | 
					          <button class="editing icon" @click="updateRoles()">
 | 
				
			||||||
            <i class="bi bi-check-lg" />
 | 
					            <i class="bi bi-check-lg" />
 | 
				
			||||||
          </button>
 | 
					          </button>
 | 
				
			||||||
        </template>
 | 
					        </template>
 | 
				
			||||||
| 
						 | 
					@ -314,10 +314,6 @@ 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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ function logout() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <DropdownMenuRoot>
 | 
					  <DropdownMenuRoot>
 | 
				
			||||||
    <DropdownMenuTrigger className="profile-button">
 | 
					    <DropdownMenuTrigger className="profile-button no-border">
 | 
				
			||||||
      {{ authStore.username }}
 | 
					      {{ authStore.username }}
 | 
				
			||||||
      <i class="bi bi-chevron-down" />
 | 
					      <i class="bi bi-chevron-down" />
 | 
				
			||||||
    </DropdownMenuTrigger>
 | 
					    </DropdownMenuTrigger>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@ function toggle(isMain: boolean) {
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <button
 | 
					    <button
 | 
				
			||||||
      :class="{
 | 
					      :class="{
 | 
				
			||||||
 | 
					        'no-border': true,
 | 
				
			||||||
        'center': true,
 | 
					        'center': true,
 | 
				
			||||||
        'selected': roleObject?.isMain
 | 
					        'selected': roleObject?.isMain
 | 
				
			||||||
      }"
 | 
					      }"
 | 
				
			||||||
| 
						 | 
					@ -56,6 +57,7 @@ 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)
 | 
				
			||||||
      }"
 | 
					      }"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ 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);
 | 
				
			||||||
| 
						 | 
					@ -43,17 +44,13 @@ 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 || true">
 | 
					    <div v-else-if="isLoading">
 | 
				
			||||||
      <ContentLoader :speed="1">
 | 
					      <LoaderContainer>
 | 
				
			||||||
        <circle cx="10" cy="20" r="8" />
 | 
					        <rect x="0" y="15" 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="45" rx="5" ry="5" width="220" height="10" />
 | 
				
			||||||
        <circle cx="10" cy="50" r="8" />
 | 
					        <rect x="0" y="75" rx="5" ry="5" width="220" height="10" />
 | 
				
			||||||
        <rect x="25" y="45" rx="5" ry="5" width="220" height="10" />
 | 
					        <rect x="0" y="105" rx="5" ry="5" width="220" height="10" />
 | 
				
			||||||
        <circle cx="10" cy="80" r="8" />
 | 
					      </LoaderContainer>
 | 
				
			||||||
        <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"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,11 +21,11 @@ function incrementDate(delta: number) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="scroll-box">
 | 
					  <div class="scroll-box">
 | 
				
			||||||
    <button class="transparent eq" @click="incrementDate(-1)" :disabled="isDisabled">
 | 
					    <button class="transparent icon" @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 }} – {{ dateEnd }}</span>
 | 
					    <span class="date-range">{{ dateStart }} – {{ dateEnd }}</span>
 | 
				
			||||||
    <button class="transparent eq" @click="incrementDate(1)" :disabled="isDisabled">
 | 
					    <button class="transparent icon" @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>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -189,7 +189,6 @@ main {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.radio-group {
 | 
					.radio-group {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  gap: 2px;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
button.radio {
 | 
					button.radio {
 | 
				
			||||||
| 
						 | 
					@ -207,6 +206,7 @@ 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 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ 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();
 | 
				
			||||||
| 
						 | 
					@ -36,8 +37,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;
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
| 
						 | 
					@ -59,10 +60,10 @@ onMounted(() => {
 | 
				
			||||||
        <div class="left">
 | 
					        <div class="left">
 | 
				
			||||||
          <center class="margin">
 | 
					          <center class="margin">
 | 
				
			||||||
            <h1>
 | 
					            <h1>
 | 
				
			||||||
              <template v-if="isLoading || true">
 | 
					              <template v-if="isLoading">
 | 
				
			||||||
                <content-loader view-box="0 0 250 10">
 | 
					                <LoaderContainer 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" />
 | 
				
			||||||
                </content-loader>
 | 
					                </LoaderContainer>
 | 
				
			||||||
              </template>
 | 
					              </template>
 | 
				
			||||||
              <template v-else>
 | 
					              <template v-else>
 | 
				
			||||||
                {{ team.teamName }}
 | 
					                {{ team.teamName }}
 | 
				
			||||||
| 
						 | 
					@ -88,7 +89,7 @@ onMounted(() => {
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="right">
 | 
					        <div class="right">
 | 
				
			||||||
          <h2>Upcoming Events</h2>
 | 
					          <h2>Upcoming Events</h2>
 | 
				
			||||||
          <EventList :events="events" :team-context="team" />
 | 
					          <EventList />
 | 
				
			||||||
          <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' }">
 | 
				
			||||||
| 
						 | 
					@ -97,15 +98,15 @@ onMounted(() => {
 | 
				
			||||||
              </button>
 | 
					              </button>
 | 
				
			||||||
            </RouterLink>
 | 
					            </RouterLink>
 | 
				
			||||||
          </h2>
 | 
					          </h2>
 | 
				
			||||||
          <em class="subtext" v-if="!matches">
 | 
					 | 
				
			||||||
            No recent matches.
 | 
					 | 
				
			||||||
          </em>
 | 
					 | 
				
			||||||
          <MatchCard
 | 
					          <MatchCard
 | 
				
			||||||
            v-else
 | 
					            v-if="matches?.length > 0"
 | 
				
			||||||
            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>
 | 
				
			||||||
| 
						 | 
					@ -122,6 +123,7 @@ 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 {
 | 
				
			||||||
| 
						 | 
					@ -163,6 +165,7 @@ onMounted(() => {
 | 
				
			||||||
@media (max-width: 1024px) {
 | 
					@media (max-width: 1024px) {
 | 
				
			||||||
  .content-container {
 | 
					  .content-container {
 | 
				
			||||||
    flex-direction: column;
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    gap: unset;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ 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,
 | 
				
			||||||
| 
						 | 
					@ -51,20 +52,20 @@ const hasChangedTimeDetails = computed(() => {
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const isLoaded = ref(false);
 | 
					const isLoading = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const teamsStore = useTeamsStore();
 | 
					const teamsStore = useTeamsStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const team = computed(() => teamsStore.teams[teamId.value]);
 | 
					const team = computed(() => teamsStore.teams[teamId.value]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
  isLoaded.value = true;
 | 
					  isLoading.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;
 | 
				
			||||||
      isLoaded.value = false;
 | 
					      isLoading.value = false;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -72,7 +73,15 @@ onMounted(() => {
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="team-general-settings">
 | 
					  <div class="team-general-settings">
 | 
				
			||||||
    <h2>Overview</h2>
 | 
					    <h2>Overview</h2>
 | 
				
			||||||
    <div>
 | 
					    <LoaderContainer v-if="isLoading">
 | 
				
			||||||
 | 
					      <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" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ 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();
 | 
				
			||||||
| 
						 | 
					@ -33,14 +32,14 @@ onMounted(() => {
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="team-integrations">
 | 
					  <div class="team-integrations">
 | 
				
			||||||
    <div v-if="isLoading">
 | 
					    <div v-if="isLoading">
 | 
				
			||||||
      <ContentLoader>
 | 
					      <LoaderContainer>
 | 
				
			||||||
        <rect x="0" y="0" rx="3" ry="3" width="250" height="10" />
 | 
					        <rect x="0" y="0" rx="5" ry="5" width="250" height="10" />
 | 
				
			||||||
        <rect x="20" y="20" rx="3" ry="3" width="220" height="10" />
 | 
					        <rect x="20" y="20" rx="5" ry="5" width="220" height="10" />
 | 
				
			||||||
        <rect x="20" y="40" rx="3" ry="3" width="170" height="10" />
 | 
					        <rect x="20" y="40" rx="5" ry="5" width="170" height="10" />
 | 
				
			||||||
        <rect x="0" y="60" rx="3" ry="3" width="250" height="10" />
 | 
					        <rect x="0" y="60" rx="5" ry="5" width="250" height="10" />
 | 
				
			||||||
        <rect x="20" y="80" rx="3" ry="3" width="200" height="10" />
 | 
					        <rect x="20" y="80" rx="5" ry="5" width="200" height="10" />
 | 
				
			||||||
        <rect x="20" y="100" rx="3" ry="3" width="80" height="10" />
 | 
					        <rect x="20" y="100" rx="5" ry="5" width="80" height="10" />
 | 
				
			||||||
      </ContentLoader>
 | 
					      </LoaderContainer>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <template v-else>
 | 
					    <template v-else>
 | 
				
			||||||
      <DiscordIntegrationForm v-model="integrationsStore.discordIntegration" />
 | 
					      <DiscordIntegrationForm v-model="integrationsStore.discordIntegration" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,16 @@ 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>
 | 
				
			||||||
| 
						 | 
					@ -36,6 +46,8 @@ onMounted(() => {
 | 
				
			||||||
          <th>
 | 
					          <th>
 | 
				
			||||||
            Creation time
 | 
					            Creation time
 | 
				
			||||||
          </th>
 | 
					          </th>
 | 
				
			||||||
 | 
					          <th>
 | 
				
			||||||
 | 
					          </th>
 | 
				
			||||||
        </tr>
 | 
					        </tr>
 | 
				
			||||||
      </thead>
 | 
					      </thead>
 | 
				
			||||||
      <tbody>
 | 
					      <tbody>
 | 
				
			||||||
| 
						 | 
					@ -45,22 +57,12 @@ 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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -75,5 +77,6 @@ onMounted(() => {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  gap: 8px;
 | 
					  gap: 8px;
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  justify-content: end;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,9 +71,4 @@ onMounted(() => {
 | 
				
			||||||
table {
 | 
					table {
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
th {
 | 
					 | 
				
			||||||
  text-align: left;
 | 
					 | 
				
			||||||
  font-weight: 800;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ onMounted(() => {
 | 
				
			||||||
          Matches
 | 
					          Matches
 | 
				
			||||||
        </RouterLink>
 | 
					        </RouterLink>
 | 
				
			||||||
        <hr>
 | 
					        <hr>
 | 
				
			||||||
        <button class="destructive-on-hover icon-end" @click="leaveTeam">
 | 
					        <button class="destructive-on-hover icon-end no-border" @click="leaveTeam">
 | 
				
			||||||
          Leave team
 | 
					          Leave team
 | 
				
			||||||
          <i class="bi bi-box-arrow-left" />
 | 
					          <i class="bi bi-box-arrow-left" />
 | 
				
			||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
| 
						 | 
					@ -122,4 +122,9 @@ 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>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue