Add timezone-aware schedule window
							parent
							
								
									fc6092d282
								
							
						
					
					
						commit
						1bf4cc3125
					
				| 
						 | 
				
			
			@ -5,6 +5,8 @@
 | 
			
		|||
export type TeamSchema = {
 | 
			
		||||
    discordWebhookUrl?: string;
 | 
			
		||||
    id: number;
 | 
			
		||||
    minuteOffset: number;
 | 
			
		||||
    teamName: string;
 | 
			
		||||
    tzTimezone: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
import { beforeEach, describe, expect, it } from "vitest";
 | 
			
		||||
import { useScheduleStore } from "./schedule";
 | 
			
		||||
import { createPinia, setActivePinia } from "pinia";
 | 
			
		||||
 | 
			
		||||
describe("Schedule store", () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    setActivePinia(createPinia());
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it("should return the proper window start for any timezone", () => {
 | 
			
		||||
    const scheduleStore = useScheduleStore();
 | 
			
		||||
 | 
			
		||||
    let test1 = scheduleStore.getWindowStart({
 | 
			
		||||
      teamName: "",
 | 
			
		||||
      id: 0,
 | 
			
		||||
      tzTimezone: "Asia/Kolkata",
 | 
			
		||||
      minuteOffset: 10,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    expect(test1.get("minutes")).toEqual(40);
 | 
			
		||||
 | 
			
		||||
    let test2 = scheduleStore.getWindowStart({
 | 
			
		||||
      teamName: "",
 | 
			
		||||
      id: 0,
 | 
			
		||||
      tzTimezone: "America/New_York",
 | 
			
		||||
      minuteOffset: 30,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    expect(test2.get("minutes")).toEqual(30);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -3,6 +3,9 @@ import { defineStore } from "pinia";
 | 
			
		|||
import { reactive, ref, watch } from "vue";
 | 
			
		||||
import { useRoute, useRouter } from "vue-router";
 | 
			
		||||
import { useClientStore } from "./client";
 | 
			
		||||
import type { TeamSchema } from "@/client";
 | 
			
		||||
import moment from "moment";
 | 
			
		||||
import "moment-timezone";
 | 
			
		||||
 | 
			
		||||
export const useScheduleStore = defineStore("schedule", () => {
 | 
			
		||||
  const client = useClientStore().client;
 | 
			
		||||
| 
						 | 
				
			
			@ -18,23 +21,43 @@ export const useScheduleStore = defineStore("schedule", () => {
 | 
			
		|||
  const route = useRoute();
 | 
			
		||||
  const router = useRouter();
 | 
			
		||||
 | 
			
		||||
  const teamId = computed({
 | 
			
		||||
    get: () => Number(route.query.teamId),
 | 
			
		||||
    set: (value) => router.push({ query: { teamId: value } }),
 | 
			
		||||
  });
 | 
			
		||||
  //const teamId = computed({
 | 
			
		||||
  //  get: () => Number(route?.query?.teamId),
 | 
			
		||||
  //  set: (value) => router.push({ query: { teamId: value } }),
 | 
			
		||||
  //});
 | 
			
		||||
  const team = ref();
 | 
			
		||||
 | 
			
		||||
  function getWindowStart(team: TeamSchema) {
 | 
			
		||||
    // convert local 00:00 to league timezone
 | 
			
		||||
    let localMidnight = moment().startOf("isoWeek");
 | 
			
		||||
    let leagueTime = localMidnight.clone().tz(team.tz_timezone);
 | 
			
		||||
 | 
			
		||||
    let nextMinuteOffsetTime = leagueTime.clone();
 | 
			
		||||
 | 
			
		||||
    if (nextMinuteOffsetTime.minute() > team.minute_offset) {
 | 
			
		||||
      nextMinuteOffsetTime.add(1, "hour");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nextMinuteOffsetTime.minute(team.minute_offset);
 | 
			
		||||
 | 
			
		||||
    const deltaMinutes = nextMinuteOffsetTime.diff(leagueTime, "minutes");
 | 
			
		||||
 | 
			
		||||
    return localMidnight.clone().add(deltaMinutes, "minutes");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  watch(dateStart, () => {
 | 
			
		||||
    fetchSchedule();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  watch(teamId, () => {
 | 
			
		||||
    fetchSchedule();
 | 
			
		||||
  watch(team, () => {
 | 
			
		||||
    dateStart.value = getWindowStart(team.value).toDate();
 | 
			
		||||
    console.log(dateStart.value);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  async function fetchSchedule() {
 | 
			
		||||
    return client.default.getApiSchedule(
 | 
			
		||||
      Math.floor(dateStart.value.getTime() / 1000).toString(),
 | 
			
		||||
      teamId.value,
 | 
			
		||||
      team.value.id,
 | 
			
		||||
    )
 | 
			
		||||
      .then((response) => {
 | 
			
		||||
        response.availability.forEach((value, i) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +83,7 @@ export const useScheduleStore = defineStore("schedule", () => {
 | 
			
		|||
  async function saveSchedule() {
 | 
			
		||||
    return client.default.putApiSchedule({
 | 
			
		||||
      windowStart: Math.floor(dateStart.value.getTime() / 1000).toString(),
 | 
			
		||||
      teamId: teamId.value,
 | 
			
		||||
      teamId: team.value.id,
 | 
			
		||||
      availability,
 | 
			
		||||
    });
 | 
			
		||||
    //return fetch(import.meta.env.VITE_API_BASE_URL + "/schedule", {
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +106,7 @@ export const useScheduleStore = defineStore("schedule", () => {
 | 
			
		|||
    availability,
 | 
			
		||||
    fetchSchedule,
 | 
			
		||||
    saveSchedule,
 | 
			
		||||
    teamId,
 | 
			
		||||
    team,
 | 
			
		||||
    getWindowStart,
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ const selectedTeam = ref();
 | 
			
		|||
 | 
			
		||||
watch(selectedTeam, (newTeam) => {
 | 
			
		||||
  if (newTeam) {
 | 
			
		||||
    schedule.teamId = newTeam.id;
 | 
			
		||||
    schedule.team = newTeam;
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,11 +47,10 @@ onMounted(() => {
 | 
			
		|||
      options.value = Object.values(teamsList.teams);
 | 
			
		||||
      // select team with id in query parameter if exists
 | 
			
		||||
      const queryTeam = teamsList.teams.find(x => x.id == route.query.teamId);
 | 
			
		||||
      console.log(queryTeam);
 | 
			
		||||
      if (queryTeam) {
 | 
			
		||||
        selectedTeam.value = queryTeam;
 | 
			
		||||
        //schedule.teamId = queryTeam.id;
 | 
			
		||||
        schedule.fetchSchedule(schedule.teamId);
 | 
			
		||||
        schedule.team = queryTeam;
 | 
			
		||||
        schedule.fetchSchedule();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,8 @@ class TeamSchema(spec.BaseModel):
 | 
			
		|||
    id: int
 | 
			
		||||
    team_name: str
 | 
			
		||||
    discord_webhook_url: str | None
 | 
			
		||||
    tz_timezone: str
 | 
			
		||||
    minute_offset: int
 | 
			
		||||
    #players: list[PlayerTeamSpec] | None
 | 
			
		||||
 | 
			
		||||
class PlayerTeam(db.Model):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,9 @@ def map_team_to_schema(team: Team):
 | 
			
		|||
    return TeamSchema(
 | 
			
		||||
        id=team.id,
 | 
			
		||||
        team_name=team.team_name,
 | 
			
		||||
        discord_webhook_url=None
 | 
			
		||||
        discord_webhook_url=None,
 | 
			
		||||
        tz_timezone=team.tz_timezone,
 | 
			
		||||
        minute_offset=team.minute_offset
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
def map_player_to_schema(player: Player):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue