Skip to content

Commit

Permalink
make home page connected to CMS (#632)
Browse files Browse the repository at this point in the history
* make home page connected to CMS

* make content optional

* fix story
  • Loading branch information
choden-dev authored Jul 14, 2024
1 parent 56f8139 commit 3c3fd3e
Show file tree
Hide file tree
Showing 15 changed files with 244 additions and 58 deletions.
40 changes: 37 additions & 3 deletions client/sanity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,50 @@ import { structureTool } from "sanity/structure"
import { apiVersion, dataset, projectId } from "./sanity/env"
import { schema } from "./sanity/schema"

// Define the actions that should be available for singleton documents
const singletonActions = new Set(["publish", "discardChanges", "restore"])

// Define the singleton document types
const singletonTypes = new Set(["home-page"])

export default defineConfig({
basePath: "/studio",
projectId,
dataset,
// Add and edit the content schema in the './sanity/schema' folder
schema,
schema: {
...schema,
templates: (templates) =>
templates.filter(({ schemaType }) => !singletonTypes.has(schemaType))
},
plugins: [
structureTool(),
structureTool({
structure: (S) =>
S.list()
.title("Content")
.items([
// Our singleton type has a list item with a custom child
S.listItem().title("Home Page").id("home-page").child(
// Instead of rendering a list of documents, we render a single
// document, specifying the `documentId` manually to ensure
// that we're editing the single instance of the document
S.document().schemaType("home-page").documentId("home-page")
),

// Regular document types
S.documentTypeListItem("about-item").title("About Item")
])
}),
// Vision is a tool that lets you query your content with GROQ in the studio
// https://www.sanity.io/docs/the-vision-plugin
visionTool({ defaultApiVersion: apiVersion })
]
],
document: {
// For singleton types, filter out actions that are not explicitly included
// in the `singletonActions` list defined above
actions: (input, context) =>
singletonTypes.has(context.schemaType)
? input.filter(({ action }) => action && singletonActions.has(action))
: input
}
})
3 changes: 2 additions & 1 deletion client/sanity/schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AboutItemSchema } from "@/models/sanity/AboutItem/Schema"
import { HomePageSchema } from "@/models/sanity/HomePage/Schema"
import { type SchemaTypeDefinition } from "sanity"

export const schema: { types: SchemaTypeDefinition[] } = {
types: [AboutItemSchema]
types: [AboutItemSchema, HomePageSchema]
}
2 changes: 1 addition & 1 deletion client/src/app/Home.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ const meta: Meta<typeof HomeComponent> = {
export default meta

export const DefaultHomePage = () => {
return <HomeComponent data={[]} />
return <HomeComponent pricingData={[]} />
}
28 changes: 22 additions & 6 deletions client/src/app/HomeComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HomePage } from "@/models/sanity/HomePage/Utils"
import AboutSection from "./sections/AboutSection"
import BenefitSection from "./sections/BenefitSection"
import LandingSection from "./sections/LandingSection"
Expand All @@ -8,20 +9,35 @@ import { Footer } from "@/components/generic/Footer/Footer"
import { Prices } from "@/services/AppData/AppDataService"

export type HomeProps = {
data: Prices[]
pricingData: Prices[]
content?: HomePage
}

/**
* @deprecated do not use, use `WrappedHomeComponent` instead
*/
const HomeComponent = ({ data }: HomeProps) => {
const HomeComponent = ({ pricingData, content }: HomeProps) => {
return (
<>
<div className="">
<div>
<LandingSection />
<AboutSection />
<BenefitSection benefits={benefits} />
<PricingSection pricings={data} bannerContent={pricingBannerContent} />
<AboutSection
title={content?.introduction.title}
subheading={content?.introduction.subheading}
description={content?.introduction.description}
/>
<BenefitSection
benefits={
content?.benefitCards?.map((benefit) => {
return { text: benefit.description, image: benefit.imageUrl }
}) || benefits
}
/>
<PricingSection
note={content?.pricing?.discount}
pricings={pricingData}
bannerContent={pricingBannerContent}
/>
</div>
<div className="pt-14">
<Footer />
Expand Down
14 changes: 10 additions & 4 deletions client/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import AppDataService, { Prices } from "@/services/AppData/AppDataService"
import HomeComponent from "./HomeComponent"
import { sanityQuery } from "../../sanity/lib/utils"
import { HOME_PAGE_GROQ_QUERY, HomePage } from "@/models/sanity/HomePage/Utils"

const Home = async () => {
let data: Prices[]
let pricingData: Prices[]
try {
data = await AppDataService.getMembershipPricingDetails()
pricingData = await AppDataService.getMembershipPricingDetails()
} catch (e) {
data = []
pricingData = []
}

const [content] = await sanityQuery<HomePage[]>(HOME_PAGE_GROQ_QUERY)
console.log(content)

return (
<>
<HomeComponent data={data} />
<HomeComponent pricingData={pricingData} content={content} />
</>
)
}
Expand Down
32 changes: 20 additions & 12 deletions client/src/app/sections/AboutSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
const AboutSection = () => (
interface IAboutSection {
title?: string
description?: string
subheading?: string
}

const DEFAULT_TITLE = "Get ready for the best year of your life!" as const
const DEFAULT_SUBHEADING =
"The University of Auckland Snowsports Club is back again for another banging year, and it's time to lock in your membership for 2024!" as const
const DEFAULT_DESCRIPTION =
"Whether you're new to the club or an old fart coming back for more, we can't wait to see your pretty face for a year of sending and shredding on and off the slopes!" as const

const AboutSection = ({
title = DEFAULT_TITLE,
subheading = DEFAULT_SUBHEADING,
description = DEFAULT_DESCRIPTION
}: IAboutSection) => (
<section id="about">
<div
className="bg-home-about-image relative
Expand All @@ -10,18 +26,10 @@ const AboutSection = () => (
<div className="grid gap-10 lg:grid-cols-2">
<div className="bg-gray-1 pointer-events-none absolute -z-20 h-screen w-full opacity-20" />
<div className="text-dark-blue-100 flex flex-col gap-6 text-center lg:max-w-[450px] lg:text-left">
<h2 className="italic">Get ready for the best year of your life!</h2>
<h2 className="italic">{title}</h2>
<div>
<h4>
The University of Auckland Snowsports Club is back again for
another banging year, and it's time to lock in your membership for
2024!
</h4>
<p className="mt-2">
Whether you're new to the club or an old fart coming back for
more, we can't wait to see your pretty face for a year of sending
and shredding on and off the slopes!
</p>
<h4>{subheading}</h4>
<p className="mt-2">{description}</p>
</div>
</div>
<div className="flex justify-center lg:justify-end">
Expand Down
4 changes: 2 additions & 2 deletions client/src/app/sections/BenefitSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ const BenefitSection = ({ benefits }: IBenefitSection) => (
<HomeSectionHeading text="Member Benefits" />
<div className="mt-3 grid grid-cols-1 items-center gap-7 lg:grid-cols-2">
{benefits.map((benefit) => {
const { text, icon } = benefit
const { text, image } = benefit
return (
<span key={text} className="flex h-full w-full justify-center">
<MemberBenefitCard Icon={icon} text={text} />
<MemberBenefitCard imageSrc={image} text={text} />
</span>
)
})}
Expand Down
16 changes: 11 additions & 5 deletions client/src/app/sections/LandingSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import Facebook from "@/assets/icons/FacebookBlue.svg"
import Instagram from "@/assets/icons/InstagramBlue.svg"
import Link from "next/link"

const LandingSection = () => (
interface ILandingSection {
headline?: string
}

const DEFAULT_HEADLINE =
"The largest sports club on campus, and the cheapest membership on Mt Ruapehu!"

const LandingSection = ({ headline = DEFAULT_HEADLINE }: ILandingSection) => (
<section>
<div
className="bg-home-ski-image relative flex
Expand All @@ -13,15 +20,14 @@ const LandingSection = () => (
overflow-hidden bg-cover bg-top bg-no-repeat"
>
<div className="bg-gray-1 pointer-events-none absolute -z-20 h-screen opacity-90" />
<div className="z-10 mx-6 flex flex-col gap-10 text-center lg:gap-20">
<div className="z-10 mx-6 flex flex-col gap-10 text-center lg:gap-16">
<div className="flex w-full">
<UASCHeader className=" pointer-events-none w-full" />
</div>

<div className="flex items-center gap-6">
<p className="text-dark-blue-100 font-small tracking-tighter md:text-3xl">
The largest sports club on campus, and <br /> the cheapest
membership on Mt Ruapehu!
<p className="text-dark-blue-100 font-small max-w-[520px] tracking-tighter md:text-3xl">
{headline}
</p>

<span>
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/sections/PricingSection.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const meta: Meta<typeof PricingSection> = {

export default meta

export const DefaultPricingSection = ({ data }: HomeProps) => {
export const DefaultPricingSection = ({ pricingData: data }: HomeProps) => {
return (
<PricingSection
pricings={data}
Expand Down
16 changes: 4 additions & 12 deletions client/src/app/sections/utils/Benefits.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
import { Benefit } from "@/components/utils/types"
import LodgeIcon from "@/assets/icons/mountain_lodge.svg"
import TicketIcon from "@/assets/icons/ticket.svg"
import PriceTagIcon from "@/assets/icons/price_tag.svg"
import HandSignIcon from "@/assets/icons/hand_sign.svg"

export const benefits: Benefit[] = [
{
text: "Book our cozy ski lodge on the Whakapapa skifield!",
icon: LodgeIcon
text: "Book our cozy ski lodge on the Whakapapa skifield!"
},
{
text: "Access cheaper tickets and priority admission to our sell-out events!",
icon: TicketIcon
text: "Access cheaper tickets and priority admission to our sell-out events!"
},
{
text: "Meet lifelong friends you can send it with on and off the mountain!",
icon: HandSignIcon
text: "Meet lifelong friends you can send it with on and off the mountain!"
},
{
text: "Enjoy a range of discounts with our sponsors such as Snowcentre, Pit Viper and many more!",
icon: PriceTagIcon
text: "Enjoy a range of discounts with our sponsors such as Snowcentre, Pit Viper and many more!"
}
]
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Meta, StoryObj } from "@storybook/react"
import TestIcon from "@/assets/icons/bell.svg"

import Card from "./MemberBenefitCard"
const meta: Meta<typeof Card> = {
Expand All @@ -23,7 +22,7 @@ export const BenefitCard1: Story = {
args: {
variant: "default",
text: "Book our cozy ski lodge on the Whakapapa skifield",
Icon: TestIcon
imageSrc: "public/images/AboutBackgroundImage.png"
}
}

Expand All @@ -32,6 +31,6 @@ export const BenefitCard2: Story = {
args: {
variant: "default",
text: "Default Card Variant",
Icon: TestIcon
imageSrc: "public/images/AboutBackgroundImage.png"
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { SvgImport } from "@/components/utils/types"
import Image from "next/image"

type cardVariants = "default"

interface ICardProps {
/**
* The src of the icon
*/
Icon?: SvgImport
imageSrc?: string
/**
* What the card should say
*/
Expand All @@ -15,7 +16,7 @@ interface ICardProps {

type props = ICardProps

const BenefitCard = ({ text, Icon }: props) => {
const BenefitCard = ({ text, imageSrc }: props) => {
return (
<div
className="border-light-blue-100
Expand All @@ -27,7 +28,14 @@ const BenefitCard = ({ text, Icon }: props) => {
{text}
</h3>
<span className=" -ml-7 w-[138px] min-w-[138px] opacity-15">
{Icon && <Icon className="fill-light-blue-100" />}
{imageSrc && (
<Image
width={1000}
height={1000}
src={imageSrc}
alt={`corresponding image for ${text}`}
/>
)}
</span>
</div>
)
Expand All @@ -38,12 +46,12 @@ const BenefitCard = ({ text, Icon }: props) => {
* Usage: pass in the SVG imported using the `import Icon from 'path/icon.svg '` syntax
*
*/
const Card = ({ Icon: SvgIcon, text, variant }: props) => {
const Card = ({ imageSrc, text, variant }: props) => {
switch (variant) {
case "default":
return <BenefitCard Icon={SvgIcon} text={text} />
return <BenefitCard imageSrc={imageSrc} text={text} />
}
return <BenefitCard Icon={SvgIcon} text={text} />
return <BenefitCard imageSrc={imageSrc} text={text} />
}

export default Card
2 changes: 1 addition & 1 deletion client/src/components/utils/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type SvgImport = FC<SVGProps<SVGElement>>
*/
export type Benefit = {
text: string
icon?: SvgImport
image?: string
}

/**
Expand Down
Loading

0 comments on commit 3c3fd3e

Please sign in to comment.