feat(frontend): Implement matches
							parent
							
								
									45ac071a7f
								
							
						
					
					
						commit
						caaee983f2
					
				| 
						 | 
					@ -21,6 +21,7 @@ export type { EventSchema } from './models/EventSchema';
 | 
				
			||||||
export type { EventWithPlayerSchema } from './models/EventWithPlayerSchema';
 | 
					export type { EventWithPlayerSchema } from './models/EventWithPlayerSchema';
 | 
				
			||||||
export type { EventWithPlayerSchemaList } from './models/EventWithPlayerSchemaList';
 | 
					export type { EventWithPlayerSchemaList } from './models/EventWithPlayerSchemaList';
 | 
				
			||||||
export type { GetEventPlayersResponse } from './models/GetEventPlayersResponse';
 | 
					export type { GetEventPlayersResponse } from './models/GetEventPlayersResponse';
 | 
				
			||||||
 | 
					export type { MatchSchema } from './models/MatchSchema';
 | 
				
			||||||
export type { PlayerEventRolesSchema } from './models/PlayerEventRolesSchema';
 | 
					export type { PlayerEventRolesSchema } from './models/PlayerEventRolesSchema';
 | 
				
			||||||
export type { PlayerRoleSchema } from './models/PlayerRoleSchema';
 | 
					export type { PlayerRoleSchema } from './models/PlayerRoleSchema';
 | 
				
			||||||
export type { PlayerSchema } from './models/PlayerSchema';
 | 
					export type { PlayerSchema } from './models/PlayerSchema';
 | 
				
			||||||
| 
						 | 
					@ -28,11 +29,14 @@ export type { PlayerTeamAvailabilityRoleSchema } from './models/PlayerTeamAvaila
 | 
				
			||||||
export type { PutScheduleForm } from './models/PutScheduleForm';
 | 
					export type { PutScheduleForm } from './models/PutScheduleForm';
 | 
				
			||||||
export type { RoleSchema } from './models/RoleSchema';
 | 
					export type { RoleSchema } from './models/RoleSchema';
 | 
				
			||||||
export type { SetUsernameJson } from './models/SetUsernameJson';
 | 
					export type { SetUsernameJson } from './models/SetUsernameJson';
 | 
				
			||||||
 | 
					export type { SubmitMatchJson } from './models/SubmitMatchJson';
 | 
				
			||||||
export type { TeamDiscordIntegrationSchema } from './models/TeamDiscordIntegrationSchema';
 | 
					export type { TeamDiscordIntegrationSchema } from './models/TeamDiscordIntegrationSchema';
 | 
				
			||||||
export type { TeamIntegrationSchema } from './models/TeamIntegrationSchema';
 | 
					export type { TeamIntegrationSchema } from './models/TeamIntegrationSchema';
 | 
				
			||||||
export type { TeamInviteSchema } from './models/TeamInviteSchema';
 | 
					export type { TeamInviteSchema } from './models/TeamInviteSchema';
 | 
				
			||||||
export type { TeamInviteSchemaList } from './models/TeamInviteSchemaList';
 | 
					export type { TeamInviteSchemaList } from './models/TeamInviteSchemaList';
 | 
				
			||||||
export type { TeamLogsTfIntegrationSchema } from './models/TeamLogsTfIntegrationSchema';
 | 
					export type { TeamLogsTfIntegrationSchema } from './models/TeamLogsTfIntegrationSchema';
 | 
				
			||||||
 | 
					export type { TeamMatchSchema } from './models/TeamMatchSchema';
 | 
				
			||||||
 | 
					export type { TeamMatchSchemaList } from './models/TeamMatchSchemaList';
 | 
				
			||||||
export { TeamRole } from './models/TeamRole';
 | 
					export { TeamRole } from './models/TeamRole';
 | 
				
			||||||
export type { TeamSchema } from './models/TeamSchema';
 | 
					export type { TeamSchema } from './models/TeamSchema';
 | 
				
			||||||
export type { TeamWithRoleSchema } from './models/TeamWithRoleSchema';
 | 
					export type { TeamWithRoleSchema } from './models/TeamWithRoleSchema';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					/* generated using openapi-typescript-codegen -- do not edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					export type MatchSchema = {
 | 
				
			||||||
 | 
					    blueScore: number;
 | 
				
			||||||
 | 
					    createdAt: string;
 | 
				
			||||||
 | 
					    duration: string;
 | 
				
			||||||
 | 
					    logsTfId: number;
 | 
				
			||||||
 | 
					    logsTfTitle: string;
 | 
				
			||||||
 | 
					    matchTime: string;
 | 
				
			||||||
 | 
					    redScore: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					/* generated using openapi-typescript-codegen -- do not edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					export type SubmitMatchJson = {
 | 
				
			||||||
 | 
					    matchIds: Array<number>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					/* generated using openapi-typescript-codegen -- do not edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					import type { MatchSchema } from './MatchSchema';
 | 
				
			||||||
 | 
					export type TeamMatchSchema = {
 | 
				
			||||||
 | 
					    match: MatchSchema;
 | 
				
			||||||
 | 
					    ourScore: number;
 | 
				
			||||||
 | 
					    theirScore: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					/* generated using openapi-typescript-codegen -- do not edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					import type { TeamMatchSchema } from './TeamMatchSchema';
 | 
				
			||||||
 | 
					export type TeamMatchSchemaList = Array<TeamMatchSchema>;
 | 
				
			||||||
| 
						 | 
					@ -12,12 +12,15 @@ import type { EventSchema } from '../models/EventSchema';
 | 
				
			||||||
import type { EventWithPlayerSchema } from '../models/EventWithPlayerSchema';
 | 
					import type { EventWithPlayerSchema } from '../models/EventWithPlayerSchema';
 | 
				
			||||||
import type { EventWithPlayerSchemaList } from '../models/EventWithPlayerSchemaList';
 | 
					import type { EventWithPlayerSchemaList } from '../models/EventWithPlayerSchemaList';
 | 
				
			||||||
import type { GetEventPlayersResponse } from '../models/GetEventPlayersResponse';
 | 
					import type { GetEventPlayersResponse } from '../models/GetEventPlayersResponse';
 | 
				
			||||||
 | 
					import type { MatchSchema } from '../models/MatchSchema';
 | 
				
			||||||
import type { PlayerSchema } from '../models/PlayerSchema';
 | 
					import type { PlayerSchema } from '../models/PlayerSchema';
 | 
				
			||||||
import type { PutScheduleForm } from '../models/PutScheduleForm';
 | 
					import type { PutScheduleForm } from '../models/PutScheduleForm';
 | 
				
			||||||
import type { SetUsernameJson } from '../models/SetUsernameJson';
 | 
					import type { SetUsernameJson } from '../models/SetUsernameJson';
 | 
				
			||||||
 | 
					import type { SubmitMatchJson } from '../models/SubmitMatchJson';
 | 
				
			||||||
import type { TeamIntegrationSchema } from '../models/TeamIntegrationSchema';
 | 
					import type { TeamIntegrationSchema } from '../models/TeamIntegrationSchema';
 | 
				
			||||||
import type { TeamInviteSchema } from '../models/TeamInviteSchema';
 | 
					import type { TeamInviteSchema } from '../models/TeamInviteSchema';
 | 
				
			||||||
import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList';
 | 
					import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList';
 | 
				
			||||||
 | 
					import type { TeamMatchSchemaList } from '../models/TeamMatchSchemaList';
 | 
				
			||||||
import type { TeamSchema } from '../models/TeamSchema';
 | 
					import type { TeamSchema } from '../models/TeamSchema';
 | 
				
			||||||
import type { UpdateEventJson } from '../models/UpdateEventJson';
 | 
					import type { UpdateEventJson } from '../models/UpdateEventJson';
 | 
				
			||||||
import type { ViewAvailablePlayersResponse } from '../models/ViewAvailablePlayersResponse';
 | 
					import type { ViewAvailablePlayersResponse } from '../models/ViewAvailablePlayersResponse';
 | 
				
			||||||
| 
						 | 
					@ -289,6 +292,79 @@ export class DefaultService {
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * submit_match <PUT>
 | 
				
			||||||
 | 
					     * @param requestBody
 | 
				
			||||||
 | 
					     * @returns void
 | 
				
			||||||
 | 
					     * @throws ApiError
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public submitMatch(
 | 
				
			||||||
 | 
					        requestBody?: SubmitMatchJson,
 | 
				
			||||||
 | 
					    ): CancelablePromise<void> {
 | 
				
			||||||
 | 
					        return this.httpRequest.request({
 | 
				
			||||||
 | 
					            method: 'PUT',
 | 
				
			||||||
 | 
					            url: '/api/match/',
 | 
				
			||||||
 | 
					            body: requestBody,
 | 
				
			||||||
 | 
					            mediaType: 'application/json',
 | 
				
			||||||
 | 
					            errors: {
 | 
				
			||||||
 | 
					                422: `Unprocessable Content`,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * get_match <GET>
 | 
				
			||||||
 | 
					     * @param matchId
 | 
				
			||||||
 | 
					     * @returns MatchSchema OK
 | 
				
			||||||
 | 
					     * @throws ApiError
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public getApiMatchIdMatchId(
 | 
				
			||||||
 | 
					        matchId: number,
 | 
				
			||||||
 | 
					    ): CancelablePromise<MatchSchema> {
 | 
				
			||||||
 | 
					        return this.httpRequest.request({
 | 
				
			||||||
 | 
					            method: 'GET',
 | 
				
			||||||
 | 
					            url: '/api/match/id/{match_id}',
 | 
				
			||||||
 | 
					            path: {
 | 
				
			||||||
 | 
					                'match_id': matchId,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            errors: {
 | 
				
			||||||
 | 
					                422: `Unprocessable Content`,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * get_matches_for_player_teams <GET>
 | 
				
			||||||
 | 
					     * @returns TeamMatchSchemaList OK
 | 
				
			||||||
 | 
					     * @throws ApiError
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public getMatchesForPlayerTeams(): CancelablePromise<TeamMatchSchemaList> {
 | 
				
			||||||
 | 
					        return this.httpRequest.request({
 | 
				
			||||||
 | 
					            method: 'GET',
 | 
				
			||||||
 | 
					            url: '/api/match/player',
 | 
				
			||||||
 | 
					            errors: {
 | 
				
			||||||
 | 
					                422: `Unprocessable Content`,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * get_matches_for_team <GET>
 | 
				
			||||||
 | 
					     * @param teamId
 | 
				
			||||||
 | 
					     * @returns TeamMatchSchemaList OK
 | 
				
			||||||
 | 
					     * @throws ApiError
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public getMatchesForTeam(
 | 
				
			||||||
 | 
					        teamId: number,
 | 
				
			||||||
 | 
					    ): CancelablePromise<TeamMatchSchemaList> {
 | 
				
			||||||
 | 
					        return this.httpRequest.request({
 | 
				
			||||||
 | 
					            method: 'GET',
 | 
				
			||||||
 | 
					            url: '/api/match/team/{team_id}',
 | 
				
			||||||
 | 
					            path: {
 | 
				
			||||||
 | 
					                'team_id': teamId,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            errors: {
 | 
				
			||||||
 | 
					                422: `Unprocessable Content`,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * get <GET>
 | 
					     * get <GET>
 | 
				
			||||||
     * @param windowStart
 | 
					     * @param windowStart
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useMatchesStore } from "@/stores/matches";
 | 
				
			||||||
 | 
					import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DialogTrigger } from "radix-vue";
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const matchesStore = useMatchesStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const urlsText = ref("");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function submit() {
 | 
				
			||||||
 | 
					  const ids = urlsText.value.split("\n")
 | 
				
			||||||
 | 
					    .map((url) => {
 | 
				
			||||||
 | 
					      const matchId = url.match(/logs\.tf\/(\d+)/);
 | 
				
			||||||
 | 
					      return matchId ? Number(matchId[1]) : NaN;
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .filter((id) => !isNaN(id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  matchesStore.submitMatches(ids);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <DialogRoot>
 | 
				
			||||||
 | 
					    <DialogTrigger>
 | 
				
			||||||
 | 
					      <i class="bi bi-file-earmark-plus-fill margin" />
 | 
				
			||||||
 | 
					      Submit logs.tf matches
 | 
				
			||||||
 | 
					    </DialogTrigger>
 | 
				
			||||||
 | 
					    <DialogPortal>
 | 
				
			||||||
 | 
					      <DialogOverlay class="dialog-overlay" />
 | 
				
			||||||
 | 
					      <DialogContent>
 | 
				
			||||||
 | 
					        <DialogTitle>Submit logs.tf matches</DialogTitle>
 | 
				
			||||||
 | 
					        <DialogDescription>
 | 
				
			||||||
 | 
					          <p>
 | 
				
			||||||
 | 
					            Enter up to 10 logs.tf URLs (or match IDs) to submit them. This
 | 
				
			||||||
 | 
					            allows you to track your match stats and view them later.
 | 
				
			||||||
 | 
					          </p>
 | 
				
			||||||
 | 
					        </DialogDescription>
 | 
				
			||||||
 | 
					        <div class="form-group margin">
 | 
				
			||||||
 | 
					          <h3>logs.tf URLs</h3>
 | 
				
			||||||
 | 
					          <textarea
 | 
				
			||||||
 | 
					            v-model="urlsText"
 | 
				
			||||||
 | 
					            placeholder="Paste logs.tf URLs here (limit: 10)"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="form-group">
 | 
				
			||||||
 | 
					          <div class="action-buttons">
 | 
				
			||||||
 | 
					            <DialogClose class="accent" aria-label="Close" @click="submit">
 | 
				
			||||||
 | 
					              <i class="bi bi-check" />
 | 
				
			||||||
 | 
					              Submit
 | 
				
			||||||
 | 
					            </DialogClose>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </DialogContent>
 | 
				
			||||||
 | 
					    </DialogPortal>
 | 
				
			||||||
 | 
					  </DialogRoot>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					[role="dialog"] {
 | 
				
			||||||
 | 
					  padding: 2rem;
 | 
				
			||||||
 | 
					  border-radius: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ import TeamSettingsGeneralView from "@/views/TeamSettings/GeneralView.vue";
 | 
				
			||||||
import TeamSettingsIntegrationsView from "@/views/TeamSettings/IntegrationsView.vue";
 | 
					import TeamSettingsIntegrationsView from "@/views/TeamSettings/IntegrationsView.vue";
 | 
				
			||||||
import TeamSettingsInvitesView from "@/views/TeamSettings/InvitesView.vue";
 | 
					import TeamSettingsInvitesView from "@/views/TeamSettings/InvitesView.vue";
 | 
				
			||||||
import UserSettingsView from "@/views/UserSettingsView.vue";
 | 
					import UserSettingsView from "@/views/UserSettingsView.vue";
 | 
				
			||||||
 | 
					import MatchesView from "@/views/MatchesView.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = createRouter({
 | 
					const router = createRouter({
 | 
				
			||||||
  history: createWebHistory(import.meta.env.BASE_URL),
 | 
					  history: createWebHistory(import.meta.env.BASE_URL),
 | 
				
			||||||
| 
						 | 
					@ -78,6 +79,11 @@ const router = createRouter({
 | 
				
			||||||
      name: "user-settings",
 | 
					      name: "user-settings",
 | 
				
			||||||
      component: UserSettingsView,
 | 
					      component: UserSettingsView,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/matches",
 | 
				
			||||||
 | 
					      name: "matches",
 | 
				
			||||||
 | 
					      component: MatchesView,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					import type { MatchSchema, TeamMatchSchema } from "@/client";
 | 
				
			||||||
 | 
					import { defineStore } from "pinia";
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					import { useClientStore } from "./client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useMatchesStore = defineStore("matches", () => {
 | 
				
			||||||
 | 
					  const clientStore = useClientStore();
 | 
				
			||||||
 | 
					  const client = clientStore.client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const matches = ref<{ [id: number]: MatchSchema }>({ });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const teamMatches = ref<{ [id: number]: TeamMatchSchema }>({ });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function fetchMatches() {
 | 
				
			||||||
 | 
					    return clientStore.call(
 | 
				
			||||||
 | 
					      fetchMatches.name,
 | 
				
			||||||
 | 
					      () => client.default.getMatchesForPlayerTeams(),
 | 
				
			||||||
 | 
					      (response) => {
 | 
				
			||||||
 | 
					        response.forEach((match) => {
 | 
				
			||||||
 | 
					          matches.value[match.match.logsTfId] = match.match;
 | 
				
			||||||
 | 
					          teamMatches.value[match.match.logsTfId] = match;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        return response;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function submitMatches(logsTfIds: number[]) {
 | 
				
			||||||
 | 
					    return client.default.submitMatch({ matchIds: logsTfIds });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    matches,
 | 
				
			||||||
 | 
					    teamMatches,
 | 
				
			||||||
 | 
					    fetchMatches,
 | 
				
			||||||
 | 
					    submitMatches,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import AddMatchDialog from "@/components/AddMatchDialog.vue";
 | 
				
			||||||
 | 
					import { useMatchesStore } from "@/stores/matches";
 | 
				
			||||||
 | 
					import { onMounted } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const matchesStore = useMatchesStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  matchesStore.fetchMatches();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <main>
 | 
				
			||||||
 | 
					    <div class="header">
 | 
				
			||||||
 | 
					      <h1>
 | 
				
			||||||
 | 
					        <i class="bi bi-trophy-fill margin"></i>
 | 
				
			||||||
 | 
					        Matches you've played
 | 
				
			||||||
 | 
					      </h1>
 | 
				
			||||||
 | 
					      <div class="button-group">
 | 
				
			||||||
 | 
					        <AddMatchDialog />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <table>
 | 
				
			||||||
 | 
					      <thead>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <th>RED</th>
 | 
				
			||||||
 | 
					          <th>BLU</th>
 | 
				
			||||||
 | 
					          <th>Match Date</th>
 | 
				
			||||||
 | 
					          <th>logs.tf URL</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					      </thead>
 | 
				
			||||||
 | 
					      <tbody>
 | 
				
			||||||
 | 
					        <tr v-for="match in matchesStore.matches" :key="match.logsTfId">
 | 
				
			||||||
 | 
					          <td>{{ match.redScore }}</td>
 | 
				
			||||||
 | 
					          <td>{{ match.blueScore }}</td>
 | 
				
			||||||
 | 
					          <td>{{ match.matchTime }}</td>
 | 
				
			||||||
 | 
					          <td>
 | 
				
			||||||
 | 
					            <a :href="`https://logs.tf/${match.logsTfId}`" target="_blank">
 | 
				
			||||||
 | 
					              #{{ match.logsTfId }}
 | 
				
			||||||
 | 
					            </a>
 | 
				
			||||||
 | 
					          </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					      </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					  </main>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					.header {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: space-between;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.button-group {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: flex-end;
 | 
				
			||||||
 | 
					  margin-bottom: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table {
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					th {
 | 
				
			||||||
 | 
					  text-align: left;
 | 
				
			||||||
 | 
					  font-weight: 800;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
		Loading…
	
		Reference in New Issue