Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/assets/css/_component.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
}

@utility button-secondary {
@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;
@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;
}

@utility button-sm {
Expand Down
16 changes: 13 additions & 3 deletions app/components/base/InlineLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@
<NuxtLink
:to="href"
:target="external ? '_blank' : undefined"
class="group inline-flex flex-row gap-px"
class="group inline-flex flex-row gap-px items-center"
>
<IconRenderer :icon="typedIcon" aria-hidden class="size-5 shrink-0 mr-2" />
<slot />
<IconArrowOutward
v-if="external"
v-if="external && showExternalIcon"
aria-label="opens in new tab"
class="w-[1em] group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform duration-default ease-default"
/>
<div v-else-if="$slots.trailing" aria-hidden class="size-5 shrink-0 ml-2">
<slot name="trailing" />
</div>
</NuxtLink>
</template>

<script setup lang="ts">
defineProps<{
import type { IconType } from "~/components/render/IconRenderer.vue";

const { showExternalIcon = true, icon } = defineProps<{
href: string;
external?: boolean | null;
showExternalIcon?: boolean;
icon?: string | null;
}>();

const typedIcon = computed(() => icon as IconType | null);
</script>
40 changes: 40 additions & 0 deletions app/components/base/LinkCollection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<ul
v-if="filteredLinks.length > 0"
class="flex flex-row flex-wrap gap-x-15 gap-y-2"
:class="{
'justify-start': align === 'start',
'justify-center': align === 'center',
}"
>
<li v-for="(link, index) in filteredLinks" :key="link.url ?? index">
<InlineLink
:href="link.fileDownload?.url ?? link.url ?? ''"
:external="link.external"
:show-external-icon="false"
:icon="link.icon"
class="no-underline text-foreground hover:text-accent font-semibold text-xl py-2 items-center"
>
{{ link.text }}
<template #trailing>
<IconArrowForward
class="text-action group-hover:translate-x-2 transition-transform duration-default ease-default"
/>
</template>
</InlineLink>
</li>
</ul>
</template>

<script setup lang="ts">
import type { LinkFragment } from "~~/shared/types/graphql";

const { links, align = "start" } = defineProps<{
links: (LinkFragment | null)[] | undefined;
align?: "start" | "center";
}>();

const filteredLinks = computed(() =>
(links ?? []).filter((link) => link !== null),
);
</script>
11 changes: 10 additions & 1 deletion app/components/modules/FiftyFiftySecondary.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
<Heading as="h2">{{ data.heading }}</Heading>
<p class="type-eyebrow order-first">{{ data.eyebrow }}</p>
<RichTextRenderer :json="data?.copy?.json" />
<div class="flex flex-wrap gap-x-5 gap-y-3">
<div v-if="ctaStyle === 'Button'" class="flex flex-wrap gap-x-5 gap-y-3">
<InlineLink
v-if="data.callToAction?.url"
:href="data.callToAction.url"
:external="data.callToAction.external"
:icon="data.callToAction.icon"
class="button button-md"
>
{{ data.callToAction.text }}
Expand All @@ -25,11 +26,16 @@
v-if="data.secondaryCallToAction?.url"
:href="data.secondaryCallToAction.url"
:external="data.secondaryCallToAction.external"
:icon="data.secondaryCallToAction.icon"
class="button-secondary button-md"
>
{{ data.secondaryCallToAction.text }}
</InlineLink>
</div>
<LinkCollection
v-else
:links="[data.callToAction, data.secondaryCallToAction]"
/>
</div>
<div
v-if="data.image?.url"
Expand Down Expand Up @@ -62,4 +68,7 @@ import type { FiftyFiftyFragment } from "~~/shared/types/graphql";
const { data } = defineProps<ModuleProps<FiftyFiftyFragment>>();

const align = computed(() => data.imageAlignment as "Left" | "Right");
const ctaStyle = computed(
() => data.callToActionStyle as "Button" | "Arrow Link",
);
</script>
11 changes: 10 additions & 1 deletion app/components/modules/FiftyFiftyWhite.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
<Heading as="h2">{{ data.heading }}</Heading>
<p class="type-eyebrow order-first">{{ data.eyebrow }}</p>
<RichTextRenderer :json="data?.copy?.json" />
<div class="flex flex-wrap gap-x-5 gap-y-3">
<div v-if="ctaStyle === 'Button'" class="flex flex-wrap gap-x-5 gap-y-3">
<InlineLink
v-if="data.callToAction?.url"
:href="data.callToAction.url"
:external="data.callToAction.external"
:icon="data.callToAction.icon"
class="button button-md"
>
{{ data.callToAction.text }}
Expand All @@ -22,11 +23,16 @@
v-if="data.secondaryCallToAction?.url"
:href="data.secondaryCallToAction.url"
:external="data.secondaryCallToAction.external"
:icon="data.secondaryCallToAction.icon"
class="button-secondary button-md"
>
{{ data.secondaryCallToAction.text }}
</InlineLink>
</div>
<LinkCollection
v-else
:links="[data.callToAction, data.secondaryCallToAction]"
/>
</div>
<div
v-if="data.image?.url"
Expand All @@ -52,4 +58,7 @@ import type { FiftyFiftyFragment } from "~~/shared/types/graphql";
const { data } = defineProps<ModuleProps<FiftyFiftyFragment>>();

const align = computed(() => data.imageAlignment as "Left" | "Right");
const ctaStyle = computed(
() => data.callToActionStyle as "Button" | "Arrow Link",
);
</script>
53 changes: 53 additions & 0 deletions app/components/modules/Schedule.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<ContentContainer
as="section"
class="pb-vertical md:pb-vertical-lg gap-y-7 md:gap-y-10"
grid
>
<div class="col-span-full max-w-copy mx-auto text-center">
<Heading as="h2" class="mb-6">{{ data.heading }}</Heading>
<RichTextRenderer :json="data?.copy?.json" class="type-body text-muted" />
</div>

<div
v-if="data.eventDate"
class="col-span-full mx-auto text-center flex flex-col items-center gap-y-6"
>
<Heading as="h3" variant="h4">{{ data.eventDate }}</Heading>
<div class="divider" />
</div>

<div
class="col-span-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
>
<div
v-for="(event, index) in events"
:key="index"
class="rounded-xl p-6 text-center bg-secondary"
>
<Heading as="h4" class="mb-2">{{ event.title }}</Heading>
<RichTextRenderer
:json="event.copy?.json"
class="type-body text-muted"
/>
</div>
</div>

<LinkCollection
:links="data.callToActionCollection?.items"
align="center"
class="col-span-full mx-auto md:px-side"
/>
</ContentContainer>
</template>

<script setup lang="ts">
import type { ModuleProps } from "~/types/module";
import type { ScheduleFragment } from "~~/shared/types/graphql";

const { data } = defineProps<ModuleProps<ScheduleFragment>>();

const events = computed(
() => data.eventsCollection?.items.filter((item) => item !== null) ?? [],
);
</script>
22 changes: 22 additions & 0 deletions app/components/render/IconRenderer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<template>
<component :is="Icon" v-if="Icon" class="size-5 shrink-0" />
</template>

<script setup lang="ts">
import { IconApple, IconDownload, IconGoogle } from "#components";
Comment thread
ben-basten marked this conversation as resolved.
export type IconType = "Download" | "Apple" | "Google";

const icons: Record<IconType, Component> = {
Download: IconDownload,
Apple: IconApple,
Google: IconGoogle,
};
const props = defineProps<{
icon: IconType | null | undefined;
}>();

const Icon = computed(() => {
if (!props.icon) return null;
return icons[props.icon];
});
</script>
2 changes: 2 additions & 0 deletions app/components/render/ModuleRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import HomepageHero from "~/components/modules/HomepageHero.vue";
import FiftyFifty from "~/components/modules/FiftyFifty.vue";
import Accordion from "~/components/modules/Accordion.vue";
import Schedule from "~/components/modules/Schedule.vue";
import type { Component } from "vue";
import type { PageStandardFragment } from "~~/shared/types/graphql";

Expand All @@ -21,6 +22,7 @@ const modules: Record<string, Component> = {
HomepageHero: HomepageHero,
ModuleFiftyfifty: FiftyFifty,
ModuleAccordion: Accordion,
ModuleSchedule: Schedule,
};

const component = computed(() => {
Expand Down
12 changes: 12 additions & 0 deletions app/components/svg/IconApple.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xml:space="preserve"
viewBox="0 0 814 1000"
fill="currentColor"
>
<path
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"
/>
</svg>
</template>
11 changes: 11 additions & 0 deletions app/components/svg/IconArrowForward.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 -960 960 960"
fill="currentColor"
>
<path
d="M647-440H160v-80h487L423-744l57-56 320 320-320 320-57-56 224-224Z"
/>
</svg>
</template>
11 changes: 11 additions & 0 deletions app/components/svg/IconDownload.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 -960 960 960"
fill="currentColor"
>
<path
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"
/>
</svg>
</template>
11 changes: 11 additions & 0 deletions app/components/svg/IconGoogle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 488 512"
fill="currentColor"
>
<path
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"
/>
</svg>
</template>
4 changes: 4 additions & 0 deletions server/graphql/fragments/link.fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ export const LINK_FRAGMENT = gql`
text
url
external
icon
fileDownload {
url
}
}
`;
1 change: 1 addition & 0 deletions server/graphql/modules/fifty-fifty.fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const FIFTY_FIFTY_FRAGMENT = gql`
secondaryCallToAction {
...Link
}
callToActionStyle
image {
...Image
}
Expand Down
26 changes: 26 additions & 0 deletions server/graphql/modules/schedule.fragment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { gql } from "graphql-request";

export const SCHEDULE_FRAGMENT = gql`
fragment Schedule on ModuleSchedule {
heading
copy {
json
}
eventDate
callToActionCollection(limit: 3) {
items {
...Link
}
}
eventsCollection(limit: 15) {
items {
... on ComponentTitleCopy {
title
copy {
json
}
}
}
}
}
`;
5 changes: 5 additions & 0 deletions server/graphql/queries/page-standard.query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IMAGE_FRAGMENT } from "../fragments/image.fragment";
import { FIFTY_FIFTY_FRAGMENT } from "../modules/fifty-fifty.fragment";
import { LINK_FRAGMENT } from "../fragments/link.fragment";
import { ACCORDION_FRAGMENT } from "../modules/accordion.fragment";
import { SCHEDULE_FRAGMENT } from "../modules/schedule.fragment";

export const PAGE_STANDARD_QUERY = gql`
query PageStandard($slug: String!) {
Expand Down Expand Up @@ -31,12 +32,16 @@ export const PAGE_STANDARD_QUERY = gql`
... on ModuleAccordion {
...Accordion
}
... on ModuleSchedule {
...Schedule
}
}
}
}
${HOMEPAGE_HERO_FRAGMENT}
${FIFTY_FIFTY_FRAGMENT}
${ACCORDION_FRAGMENT}
${SCHEDULE_FRAGMENT}
${IMAGE_FRAGMENT}
${LINK_FRAGMENT}
`;