Set start month based on query parameters

This commit is contained in:
Maciej Pędzich 2023-01-14 21:45:26 +01:00
parent 065b78ec26
commit 694bf88379
4 changed files with 199 additions and 1 deletions

56
package-lock.json generated
View File

@ -13,6 +13,7 @@
"@astrojs/tailwind": "^2.1.3",
"@astrojs/vue": "^1.2.2",
"@fortawesome/fontawesome-free": "^6.2.1",
"@vuepic/vue-datepicker": "^3.6.4",
"astro": "^1.8.0",
"daisyui": "^2.46.0",
"debounce": "^1.2.1",
@ -1171,6 +1172,21 @@
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz",
"integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg=="
},
"node_modules/@vuepic/vue-datepicker": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.6.4.tgz",
"integrity": "sha512-A13K+UNf29H2kQK4RYbFwqgkAFnWxArqW3AD3inhtIDmhI5n3QsUIvSTWJBszYcuhx2k2f2mD6dEPncOtsZi3A==",
"dependencies": {
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.7"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"vue": ">=3.2.0"
}
},
"node_modules/acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
@ -1949,6 +1965,26 @@
"node": ">= 12"
}
},
"node_modules/date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/date-fns-tz": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.7.tgz",
"integrity": "sha512-1t1b8zyJo+UI8aR+g3iqr5fkUHWpd58VBx8J/ZSQ+w7YrGlw80Ag4sA86qkfCXRBLmMc4I2US+aPMd4uKvwj5g==",
"peerDependencies": {
"date-fns": ">=2.0.0"
}
},
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
@ -7508,6 +7544,15 @@
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz",
"integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg=="
},
"@vuepic/vue-datepicker": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.6.4.tgz",
"integrity": "sha512-A13K+UNf29H2kQK4RYbFwqgkAFnWxArqW3AD3inhtIDmhI5n3QsUIvSTWJBszYcuhx2k2f2mD6dEPncOtsZi3A==",
"requires": {
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.7"
}
},
"acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
@ -8032,6 +8077,17 @@
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA=="
},
"date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
},
"date-fns-tz": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.7.tgz",
"integrity": "sha512-1t1b8zyJo+UI8aR+g3iqr5fkUHWpd58VBx8J/ZSQ+w7YrGlw80Ag4sA86qkfCXRBLmMc4I2US+aPMd4uKvwj5g==",
"requires": {}
},
"debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",

View File

@ -23,6 +23,7 @@
"@astrojs/tailwind": "^2.1.3",
"@astrojs/vue": "^1.2.2",
"@fortawesome/fontawesome-free": "^6.2.1",
"@vuepic/vue-datepicker": "^3.6.4",
"astro": "^1.8.0",
"daisyui": "^2.46.0",
"debounce": "^1.2.1",

View File

@ -1,3 +1,140 @@
<script setup lang="ts">
import { onBeforeMount, ref } from 'vue';
import Datepicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css';
import type { UpdateMonthYearPayload } from '@/models/update-month-year-payload';
const today = new Date();
const minDate = ref(new Date('2021-01-01'));
const startDate = ref(new Date());
const getStartDateArgs = () => {
const queryParams = new URLSearchParams(location.search);
const year = queryParams.has('year')
? Math.max(
Math.min(
Number(queryParams.get('year')) || today.getFullYear(),
today.getFullYear()
),
2021
)
: today.getFullYear();
const normalisedMonthParam = Math.min(
// Query param months aren't zero-based, but JS Date months are
Math.max((Number(queryParams.get('month')) || 1) - 1, 0),
11
);
const month = queryParams.has('month')
? year === today.getFullYear()
? Math.min(normalisedMonthParam, today.getMonth())
: normalisedMonthParam
: today.getMonth();
return { month, year };
};
const updateSearchParams = ({ month, year }: UpdateMonthYearPayload) => {
const url = new URL(location.href);
url.searchParams.set('month', (month + 1).toString());
url.searchParams.set('year', year.toString());
window.history.pushState({}, '', url);
};
onBeforeMount(() => {
const { month, year } = getStartDateArgs();
startDate.value = new Date(year, month, 1);
});
</script>
<template>
<strong>TODO: implement snapshot calendar.</strong>
<Datepicker
:min-date="minDate"
:max-date="today"
:start-date="startDate"
:enable-time-picker="false"
:month-change-on-arrows="false"
:month-change-on-scroll="false"
no-swipe
no-today
prevent-min-max-navigation
inline
@update-month-year="updateSearchParams"
>
</Datepicker>
</template>
<style scoped lang="postcss">
:deep(div.dp__menu) {
@apply bg-base-100 shadow-xl border-base-content border-opacity-20;
}
:deep(div.dp__calendar_header) {
@apply w-full px-1 py-2 text-base-content border-base-content border-opacity-20;
}
:deep(div.dp__month_year_row) {
@apply text-base-content;
}
:deep(div.dp__inner_nav_disabled) {
@apply bg-transparent opacity-30;
}
:deep(div.dp__calendar_header_separator) {
@apply bg-base-content opacity-20;
}
:deep(div.dp__month_year_select),
:deep(div.dp__inner_nav),
:deep(div.dp__overlay_cell) {
@apply hover:bg-primary hover:text-primary-content;
}
:deep(div.dp__inner_nav_disabled) {
@apply hover:bg-transparent hover:text-inherit;
}
:deep(div.dp__calendar_item) {
@apply text-base-content;
}
:deep(div.dp__cell_inner) {
@apply md:mx-2 md:my-1.5 mx-1.5 my-1 p-0 hover:bg-transparent hover:text-inherit;
}
:deep(div.dp__cell_disabled) {
@apply text-base-content opacity-30;
}
:deep(div.dp__active_date) {
@apply bg-transparent text-inherit;
}
:deep(div.dp__action_row:last-of-type) {
@apply hidden;
}
:deep(div.dp__overlay),
:deep(div.dp__button.dp__overlay_action) {
@apply bg-base-100 text-base-content;
}
:deep(div.dp__overlay_cell) {
@apply bg-transparent;
}
:deep(div.dp__overlay_cell_active) {
@apply bg-primary text-primary-content;
}
:deep(div.dp__overlay_cell_disabled) {
@apply opacity-30 hover:bg-transparent hover:text-inherit;
}
</style>

View File

@ -0,0 +1,4 @@
export interface UpdateMonthYearPayload {
month: number;
year: number;
}