-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pull sanity data for curated instructor pages #602
Conversation
This pull request is being automatically deployed with Vercel (learn more). egghead-next-storybook – ./🔍 Inspect: https://vercel.com/eggheadio/egghead-next-storybook/5dNQhpbxRvPvE1ot9y2MRDfN8zC5 egghead-io-nextjs – ./🔍 Inspect: https://vercel.com/eggheadio/egghead-io-nextjs/6kou3xL2pFJtvSMwTuZBECJWEbCB |
src/components/search/index.tsx
Outdated
<InstructorCuratedPage | ||
instructor={instructor} | ||
sanityInstructor={sanityInstructor} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass sanity data down
@@ -14,6 +15,7 @@ const InstructorsIndex: any = { | |||
'flavio-corpa': SearchFlavioCorpa, | |||
'hiro-nishimura': SearchHirokoNishimura, | |||
'chris-biscardi': SearchChrisBiscardi, | |||
'stephanie-eckles': SearchStephanieEckles, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add stephanie to the instructors index for curated pages
<SearchInstructorEssential | ||
instructor={combinedInstructor} | ||
CTAComponent={ | ||
<CssFormStyling | ||
resource={primaryCourse} | ||
location="Stephanie Eckles instructor page" | ||
/> | ||
} | ||
/> | ||
<section className="grid grid-cols-4 gap-3 -mt-10 mb-10 pb-10 xl:px-0 px-5 max-w-screen-xl mx-auto dark:bg-gray-900 w-full"> | ||
<ProjectStack className="col-span-1" data={projects.resources} /> | ||
<div className="col-span-3 grid grid-cols-2 gap-3"> | ||
<CardHorizontal className="col-span-2" resource={secondCourse} /> | ||
<CardHorizontal className="col-span-1" resource={thirdCourse} /> | ||
<CardHorizontal className="col-span-1" resource={fourthCourse} /> | ||
</div> | ||
</section> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
display courses and projects on page
export const stephanieEcklesQuery = groq`*[_type == 'resource' && slug.current == "stephanie-eckles-landing-page"][0]{ | ||
'projects': resources[slug.current == 'instructor-landing-page-projects'][0]{ | ||
resources[]{ | ||
title, | ||
'path': url, | ||
description, | ||
image | ||
} | ||
}, | ||
'courses': resources[slug.current == 'instructor-landing-page-featured-courses'][0]{ | ||
resources[]->{ | ||
title, | ||
'description': summary, | ||
path, | ||
byline, | ||
image, | ||
'background': images[label == 'feature-card-background'][0].url, | ||
'instructor': collaborators[]->[role == 'instructor'][0]{ | ||
'name': person->.name | ||
}, | ||
} | ||
}, | ||
}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sanity query
|
||
const sanityInstructorHash = { | ||
'stephanie-eckles': stephanieEcklesQuery, | ||
} | ||
|
||
type SelectedInstructor = keyof typeof sanityInstructorHash | ||
|
||
const canLoadSanityInstructor = ( | ||
selectedInstructor: string, | ||
): selectedInstructor is SelectedInstructor => { | ||
const keyNames = Object.keys(sanityInstructorHash) | ||
|
||
return keyNames.includes(selectedInstructor) | ||
} | ||
|
||
export const loadSanityInstructor = async (selectedInstructor: string) => { | ||
if (!canLoadSanityInstructor(selectedInstructor)) return | ||
|
||
const query = sanityInstructorHash[selectedInstructor] | ||
if (!query) return | ||
|
||
return await sanityClient.fetch(query) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@theianjones helped me implement this.
loadSanityInstructor
uses a type guard (canLoadSanityInstructor
) to check that the instructor slug (the one that will be passed in via getServerSideProps
) is present in the defined sanityInstructorHash
as a key. If it is, that key is associated with the query that it will call.
This makes sure that we are only querying for instructor data on the pages that we want to load sanity data onto.
src/pages/q/[[...all]].tsx
Outdated
try { | ||
initialInstructor = await loadInstructor(instructorSlug) | ||
|
||
sanityInstructor = await loadSanityInstructor(instructorSlug) | ||
} catch (error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an instructor filter is selected we will load sanity data (if it passes the type guard)
src/components/search/index.tsx
Outdated
@@ -34,6 +34,7 @@ type SearchProps = { | |||
searchClient?: any | |||
searchState?: any | |||
instructor?: any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this stands out to me. I do t like “sanity” as special data. could we merge this into a si file “instructor” object so it’s “just an instructor” and then display data based on the shape of instructor and the available properties
instructor: any | ||
sanityInstructor: any | ||
}) { | ||
const combinedInstructor = {...instructor} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could actually be combined at a higher level
@@ -211,6 +215,8 @@ export const getServerSideProps: GetServerSideProps = async function ({ | |||
) | |||
try { | |||
initialInstructor = await loadInstructor(instructorSlug) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here’s where I’d consider a single “load instructor” that loads from all sources
sanityInstructor = await loadSanityInstructor(instructorSlug) | ||
|
||
initialInstructor = { | ||
...initialInstructor, | ||
...sanityInstructor, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the data is being overridden but it makes sense to me that sanity data would take precedence over the initialInstructor
data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this pattern makes a lot of sense so we don't have two+ data sources at the component, we just bring it together at the server level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we are using a stale-while-revalidate
cache header, it should be performant!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, it was also super easy to refactor
<section className="grid grid-cols-4 gap-3 -mt-10 mb-10 pb-10 xl:px-0 px-5 max-w-screen-xl mx-auto dark:bg-gray-900 w-full"> | ||
<ProjectStack className="col-span-1" data={projects.resources} /> | ||
<div className="col-span-3 grid grid-cols-2 gap-3"> | ||
<CardHorizontal className="col-span-2" resource={secondCourse} /> | ||
<CardHorizontal className="col-span-1" resource={thirdCourse} /> | ||
<CardHorizontal className="col-span-1" resource={fourthCourse} /> | ||
</div> | ||
</section> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
</div> | ||
</a> | ||
</Link> | ||
)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -36,3 +39,26 @@ export async function loadInstructor(slug: string) { | |||
|
|||
return instructor | |||
} | |||
|
|||
const sanityInstructorHash = { | |||
'stephanie-eckles': stephanieEcklesQuery, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this pattern!
All of our curated instructor data is currently hard coded on the front end.
This loads instructor data from sanity and passes it into curated instructor pages as
sanityInstructor
One note, the linter was going ham on all the files so I committed with
no-verify
. Not sure what would have changed there but would like someone to run this on their machine.