diff options
Diffstat (limited to 'src/components/DateSelector.astro')
-rw-r--r-- | src/components/DateSelector.astro | 172 |
1 files changed, 107 insertions, 65 deletions
diff --git a/src/components/DateSelector.astro b/src/components/DateSelector.astro index d57919e..ab10fd1 100644 --- a/src/components/DateSelector.astro +++ b/src/components/DateSelector.astro @@ -1,6 +1,8 @@ --- +import { defined } from "@utils/anonymous"; + interface Props { - date: Date; + date?: Date; years: number[]; months: number[]; days?: number[]; @@ -8,9 +10,10 @@ interface Props { const { date, years, months, days } = Astro.props; -const y = date.getFullYear(); -const m = date.getMonth() + 1; -const d = date.getDate(); +const dateParts = Astro.params.date?.split("/").map(Number); +const y = dateParts?.[0]; +const m = dateParts?.[1]; +const d = dateParts?.[2]; let yI = 0; let mI = 0; let dI = 0; @@ -19,23 +22,31 @@ const list = new Intl.ListFormat("pt-PT", { type: "unit", style: "narrow" }); const pad = (n: number) => String(n).padStart(2, "0"); --- -<nav> +<nav class="mute small"> <span role="list"> Anos:{" "} { - list.formatToParts(years.map((y) => - new Intl.DateTimeFormat("pt-PT", { year: "2-digit" }).format( - new Date( - Date.UTC( - y, - 0, - 1, - date.getTimezoneOffset() / 60, - date.getTimezoneOffset() % 60, + list.formatToParts( + years.sort().map((y) => + new Intl.DateTimeFormat("pt-PT", { year: "numeric" }).format( + new Date( + Date.UTC( + y, + 0, + 3, + ...[ + date === undefined + ? undefined + : date.getTimezoneOffset() / 60, + date === undefined + ? undefined + : date.getTimezoneOffset() % 60, + ].filter(defined), + ), ), - ), - ) - )).map(({ type, value }: { type: string; value: string }) => { + ) + ), + ).map(({ type, value }: { type: string; value: string }) => { switch (type) { case "element": { const year = years[yI++]; @@ -53,67 +64,39 @@ const pad = (n: number) => String(n).padStart(2, "0"); }) } </span> - <br /> - <span role="list"> - Meses:{" "} - { - list.formatToParts(months.map((m) => - new Intl.DateTimeFormat("pt-PT", { month: "short" }).format( - new Date( - Date.UTC( - y, - m - 1, - 1, - date.getTimezoneOffset() / 60, - date.getTimezoneOffset() % 60, - ), - ), - ) - )).map(({ type, value }: { type: string; value: string }) => { - switch (type) { - case "element": { - const month = months[mI++]; - return ( - <span role="listitem"><a - class:list={[{ active: month === m }]} - href={`/blog/${y}/${pad(month)}`} - >{value}</a></span> - ); - } - case "literal": { - return <span>{value}</span>; - } - } - }) - } - </span> { - days && - ( + y && ( <><br /><span role="list"> - Dias:{" "} + Meses:{" "} { - list.formatToParts(days.map((d) => { - return new Intl.DateTimeFormat("pt-PT", { day: "numeric" }) - .format( + list.formatToParts( + months.sort().map((m) => + new Intl.DateTimeFormat("pt-PT", { month: "short" }).format( new Date( Date.UTC( y, m - 1, - d, - date.getTimezoneOffset() / 60, - date.getTimezoneOffset() % 60, + 3, + ...[ + date === undefined + ? undefined + : date.getTimezoneOffset() / 60, + date === undefined + ? undefined + : date.getTimezoneOffset() % 60, + ].filter(defined), ), ), - ); - })).map(({ type, value }: { type: string; value: string }) => { + ) + ), + ).map(({ type, value }: { type: string; value: string }) => { switch (type) { case "element": { - const day = days[dI++]; + const month = months[mI++]; return ( <span role="listitem"><a - class:list={[{ active: day === d }]} - href={`/blog/${y}/${pad(m)}/${pad(d)}`} + class:list={[{ active: month === m }]} + href={`/blog/${y}/${pad(month)}`} >{value}</a></span> ); } @@ -126,10 +109,69 @@ const pad = (n: number) => String(n).padStart(2, "0"); </span></> ) } + { + days && + ( + <><br /><span role="list"> + Dias:{" "} + { + y && m && + list.formatToParts( + days.sort().map((d) => { + return new Intl.DateTimeFormat("pt-PT", { + day: "numeric", + }) + .format( + new Date( + Date.UTC( + y, + m - 1, + d, + ...[ + date === undefined + ? undefined + : date.getTimezoneOffset() / 60, + date === undefined + ? undefined + : date.getTimezoneOffset() % 60, + ].filter(defined), + ), + ), + ); + }), + ).map( + ({ type, value }: { type: string; value: string }) => { + switch (type) { + case "element": { + const day = days[dI++]; + return ( + <span role="listitem"><a + class:list={[{ active: day === d }]} + href={`/blog/${y}/${pad(m)}/${pad(day)}`} + >{value}</a></span> + ); + } + case "literal": { + return <span>{value}</span>; + } + } + }, + ) + } + </span></> + ) + } </nav> <style> + nav { + padding-block: calc(var(--size-2) * 1em); + } a.active { font-weight: bolder; } + + a:hover { + color: var(--color-active); + } </style> |