Skip to content

Commit cdbce4e

Browse files
committed
feat: schedule module
1 parent 2ba56b7 commit cdbce4e

13 files changed

Lines changed: 209 additions & 3 deletions

File tree

app/assets/css/_component.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
}
44

55
@utility button-secondary {
6-
@apply cursor-pointer disabled:cursor-not-allowed bg-transparent border-2 border-action text-action font-semibold rounded-lg no-underline w-fit transition-colors duration-default ease-default hover:border-accent hover:text-accent;
6+
@apply cursor-pointer disabled:cursor-not-allowed bg-transparent border-2 border-action text-slate font-semibold rounded-lg no-underline w-fit transition-colors duration-default ease-default hover:border-accent hover:text-accent;
77
}
88

99
@utility button-sm {

app/components/base/InlineLink.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,26 @@
44
:target="external ? '_blank' : undefined"
55
class="group inline-flex flex-row gap-px"
66
>
7+
<IconRenderer :icon="icon" aria-hidden class="size-5 shrink-0" />
78
<slot />
89
<IconArrowOutward
9-
v-if="external"
10+
v-if="external && showExternalIcon"
1011
aria-label="opens in new tab"
1112
class="w-[1em] group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform duration-default ease-default"
1213
/>
14+
<div v-else-if="$slots.trailing" aria-hidden class="size-5 shrink-0">
15+
<slot name="trailing" />
16+
</div>
1317
</NuxtLink>
1418
</template>
1519

1620
<script setup lang="ts">
17-
defineProps<{
21+
import type { IconType } from "~/components/render/IconRenderer.vue";
22+
23+
const { showExternalIcon = true } = defineProps<{
1824
href: string;
1925
external?: boolean | null;
26+
showExternalIcon?: boolean;
27+
icon?: IconType | null;
2028
}>();
2129
</script>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<template>
2+
<ul
3+
v-if="filteredLinks.length > 0"
4+
class="flex flex-row flex-wrap gap-x-15 gap-y-2"
5+
:class="{
6+
'justify-start': align === 'start',
7+
'justify-center': align === 'center',
8+
}"
9+
>
10+
<li v-for="(link, index) in filteredLinks" :key="link.url ?? index">
11+
<InlineLink
12+
:href="link.fileDownload?.url ?? link.url ?? ''"
13+
:external="link.external"
14+
:show-external-icon="false"
15+
:icon="link.icon as IconType"
16+
class="no-underline text-foreground hover:text-accent font-semibold text-xl py-2 gap-x-3 items-center"
17+
>
18+
{{ link.text }}
19+
<template #trailing>
20+
<IconArrowForward
21+
class="text-action group-hover:translate-x-2 transition-transform duration-default ease-default"
22+
/>
23+
</template>
24+
</InlineLink>
25+
</li>
26+
</ul>
27+
</template>
28+
29+
<script setup lang="ts">
30+
import type { LinkFragment } from "~~/shared/types/graphql";
31+
import type { IconType } from "../render/IconRenderer.vue";
32+
33+
const { links, align = "start" } = defineProps<{
34+
links: (LinkFragment | null)[] | undefined;
35+
align?: "start" | "center";
36+
}>();
37+
38+
const filteredLinks = computed(() =>
39+
(links ?? []).filter((link) => link !== null),
40+
);
41+
</script>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<template>
2+
<ContentContainer
3+
as="section"
4+
class="pb-vertical md:pb-vertical-lg gap-y-7 md:gap-y-10"
5+
grid
6+
>
7+
<div class="col-span-full max-w-copy mx-auto text-center">
8+
<Heading as="h2" class="mb-6">{{ data.heading }}</Heading>
9+
<RichTextRenderer :json="data?.copy?.json" class="type-body text-muted" />
10+
</div>
11+
12+
<div
13+
v-if="data.eventDate"
14+
class="col-span-full mx-auto text-center flex flex-col items-center gap-y-6"
15+
>
16+
<Heading as="h3" variant="h4">{{ data.eventDate }}</Heading>
17+
<div class="divider" />
18+
</div>
19+
20+
<div
21+
class="col-span-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
22+
>
23+
<div
24+
v-for="(event, index) in events"
25+
:key="index"
26+
class="bg-surface rounded-xl p-6 text-center bg-secondary"
27+
>
28+
<Heading as="h4" class="mb-2">{{ event.title }}</Heading>
29+
<RichTextRenderer
30+
:json="event.copy?.json"
31+
class="type-body text-muted"
32+
/>
33+
</div>
34+
</div>
35+
36+
<LinkCollection
37+
:links="data.callToActionCollection?.items"
38+
align="center"
39+
class="col-span-full mx-auto px-side-mobile md:px-side"
40+
/>
41+
</ContentContainer>
42+
</template>
43+
44+
<script setup lang="ts">
45+
import type { ModuleProps } from "~/types/module";
46+
import type { ScheduleFragment } from "~~/shared/types/graphql";
47+
48+
const { data } = defineProps<ModuleProps<ScheduleFragment>>();
49+
50+
const events = computed(
51+
() => data.eventsCollection?.items.filter((item) => item !== null) ?? [],
52+
);
53+
</script>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<component :is="Icon" v-if="Icon" class="size-5 shrink-0" />
3+
</template>
4+
5+
<script setup lang="ts">
6+
import { IconApple, IconDownload, IconGoogle } from "#components";
7+
export type IconType = "Download" | "Apple" | "Google";
8+
9+
const icons: Record<IconType, Component> = {
10+
Download: IconDownload,
11+
Apple: IconApple,
12+
Google: IconGoogle,
13+
};
14+
const props = defineProps<{
15+
icon: IconType | null | undefined;
16+
}>();
17+
18+
const Icon = computed(() => {
19+
if (!props.icon) return null;
20+
return icons[props.icon];
21+
});
22+
</script>

app/components/render/ModuleRenderer.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import HomepageHero from "~/components/modules/HomepageHero.vue";
77
import FiftyFifty from "~/components/modules/FiftyFifty.vue";
88
import Accordion from "~/components/modules/Accordion.vue";
9+
import Schedule from "~/components/modules/Schedule.vue";
910
import type { Component } from "vue";
1011
import type { PageStandardFragment } from "~~/shared/types/graphql";
1112
@@ -21,6 +22,7 @@ const modules: Record<string, Component> = {
2122
HomepageHero: HomepageHero,
2223
ModuleFiftyfifty: FiftyFifty,
2324
ModuleAccordion: Accordion,
25+
ModuleSchedule: Schedule,
2426
};
2527
2628
const component = computed(() => {

app/components/svg/IconApple.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<template>
2+
<svg
3+
xmlns="http://www.w3.org/2000/svg"
4+
xml:space="preserve"
5+
viewBox="0 0 814 1000"
6+
fill="currentColor"
7+
>
8+
<path
9+
d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"
10+
/>
11+
</svg>
12+
</template>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<svg
3+
xmlns="http://www.w3.org/2000/svg"
4+
viewBox="0 -960 960 960"
5+
fill="currentColor"
6+
>
7+
<path
8+
d="M647-440H160v-80h487L423-744l57-56 320 320-320 320-57-56 224-224Z"
9+
/>
10+
</svg>
11+
</template>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<svg
3+
xmlns="http://www.w3.org/2000/svg"
4+
viewBox="0 -960 960 960"
5+
fill="currentColor"
6+
>
7+
<path
8+
d="M480-320 280-520l56-58 104 104v-326h80v326l104-104 56 58-200 200ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z"
9+
/>
10+
</svg>
11+
</template>

app/components/svg/IconGoogle.vue

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<svg
3+
xmlns="http://www.w3.org/2000/svg"
4+
viewBox="0 0 488 512"
5+
fill="currentColor"
6+
>
7+
<path
8+
d="M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"
9+
/>
10+
</svg>
11+
</template>

0 commit comments

Comments
 (0)