Skip to content

Commit

Permalink
adding EDU Home page template (#614)
Browse files Browse the repository at this point in the history
* adding EDU Home page template

* fixing vue build errors

* updates topic links to go to prefiltered resource search results

* fixing accessibility issues in SearchInput
  • Loading branch information
stephiescastle committed Sep 12, 2024
1 parent 833edab commit 0a88c7e
Show file tree
Hide file tree
Showing 3 changed files with 268 additions and 4 deletions.
19 changes: 15 additions & 4 deletions packages/vue/src/components/SearchInput/SearchInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface SearchInputProps {
placeholder?: string
autoFocus?: boolean
defaultColors?: boolean
withButton?: boolean
}
// define props
Expand All @@ -16,10 +17,11 @@ const props = withDefaults(defineProps<SearchInputProps>(), {
underlinedInputValue: undefined,
placeholder: '',
autoFocus: false,
defaultColors: true
defaultColors: true,
withButton: false
})
const emit = defineEmits(['input', 'esc'])
const emit = defineEmits(['input', 'esc', 'submit'])
const model = defineModel()
const isFocused = ref(false)
Expand Down Expand Up @@ -67,20 +69,29 @@ onMounted(() => {
<input
ref="searchQueryRef"
v-model="model"
class="pl-14 focus:ring-2 relative z-10 w-full pr-5 text-lg bg-transparent border-0"
class="pl-14 h-full focus:ring-2 relative z-10 w-full px-5 text-sm md:text-base lg:text-lg bg-transparent border-0"
:class="{
'text-gray-dark': defaultColors,
'py-1': underlinedInput,
'py-4': !underlinedInput
'py-3.5 lg:py-5': !underlinedInput
}"
type="search"
aria-label="Query"
:placeholder="placeholder"
@keydown.esc="emit('esc')"
@keydown.enter="emit('submit')"
@input="emit('input', $event.target)"
@focus="isFocused = true"
@blur="isFocused = false"
/>
<button
v-if="withButton"
class="z-10 cursor-pointer bg-action p-4 lg:p-5 border border-white"
aria-label="Search resources"
@click="emit('submit')"
>
<IconSearch class="relative z-10 text-xl sm:text-2xl lg:text-3xl text-white" />
</button>
</div>
</template>
<style lang="scss" scoped>
Expand Down
99 changes: 99 additions & 0 deletions packages/vue/src/templates/edu/PageEduHome/PageEduHome.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { BlockLinkCardCarouselData } from './../../../components/BlockLinkCarousel/BlockLinkCarousel.stories.js'
import { EventsBlockLinkCarouselData } from './../../../components/BlockLinkCarousel/BlockLinkCarousel.stories'
import { AboutTheAuthorData } from './../../../components/AboutTheAuthor/AboutTheAuthor.stories'
import { BlockImageData } from './../../../components/BlockImage/BlockImage.stories'
import { BlockVideoData } from './../../../components/BlockVideo/BlockVideo.stories'
import { BlockVideoEmbedData } from './../../../components/BlockVideoEmbed/BlockVideoEmbed.stories'
import { BlockImageComparisonData } from './../../../components/BlockImageComparison/BlockImageComparison.stories'
import PageEduHome from './PageEduHome.vue'

export default {
title: 'Templates/EDU/PageEduHome',
component: PageEduHome,
tags: ['!autodocs'],
parameters: {
html: {
root: '#storyDecorator'
},
layout: 'fullscreen'
},
excludeStories: /.*Data$/
}

// stories
export const BaseStory = {
name: 'PageEduHome',
args: {
data: {
__typename: 'EDUHomePage',
title: 'EDU Homepage',
slug: 'edu-home',
url: '/',
lastPublishedAt: '2024-08-22T02:33:13.507206+00:00',
thumbnailImage: {
alt: '',
original: 'https://picsum.photos/512/288'
},
heroImage: {
// beach
src: {
url: 'https://picsum.photos/id/973/1800/1200',
width: 1800,
height: 1200
},
// lake
srcSet:
'https://picsum.photos/id/865/768/548 768w, https://picsum.photos/id/865/1024/684 1024w, https://picsum.photos/id/865/1440/770 1440w, https://picsum.photos/id/865/1800/963 1800w',
// jungle
screenMd: {
url: 'https://picsum.photos/id/921/800/640'
},
// desert
screenSm: {
url: 'https://picsum.photos/id/247/640/900'
},
alt: 'Robotics detail page hero image'
},
heroText: 'Discover a universe of activities & resources',
hotTopics: [
{
page: {
title: 'Psyche Asteroid',
url: '/topic/'
}
},
{
page: {
title: 'Mars Rovers',
url: '/topic/'
}
},
{
page: {
title: 'Webb Space Telescope',
url: '/topic/'
}
},
{
page: {
title: 'NASA Pi Day',
url: '/topic/'
}
}
],
body: [
{
blockType: 'HeadingBlock',
heading: 'EDU Home',
level: 'h2',
size: 'h2'
},
{
blockType: 'RichTextBlock',
value:
'<p>Lorem ipsum <a href="/missions/test-mission/">dolor</a> sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.</p><p>Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.</p>\n'
}
]
}
}
}
154 changes: 154 additions & 0 deletions packages/vue/src/templates/edu/PageEduHome/PageEduHome.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<script setup lang="ts">
import { computed, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import type { ImageObject, PageObject } from '../../../interfaces'
import SearchInput from './../../../components/SearchInput/SearchInput.vue'
import BlockStreamfield from './../../../components/BlockStreamfield/BlockStreamfield.vue'
import BaseLink from './../../../components/BaseLink/BaseLink.vue'
const router = useRouter()
interface PageEduHomeObject extends PageObject {
heroImage: ImageObject
heroText: string
hotTopics: {
page: PageObject
}[]
}
interface PageEduHomeProps {
data: PageEduHomeObject
}
// define props
const props = withDefaults(defineProps<PageEduHomeProps>(), {
data: undefined
})
const { data } = reactive(props)
const searchQuery = ref(undefined)
const image = computed(() => {
return data?.heroImage
})
const submitSearch = () => {
router.push({ path: '/edu/resources/', query: { query: searchQuery.value } })
}
</script>
<template>
<div
v-if="data"
class="PageEduHome ThemeVariantLight -nav-offset"
>
<div class="EduHero max-w-screen-3xl relative mx-auto">
<div class="absolute inset-0 z-10 bg-black">
<picture v-if="image?.src">
<source
media="(min-width: 768px)"
:srcset="image.srcSet"
/>
<source
media="(min-width: 420px)"
:srcset="image.screenMd?.url"
/>
<source :srcset="image.screenSm?.url" />
<img
class="md:object-right object-cover object-bottom w-full h-full"
:src="image.src.url"
:width="image.src.width"
:height="image.src.height"
:alt="image.alt"
/>
</picture>
</div>
<div class="content-wrapper lg:flex lg:items-center relative z-20 w-full h-full">
<div
class="bg-gradient-to-b lg:bg-gradient-to-l from-transparent-w25 lg:from-transparent-w50 to-transparent-black-50 lg:to-transparent-black-50 absolute inset-0"
></div>
<div class="text-contrast relative w-full text-white">
<div class="lg:py-0 pb-10 container pt-8 mx-auto">
<div class="lg:px-10 2xl:px-0 pt-30 lg:pt-16 lg:pb-18 px-4">
<h1
v-if="data.heroText"
class="lg:w-3/4 xl:w-3/4 xl:text-10xl lg:text-9xl text-7xl lg:tracking-tightest lg:leading-tighter mb-5 font-bold leading-tight"
>
{{ data.heroText }}
</h1>
<div class="md:w-4/5 lg:w-2/3 xl:w-1/2 w-full">
<SearchInput
v-model="searchQuery"
class="bg-white border-none"
placeholder="Search the K-12 resource library"
with-button
@submit="submitSearch()"
/>
</div>
<div
v-if="data.hotTopics?.length"
class="md:flex flex-row mt-10"
>
<h2
class="text-subtitle mt-1 text-white font-semibold whitespace-nowrap mr-5 mb-3 md:mb-0 lg:mr-8"
>
Hot Topics
</h2>
<ul class="flex flex-row flex-wrap">
<li
v-for="(topic, index) in data.hotTopics"
:key="index"
class="mr-2 mb-2"
>
<BaseLink
variant="none"
:to="`/edu/resources?query=${topic.page?.title}`"
link-class="text-gray-dark whitespace-nowrap text-sm bg-[#99D1DF] font-extrabold rounded-full inline-block px-3 py-1 text-contrast-none hover:bg-action hover:text-white"
>
{{ topic.page?.title }}
</BaseLink>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div
v-if="data.body?.length"
class="my-10 lg:my-18"
>
<BlockStreamfield
v-if="data.body?.length"
:data="data.body"
/>
</div>
</div>
</template>
<style lang="scss">
.PageEduHome {
.EduHero {
.content-wrapper {
@screen lg {
min-height: 548px; // maintains 1440x770 aspect ratio
}
@screen xl {
min-height: 684px; // maintains 1440x770 aspect ratio
}
@screen 2xl {
min-height: 770px; // 1440x770
}
@screen 3xl {
min-height: 963px; // maintains 1440x770 aspect ratio
}
input::placeholder {
@apply font-medium text-gray-dark opacity-80;
}
}
}
}
</style>

0 comments on commit 0a88c7e

Please sign in to comment.