Move matches tab to team settings
parent
52d8ea5988
commit
13fd7fdfc0
|
@ -21,6 +21,7 @@ export type { EventSchema } from './models/EventSchema';
|
|||
export type { EventWithPlayerSchema } from './models/EventWithPlayerSchema';
|
||||
export type { EventWithPlayerSchemaList } from './models/EventWithPlayerSchemaList';
|
||||
export type { GetEventPlayersResponse } from './models/GetEventPlayersResponse';
|
||||
export type { GetMatchQuery } from './models/GetMatchQuery';
|
||||
export type { MatchSchema } from './models/MatchSchema';
|
||||
export type { PlayerEventRolesSchema } from './models/PlayerEventRolesSchema';
|
||||
export type { PlayerRoleSchema } from './models/PlayerRoleSchema';
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type GetMatchQuery = {
|
||||
limit: (number | null);
|
||||
};
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
export type MatchSchema = {
|
||||
blueScore: number;
|
||||
createdAt: string;
|
||||
duration: string;
|
||||
duration: number;
|
||||
logsTfId: number;
|
||||
logsTfTitle: string;
|
||||
matchTime: string;
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
/* eslint-disable */
|
||||
export type SubmitMatchJson = {
|
||||
matchIds: Array<number>;
|
||||
teamId: number;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import type { MatchSchema } from './MatchSchema';
|
|||
export type TeamMatchSchema = {
|
||||
match: MatchSchema;
|
||||
ourScore: number;
|
||||
teamColor: string;
|
||||
theirScore: number;
|
||||
};
|
||||
|
||||
|
|
|
@ -348,11 +348,13 @@ export class DefaultService {
|
|||
/**
|
||||
* get_matches_for_team <GET>
|
||||
* @param teamId
|
||||
* @param limit
|
||||
* @returns TeamMatchSchemaList OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public getMatchesForTeam(
|
||||
teamId: number,
|
||||
limit: (number | null),
|
||||
): CancelablePromise<TeamMatchSchemaList> {
|
||||
return this.httpRequest.request({
|
||||
method: 'GET',
|
||||
|
@ -360,6 +362,9 @@ export class DefaultService {
|
|||
path: {
|
||||
'team_id': teamId,
|
||||
},
|
||||
query: {
|
||||
'limit': limit,
|
||||
},
|
||||
errors: {
|
||||
422: `Unprocessable Content`,
|
||||
},
|
||||
|
@ -520,7 +525,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public deleteTeam(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
): CancelablePromise<any> {
|
||||
return this.httpRequest.request({
|
||||
method: 'DELETE',
|
||||
|
@ -542,7 +547,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public getTeam(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
): CancelablePromise<ViewTeamResponse> {
|
||||
return this.httpRequest.request({
|
||||
method: 'GET',
|
||||
|
@ -590,8 +595,8 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public editMemberRoles(
|
||||
teamId: string,
|
||||
targetPlayerId: string,
|
||||
teamId: number,
|
||||
targetPlayerId: number,
|
||||
requestBody?: EditMemberRolesJson,
|
||||
): CancelablePromise<void> {
|
||||
return this.httpRequest.request({
|
||||
|
@ -617,7 +622,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public getIntegrations(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
): CancelablePromise<TeamIntegrationSchema> {
|
||||
return this.httpRequest.request({
|
||||
method: 'GET',
|
||||
|
@ -638,7 +643,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public updateIntegrations(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
requestBody?: TeamIntegrationSchema,
|
||||
): CancelablePromise<TeamIntegrationSchema> {
|
||||
return this.httpRequest.request({
|
||||
|
@ -661,7 +666,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public getInvites(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
): CancelablePromise<TeamInviteSchemaList> {
|
||||
return this.httpRequest.request({
|
||||
method: 'GET',
|
||||
|
@ -682,7 +687,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public createInvite(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
): CancelablePromise<TeamInviteSchema> {
|
||||
return this.httpRequest.request({
|
||||
method: 'POST',
|
||||
|
@ -704,7 +709,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public revokeInvite(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
key: string,
|
||||
): CancelablePromise<void> {
|
||||
return this.httpRequest.request({
|
||||
|
@ -729,8 +734,8 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public createOrUpdatePlayer(
|
||||
teamId: string,
|
||||
playerId: string,
|
||||
teamId: number,
|
||||
playerId: number,
|
||||
requestBody?: AddPlayerJson,
|
||||
): CancelablePromise<any> {
|
||||
return this.httpRequest.request({
|
||||
|
@ -757,8 +762,8 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public removePlayerFromTeam(
|
||||
teamId: string,
|
||||
targetPlayerId: string,
|
||||
teamId: number,
|
||||
targetPlayerId: number,
|
||||
): CancelablePromise<any> {
|
||||
return this.httpRequest.request({
|
||||
method: 'DELETE',
|
||||
|
@ -781,7 +786,7 @@ export class DefaultService {
|
|||
* @throws ApiError
|
||||
*/
|
||||
public getTeamMembers(
|
||||
teamId: string,
|
||||
teamId: number,
|
||||
): CancelablePromise<ViewTeamMembersResponseList> {
|
||||
return this.httpRequest.request({
|
||||
method: 'GET',
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { useTeamDetails } from "@/composables/team-details";
|
||||
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 { teamId } = useTeamDetails();
|
||||
|
||||
const urlsText = ref("");
|
||||
|
||||
function submit() {
|
||||
|
@ -15,7 +18,10 @@ function submit() {
|
|||
})
|
||||
.filter((id) => !isNaN(id));
|
||||
|
||||
matchesStore.submitMatches(ids);
|
||||
matchesStore.submitMatches(ids, teamId.value)
|
||||
.then(() => {
|
||||
urlsText.value = "";
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ function disableIntegration() {
|
|||
|
||||
<template>
|
||||
<h2>logs.tf Auto-Tracking</h2>
|
||||
<p>Automatically fetch and track match history from logs.tf. (CURRENTLY NOT IMPLEMENTED)</p>
|
||||
<p>Automatically fetch and track match history from logs.tf.</p>
|
||||
<div v-if="model">
|
||||
<div class="form-group margin">
|
||||
<h3>logs.tf API key (optional)</h3>
|
||||
|
|
|
@ -1,37 +1,91 @@
|
|||
<script setup lang="ts">
|
||||
import type { TeamMatchSchema, TeamSchema } from '@/client';
|
||||
import moment from 'moment';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const matchTime = computed(() => moment(props.teamMatch.match.matchTime)
|
||||
.format("LL LT"));
|
||||
|
||||
const props = defineProps<{
|
||||
team: TeamSchema,
|
||||
teamMatch: TeamMatchSchema,
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="match-card">
|
||||
<div class="match-title">
|
||||
<h3>
|
||||
{{ teamMatch.match.logsTfTitle }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="match-scores">
|
||||
<div class="team-and-score">
|
||||
<span class="team-name">
|
||||
NVBLU
|
||||
<span v-if="teamMatch.teamColor == 'Blue'">
|
||||
BLU
|
||||
</span>
|
||||
<span v-else>
|
||||
RED
|
||||
</span>
|
||||
</span>
|
||||
<span class="score">
|
||||
3
|
||||
{{ teamMatch.ourScore }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="score">-</span>
|
||||
<div class="team-and-score">
|
||||
<span class="score">
|
||||
2
|
||||
{{ teamMatch.theirScore }}
|
||||
</span>
|
||||
<span class="team-name">
|
||||
RED
|
||||
<span v-if="teamMatch.teamColor == 'Blue'">
|
||||
RED
|
||||
</span>
|
||||
<span v-else>
|
||||
BLU
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-row">
|
||||
<div class="subtext">
|
||||
{{ matchTime }}
|
||||
</div>
|
||||
<div>
|
||||
<a :href="'https://logs.tf/' + teamMatch.match.logsTfId" target="_blank" class="button">
|
||||
#{{ teamMatch.match.logsTfId }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.match-card {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--text);
|
||||
border-radius: 8px;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.match-title {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bottom-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bottom-row > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.match-scores {
|
||||
|
|
|
@ -11,8 +11,8 @@ import TeamSettingsView from "@/views/TeamSettingsView.vue";
|
|||
import TeamSettingsGeneralView from "@/views/TeamSettings/GeneralView.vue";
|
||||
import TeamSettingsIntegrationsView from "@/views/TeamSettings/IntegrationsView.vue";
|
||||
import TeamSettingsInvitesView from "@/views/TeamSettings/InvitesView.vue";
|
||||
import TeamSettingsMatchesView from "@/views/TeamSettings/MatchesView.vue";
|
||||
import UserSettingsView from "@/views/UserSettingsView.vue";
|
||||
import MatchesView from "@/views/MatchesView.vue";
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
|
@ -72,6 +72,11 @@ const router = createRouter({
|
|||
name: "team-settings/invites",
|
||||
component: TeamSettingsInvitesView,
|
||||
},
|
||||
{
|
||||
path: "matches",
|
||||
name: "team-settings/matches",
|
||||
component: TeamSettingsMatchesView,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -79,11 +84,6 @@ const router = createRouter({
|
|||
name: "user-settings",
|
||||
component: UserSettingsView,
|
||||
},
|
||||
{
|
||||
path: "/matches",
|
||||
name: "matches",
|
||||
component: MatchesView,
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@ export const useMatchesStore = defineStore("matches", () => {
|
|||
|
||||
const matches = ref<{ [id: number]: MatchSchema }>({ });
|
||||
|
||||
const teamMatches = ref<{ [id: number]: TeamMatchSchema }>({ });
|
||||
const teamMatches = ref<{ [teamId: number]: TeamMatchSchema[] }>({ });
|
||||
|
||||
const recentMatches = ref<TeamMatchSchema[]>([]);
|
||||
|
||||
function fetchMatches() {
|
||||
return clientStore.call(
|
||||
|
@ -18,21 +20,52 @@ export const useMatchesStore = defineStore("matches", () => {
|
|||
(response) => {
|
||||
response.forEach((match) => {
|
||||
matches.value[match.match.logsTfId] = match.match;
|
||||
teamMatches.value[match.match.logsTfId] = match;
|
||||
//teamMatches.value[match.match.logsTfId] = match;
|
||||
});
|
||||
return response;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function submitMatches(logsTfIds: number[]) {
|
||||
return client.default.submitMatch({ matchIds: logsTfIds });
|
||||
function fetchMatchesForTeam(teamId: number) {
|
||||
return clientStore.call(
|
||||
fetchMatchesForTeam.name,
|
||||
() => client.default.getMatchesForTeam(teamId, 1024),
|
||||
(response) => {
|
||||
teamMatches.value[teamId] = [];
|
||||
response.forEach((match) => {
|
||||
matches.value[match.match.logsTfId] = match.match;
|
||||
teamMatches.value[teamId].push(match);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
function fetchRecentMatchesForTeam(teamId: number, limit: number) {
|
||||
return clientStore.call(
|
||||
fetchMatchesForTeam.name,
|
||||
() => client.default.getMatchesForTeam(teamId, limit),
|
||||
(response) => {
|
||||
recentMatches.value = [];
|
||||
response.forEach((match) => {
|
||||
matches.value[match.match.logsTfId] = match.match;
|
||||
recentMatches.value.push(match);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
function submitMatches(logsTfIds: number[], teamId: number) {
|
||||
return client.default.submitMatch({ matchIds: logsTfIds, teamId });
|
||||
}
|
||||
|
||||
return {
|
||||
matches,
|
||||
teamMatches,
|
||||
recentMatches,
|
||||
fetchMatches,
|
||||
fetchMatchesForTeam,
|
||||
fetchRecentMatchesForTeam,
|
||||
submitMatches,
|
||||
}
|
||||
});
|
||||
|
|
|
@ -9,10 +9,12 @@ import moment from "moment";
|
|||
import EventList from "@/components/EventList.vue";
|
||||
import { useTeamsEventsStore } from "@/stores/teams/events";
|
||||
import MatchCard from "@/components/MatchCard.vue";
|
||||
import { useMatchesStore } from "@/stores/matches";
|
||||
|
||||
const route = useRoute();
|
||||
const teamsStore = useTeamsStore();
|
||||
const invitesStore = useInvitesStore();
|
||||
const matchesStore = useMatchesStore();
|
||||
const { team, teamId } = useTeamDetails();
|
||||
|
||||
const creationDate = computed(() => {
|
||||
|
@ -25,6 +27,7 @@ const key = computed(() => route.query.key);
|
|||
|
||||
const teamsEventsStore = useTeamsEventsStore();
|
||||
const events = computed(() => teamsEventsStore.teamEvents[teamId.value]);
|
||||
const matches = computed(() => matchesStore.recentMatches);
|
||||
|
||||
onMounted(() => {
|
||||
let doFetchTeam = () => {
|
||||
|
@ -32,6 +35,7 @@ onMounted(() => {
|
|||
.then(() => {
|
||||
teamsStore.fetchTeamMembers(teamId.value);
|
||||
teamsEventsStore.fetchTeamEvents(teamId.value);
|
||||
matchesStore.fetchRecentMatchesForTeam(teamId.value, 5);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -76,14 +80,21 @@ onMounted(() => {
|
|||
<EventList :events="events" :team-context="team" />
|
||||
<h2 id="recent-matches-header">
|
||||
Recent Matches
|
||||
<!--RouterLink class="button" to="/">
|
||||
<RouterLink class="button" :to="{ name: 'team-settings/matches' }">
|
||||
<button class="icon" v-tooltip="'View all'">
|
||||
<i class="bi bi-arrow-right-circle-fill"></i>
|
||||
</button>
|
||||
</RouterLink-->
|
||||
</RouterLink>
|
||||
</h2>
|
||||
<em class="subtext" v-if="true">No recent matches.</em>
|
||||
<MatchCard v-else />
|
||||
<em class="subtext" v-if="!matches">
|
||||
No recent matches.
|
||||
</em>
|
||||
<MatchCard
|
||||
v-else
|
||||
v-for="match in matches"
|
||||
:team-match="match"
|
||||
:team="team"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
<script setup lang="ts">
|
||||
import AddMatchDialog from "@/components/AddMatchDialog.vue";
|
||||
import { useTeamDetails } from "@/composables/team-details";
|
||||
import { useMatchesStore } from "@/stores/matches";
|
||||
import { onMounted } from "vue";
|
||||
import { useTeamsStore } from "@/stores/teams";
|
||||
import moment from "moment";
|
||||
import { computed, onMounted } from "vue";
|
||||
|
||||
const matchesStore = useMatchesStore();
|
||||
const teamsStore = useTeamsStore();
|
||||
|
||||
const { team, teamId } = useTeamDetails();
|
||||
|
||||
const matches = computed(() => matchesStore.teamMatches[teamId.value]);
|
||||
|
||||
onMounted(() => {
|
||||
matchesStore.fetchMatches();
|
||||
teamsStore.fetchTeam(teamId.value)
|
||||
.then(() => matchesStore.fetchMatchesForTeam(teamId.value));
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -15,7 +24,7 @@ onMounted(() => {
|
|||
<div class="header">
|
||||
<h1>
|
||||
<i class="bi bi-trophy-fill margin"></i>
|
||||
Matches you've played
|
||||
Matches
|
||||
</h1>
|
||||
<div class="button-group">
|
||||
<AddMatchDialog />
|
||||
|
@ -26,18 +35,20 @@ onMounted(() => {
|
|||
<tr>
|
||||
<th>RED</th>
|
||||
<th>BLU</th>
|
||||
<th>Team</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>
|
||||
<tr v-for="teamMatch in matches">
|
||||
<td>{{ teamMatch.match.redScore }}</td>
|
||||
<td>{{ teamMatch.match.blueScore }}</td>
|
||||
<td>{{ teamMatch.teamColor == 'Blue' ? 'BLU' : 'RED' }}</td>
|
||||
<td>{{ moment(teamMatch.match.matchTime).format("LL LT") }}</td>
|
||||
<td>
|
||||
<a :href="`https://logs.tf/${match.logsTfId}`" target="_blank">
|
||||
#{{ match.logsTfId }}
|
||||
<a :href="`https://logs.tf/${teamMatch.match.logsTfId}`" target="_blank">
|
||||
#{{ teamMatch.match.logsTfId }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
|
@ -42,6 +42,9 @@ onMounted(() => {
|
|||
<RouterLink class="tab" :to="{ name: 'team-settings/invites' }">
|
||||
Invites
|
||||
</RouterLink>
|
||||
<RouterLink class="tab" :to="{ name: 'team-settings/matches' }">
|
||||
Matches
|
||||
</RouterLink>
|
||||
<hr>
|
||||
<button class="destructive-on-hover icon-end" @click="leaveTeam">
|
||||
Leave team
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from typing import Optional
|
||||
from flask import Blueprint, abort
|
||||
from pydantic.v1 import validator
|
||||
#from pydantic.functional_validators import field_validator
|
||||
|
@ -41,6 +42,7 @@ def get_match(player: Player, match_id: int, **_):
|
|||
|
||||
class SubmitMatchJson(BaseModel):
|
||||
match_ids: list[int]
|
||||
team_id: int
|
||||
|
||||
@validator("match_ids")
|
||||
@classmethod
|
||||
|
@ -59,15 +61,13 @@ class SubmitMatchJson(BaseModel):
|
|||
)
|
||||
@requires_authentication
|
||||
def submit_match(json: SubmitMatchJson, **_):
|
||||
import sys
|
||||
print(json, file=sys.stderr)
|
||||
if json.match_ids is None:
|
||||
print("json.match_ids is None", file=sys.stderr)
|
||||
|
||||
for id in json.match_ids:
|
||||
load_specific_match.delay(id, None)
|
||||
load_specific_match.delay(id, json.team_id)
|
||||
return { }, 204
|
||||
|
||||
class GetMatchQuery(BaseModel):
|
||||
limit: Optional[int]
|
||||
|
||||
@api_match.get("/team/<int:team_id>")
|
||||
@spec.validate(
|
||||
resp=Response(
|
||||
|
@ -77,14 +77,19 @@ def submit_match(json: SubmitMatchJson, **_):
|
|||
)
|
||||
@requires_authentication
|
||||
@requires_team_membership()
|
||||
def get_matches_for_team(team_id: Team, **_):
|
||||
matches = (
|
||||
def get_matches_for_team(team_id: Team, query: GetMatchQuery, **_):
|
||||
q = (
|
||||
db.session.query(TeamMatch)
|
||||
.where(TeamMatch.team_id == team_id)
|
||||
.options(joinedload(TeamMatch.match))
|
||||
.all()
|
||||
.order_by(TeamMatch.match_id.desc())
|
||||
)
|
||||
|
||||
if query and query.limit:
|
||||
q = q.limit(query.limit)
|
||||
|
||||
matches = q.all()
|
||||
|
||||
return [TeamMatchSchema.from_model(match).dict(by_alias=True) for match in matches], 200
|
||||
|
||||
@api_match.get("/player")
|
||||
|
|
|
@ -19,6 +19,7 @@ class TeamMatchSchema(spec.BaseModel):
|
|||
match: "MatchSchema"
|
||||
our_score: int
|
||||
their_score: int
|
||||
team_color: str
|
||||
|
||||
@classmethod
|
||||
def from_model(cls, model: "TeamMatch"):
|
||||
|
@ -29,6 +30,7 @@ class TeamMatchSchema(spec.BaseModel):
|
|||
match=MatchSchema.from_model(model.match),
|
||||
our_score=our_score,
|
||||
their_score=their_score,
|
||||
team_color=model.team_color,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ services:
|
|||
context: ./availabili.tf
|
||||
environment:
|
||||
VITE_API_URL: http://localhost:8000 # API endpoint
|
||||
ports:
|
||||
- 5173:5173
|
||||
volumes:
|
||||
- ./availabili.tf:/app
|
||||
networks:
|
||||
|
@ -62,7 +64,7 @@ services:
|
|||
ports:
|
||||
- "8000:80"
|
||||
volumes:
|
||||
- ./nginx:/etc/nginx/conf.d
|
||||
- ./nginx/development.conf:/etc/nginx/nginx.conf
|
||||
depends_on:
|
||||
- backend
|
||||
- frontend
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
server {
|
||||
listen 80;
|
||||
|
||||
# Proxy for the Vite frontend
|
||||
location / {
|
||||
proxy_pass http://frontend:5173;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# Proxy for the Flask backend API
|
||||
location /api/ {
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location /apidoc/ {
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
# Proxy for the Vite frontend
|
||||
location / {
|
||||
proxy_pass http://frontend:5173;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# Proxy for the Flask backend API
|
||||
location /api/ {
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location /apidoc/ {
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue