diff --git a/src/assets/img/camo-transparent-bg.png b/src/assets/img/camo-transparent-bg.png
new file mode 100644
index 0000000..f522899
Binary files /dev/null and b/src/assets/img/camo-transparent-bg.png differ
diff --git a/src/components/ScheduleBox.vue b/src/components/ScheduleBox.vue
index ec7ac79..2c1e346 100644
--- a/src/components/ScheduleBox.vue
+++ b/src/components/ScheduleBox.vue
@@ -60,7 +60,7 @@
+
+
diff --git a/src/stores/data.mjs b/src/stores/data.mjs
index fa40a9b..2aa8802 100644
--- a/src/stores/data.mjs
+++ b/src/stores/data.mjs
@@ -41,11 +41,13 @@ function defineEndpointStore(id, endpoint, transform = null) {
export const useSchedulesDataStore = defineEndpointStore('schedules', '/data/schedules.json', d => d.data);
export const useGearDataStore = defineEndpointStore('gear', '/data/gear.json', d => d.data);
+export const useFestivalsDataStore = defineEndpointStore('festivals', '/data/festivals.json');
export const useDataStore = defineStore('data', () => {
const stores = {
schedules: useSchedulesDataStore(),
gear: useGearDataStore(),
+ festivals: useFestivalsDataStore(),
};
let updateDataTimer;
@@ -93,6 +95,7 @@ export const useDataStore = defineStore('data', () => {
stopUpdating,
schedules: computed(() => stores.schedules.data),
gear: computed(() => stores.gear.data),
+ festivals: computed(() => stores.festivals.data),
}
});
diff --git a/src/stores/schedules.mjs b/src/stores/schedules.mjs
index fe84ca7..03e783f 100644
--- a/src/stores/schedules.mjs
+++ b/src/stores/schedules.mjs
@@ -28,17 +28,24 @@ export const useRegularSchedulesStore = defineScheduleStore('regular', {
settings: node => node.regularMatchSetting,
});
-// Anarchy Battle
+// Anarchy Battle (Series)
export const useAnarchySeriesSchedulesStore = defineScheduleStore('anarchy/series', {
nodes: () => useSchedulesDataStore().data?.bankaraSchedules.nodes,
settings: node => node.bankaraMatchSettings?.find(s => s.mode === 'CHALLENGE'),
});
+// Anarchy Battle (Open)
export const useAnarchyOpenSchedulesStore = defineScheduleStore('anarchy/open', {
nodes: () => useSchedulesDataStore().data?.bankaraSchedules.nodes,
settings: node => node.bankaraMatchSettings?.find(s => s.mode === 'OPEN'),
});
+// Splatfest Battle
+export const useSplatfestSchedulesStore = defineScheduleStore('splatfest', {
+ nodes: () => useSchedulesDataStore().data?.festSchedules.nodes,
+ settings: node => node.festMatchSetting,
+});
+
// Salmon Run
export const useSalmonRunSchedulesStore = defineScheduleStore('salmonRun', {
nodes: () => useSchedulesDataStore().data?.coopGroupingSchedule.regularSchedules.nodes,
@@ -49,5 +56,6 @@ if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useRegularSchedulesStore, import.meta.hot));
import.meta.hot.accept(acceptHMRUpdate(useAnarchySeriesSchedulesStore, import.meta.hot));
import.meta.hot.accept(acceptHMRUpdate(useAnarchyOpenSchedulesStore, import.meta.hot));
+ import.meta.hot.accept(acceptHMRUpdate(useSplatfestSchedulesStore, import.meta.hot));
import.meta.hot.accept(acceptHMRUpdate(useSalmonRunSchedulesStore, import.meta.hot));
}
diff --git a/src/stores/splatfests.mjs b/src/stores/splatfests.mjs
new file mode 100644
index 0000000..b9dd956
--- /dev/null
+++ b/src/stores/splatfests.mjs
@@ -0,0 +1,51 @@
+import { acceptHMRUpdate, defineStore } from "pinia";
+import { computed } from "vue";
+import { useFestivalsDataStore } from "./data.mjs";
+import { useTimeStore } from "./time.mjs";
+
+export const STATUS_PAST = 'past';
+export const STATUS_ACTIVE = 'active';
+export const STATUS_UPCOMING = 'upcoming';
+
+function defineSplatfestRegionStore(region) {
+ return defineStore(`splatfests/${region}`, () => {
+ const time = useTimeStore();
+ const store = useFestivalsDataStore();
+
+ function getStatus(node) {
+ switch (true) {
+ case time.isActive(node.startTime, node.endTime):
+ return STATUS_ACTIVE;
+ case time.isUpcoming(node.startTime):
+ return STATUS_UPCOMING;
+ default:
+ return STATUS_PAST;
+ }
+ }
+
+ const festivals = computed(() => store.data?.[region]?.data.festRecords.nodes.map(node => {
+ return {
+ ...node,
+ status: getStatus(node),
+ };
+ }));
+
+ const previousFestivals = computed(() => festivals.value?.filter(f => f.status === STATUS_PAST));
+ const activeFestival = computed(() => festivals.value?.find(f => f.status === STATUS_ACTIVE));
+ const upcomingFestival = computed(() => festivals.value?.find(f => f.status === STATUS_UPCOMING))
+
+ return { festivals, previousFestivals, activeFestival, upcomingFestival };
+ });
+}
+
+export const useUSSplatfestsStore = defineSplatfestRegionStore('US');
+export const useEUSplatfestsStore = defineSplatfestRegionStore('EU');
+export const useJPSplatfestsStore = defineSplatfestRegionStore('JP');
+export const useAPSplatfestsStore = defineSplatfestRegionStore('AP');
+
+if (import.meta.hot) {
+ import.meta.hot.accept(acceptHMRUpdate(useUSSplatfestsStore, import.meta.hot));
+ import.meta.hot.accept(acceptHMRUpdate(useEUSplatfestsStore, import.meta.hot));
+ import.meta.hot.accept(acceptHMRUpdate(useJPSplatfestsStore, import.meta.hot));
+ import.meta.hot.accept(acceptHMRUpdate(useAPSplatfestsStore, import.meta.hot));
+}
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index c9fb018..5d905a6 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -1,12 +1,25 @@