diff --git a/components/sections/home-page/features/StudentsFeatures.tsx b/components/sections/home-page/features/StudentsFeatures.tsx new file mode 100644 index 000000000..ba6ca1b5b --- /dev/null +++ b/components/sections/home-page/features/StudentsFeatures.tsx @@ -0,0 +1,97 @@ +import { SanityStudentsPage } from "../../../../types/schema"; +import { Heading } from '../../../common/text' +import ContainerWithLine from '../../../common/ContainerWithLine' +import { motion } from 'framer-motion' +import { useInView } from 'react-intersection-observer' +import type { SanityImageAsset, SanityImageCrop, SanityImageHotspot, SanityReference } from "sanity-codegen"; + +import EndingLine from "../../../common/EndingLine"; +import SectionWrapper from "../../../common/layout/SectionWrapper"; + +type TeamsFeaturesProps = { + features: SanityStudentsPage['features']; +}; + +export default function StudentsFeatures({ features } : TeamsFeaturesProps) { + return ( + + { features!.map((feature) => ) } + + + ); +} + +function StudentFeature({ feature } : { feature : { + title?: string, + heading?: string, + description?: string, + image?: { + _type: 'image' + asset: SanityReference + crop?: SanityImageCrop + hotspot?: SanityImageHotspot + } +}}) { + const { title, heading, description, image } = feature!; + const [ refIcon, iconInView ] = useInView(); + + // text animation + const initPosY = 5; + const posY = iconInView ? 0 : initPosY; + + return ( + +
+
+
+
+ + + +
+

+ {title} +

+ + {heading} + +
+
+
+ +
+ +

+ {description} +

+
+
+ + + + +
+
+
+
+ ); +} diff --git a/components/sections/home-page/features/TeamsFeatures.tsx b/components/sections/home-page/features/TeamsFeatures.tsx index f9e649277..55681d6a0 100644 --- a/components/sections/home-page/features/TeamsFeatures.tsx +++ b/components/sections/home-page/features/TeamsFeatures.tsx @@ -1,5 +1,5 @@ import { SanityTeamsPage } from "../../../../types/schema"; -import { Heading, Typography } from '../../../common/text' +import { Heading } from '../../../common/text' import ContainerWithLine from '../../../common/ContainerWithLine' import { motion } from 'framer-motion' import { useInView } from 'react-intersection-observer' @@ -8,7 +8,6 @@ import type { SanityImageAsset, SanityImageCrop, SanityImageHotspot, SanityRefer import EndingLine from "../../../common/EndingLine"; import SectionWrapper from "../../../common/layout/SectionWrapper"; import DecoratedText from "../../../common/text/utils/DecoratedText"; -import Feature from "./Feature"; type TeamsFeaturesProps = { topUseCase: SanityTeamsPage['topUseCase']; @@ -28,7 +27,6 @@ export default function TeamsFeatures({ topUseCase, features } : TeamsFeaturesPr function TopUseCase({ topUseCase } : { topUseCase: SanityTeamsPage['topUseCase']}) { const { heading, image, subsections } = topUseCase!; const [ refIcon, iconInView ] = useInView(); - const [ refImage, imageInView ] = useInView(); // text animation const initPosY = 5; @@ -108,7 +106,6 @@ function TeamFeature({ feature } : { feature : { }}) { const { title, heading, description, image } = feature!; const [ refIcon, iconInView ] = useInView(); - const [ refImage, imageInView ] = useInView(); // text animation const initPosY = 5; diff --git a/components/sections/navigation/DesktopNavigation.tsx b/components/sections/navigation/DesktopNavigation.tsx index 7ee5f8859..53b220eda 100644 --- a/components/sections/navigation/DesktopNavigation.tsx +++ b/components/sections/navigation/DesktopNavigation.tsx @@ -25,11 +25,16 @@ const useCases = [ title: 'Maintainers', description: 'Grow and celebrate your open source community.', }, - { - link: '/contributors', - title: 'Contributors', - description: 'Start the path to your next contribution.', + { + link: "/contributors", + title: "Contributors", + description: "Start the path to your next contribution." }, + { + link: "/students", + title: "Students", + description: "Follow your passion and make your mark." + } ] const DesktopNavigation: FC = ({ diff --git a/components/sections/navigation/DropdownMenu.tsx b/components/sections/navigation/DropdownMenu.tsx index 0318f9d3f..b3f386c4b 100644 --- a/components/sections/navigation/DropdownMenu.tsx +++ b/components/sections/navigation/DropdownMenu.tsx @@ -26,7 +26,7 @@ const DropdownMenu = ({ menuItems, className, label }: DropdownMenuProps) => { Menu - +

MENU diff --git a/components/sections/navigation/MobileNavigation.tsx b/components/sections/navigation/MobileNavigation.tsx index 60726b38e..c01fe10b4 100644 --- a/components/sections/navigation/MobileNavigation.tsx +++ b/components/sections/navigation/MobileNavigation.tsx @@ -14,6 +14,7 @@ const useCases = [ { label: "Teams", url: "/teams" }, { label: "Maintainers", url: "/maintainers" }, { label: "Contributors", url: "/contributors" }, + { label: "Students", url: "/students" }, ] const MobileNavigation: FC = ({ diff --git a/lib/sanity.ts b/lib/sanity.ts index eac6d402b..16e81b82e 100644 --- a/lib/sanity.ts +++ b/lib/sanity.ts @@ -123,6 +123,32 @@ export const getTeamsPageData: () => Promise = async () => { return teamsPageData; } +export const getStudentsPageData: () => Promise = async () => { + const teamsPageData = await client.fetch( + ` + *[_type == "studentsPage"][0] { + ..., + hero { + ..., + "image": image.asset->url, + users[] { + ..., + "name": *[ _type == "user" && _id == ^._ref][0].name, + "website": *[ _type == "user" && _id == ^._ref][0].website, + "logo": *[ _type == "user" && _id == ^._ref][0].logo.asset->url, + } + }, + features[] { + ..., + "image": image.asset->url, + }, + } + ` + ); + console.log('fetch', { teamsPageData }); + return teamsPageData; +} + export const getSEOData: () => Promise = async () => { const seoData = await client.fetch( ` diff --git a/pages/students/index.tsx b/pages/students/index.tsx new file mode 100644 index 000000000..9878e3880 --- /dev/null +++ b/pages/students/index.tsx @@ -0,0 +1,72 @@ +import React, { FC } from 'react' +import PageLayout from '../../components/common/layout/PageLayout' +import { getAllBlogs, getCommonData, getFeaturedBlogs, getStudentsPageData } from '../../lib/sanity' +import Background from '../../components/sections/about/Background' +import { SanityBlog, SanityFooter, SanityNavigation, SanitySeo, SanityStudentsPage, SanityUser } from '../../types/schema' +import Blogs from '../../components/sections/home-page/blogs/Blogs' +import Hero from '../../components/sections/home-page/Hero' +import Logos from '../../components/sections/home-page/Logos' +import CTA from '../../components/sections/teams/CTA' +import StudentsFeatures from "../../components/sections/home-page/features/StudentsFeatures"; + +interface Props { + data: { + commonData: { + navigationLinks: SanityNavigation[] + seoData: SanitySeo + footer: SanityFooter[] + } + studentsPageData: SanityStudentsPage + blogs: SanityBlog[] + featuredBlogs: SanityBlog[] + } +} + +export async function getStaticProps() { + const [commonData, studentsPageData, featuredBlogs, blogs] = await Promise.all([ + getCommonData(), + getStudentsPageData(), + getFeaturedBlogs(), + getAllBlogs(), + ]) + + const data = { commonData, studentsPageData, featuredBlogs, blogs } + + return { + props: { + data, + }, + revalidate: 30, + } +} + +const Index: FC = ({ + data: { commonData, studentsPageData, blogs, featuredBlogs }, +}) => { + const displayBlogs = [...blogs, ...featuredBlogs].sort( + (a, b) => +new Date(b._createdAt) - +new Date(a._createdAt) + ) + + return ( + + + + + + + + ) +} + +export default Index; diff --git a/sanity/deskStructure.js b/sanity/deskStructure.js index 535e245b7..533585734 100644 --- a/sanity/deskStructure.js +++ b/sanity/deskStructure.js @@ -1,6 +1,6 @@ // /deskStructure.js import S from '@sanity/desk-tool/structure-builder' -import { FaMoneyCheckAlt, FaInfoCircle, FaHome } from 'react-icons/fa' +import { FaMoneyCheckAlt, FaInfoCircle, FaHome, FaGraduationCap } from 'react-icons/fa' import { VscOrganization } from "react-icons/vsc"; export default () => @@ -31,6 +31,16 @@ export default () => .title("Teams Page") ), + S.listItem() + .title("Students Page") + .icon(FaGraduationCap) + .child( + S.document() + .schemaType("studentsPage") + .documentId("studentsPage") + .title("Students Page") + ), + S.listItem() .title("Pricing Page") .icon(FaMoneyCheckAlt) diff --git a/sanity/schemas/pages/studentsPage.js b/sanity/schemas/pages/studentsPage.js new file mode 100644 index 000000000..f7c535d8c --- /dev/null +++ b/sanity/schemas/pages/studentsPage.js @@ -0,0 +1,176 @@ +export default { + title: 'Students Page', + name: 'studentsPage', + type: 'object', + fields: [ + { + title: 'Hero', + name: 'hero', + type: 'object', + description: 'All information here will be displayed in the hero section of the home page.', + fields: [ + { + title: 'Title', + name: 'title', + type: 'string', + description: 'Title will be displayed in smaller font size on top the heading.', + }, + { + title: 'Heading', + name: 'heading', + type: 'string', + description: 'Heading will be displayed in larger font size below the title.', + }, + { + title: 'Description', + name: 'description', + type: 'text', + description: 'The summary of the Open Sauced should be written here.', + }, + { + title: 'CTA', + name: 'cta', + type: 'array', + of: [ + { + type: 'object', + description: 'This CTA will be displayed only on hero section.', + fields: [ + { + title: 'CTA Label', + name: 'ctaLabel', + type: 'string', + }, + { + title: 'CTA Link', + name: 'ctaLink', + type: 'string', + } + ] + } + ] + + }, + { + title: 'Hero Image', + name: 'image', + type: 'image', + description: 'This image will be displayed on the right side of the hero section.', + }, + { + title: 'Users', + name: 'users', + type: 'array', + of: [ + { + type: 'reference', + to: [ + { + type: 'user', + } + ] + } + ] + } + ] + }, + { + title: 'Features', + name: 'features', + type: 'array', + description: 'All the features of Open Sauced should be displayed here.', + of: [ + { + title: 'Feature', + name: 'feature', + type: 'object', + fields: [ + { + title: 'Title', + name: 'title', + type: 'string', + description: 'Title will be displayed in smaller font size on top the heading.', + }, + { + title: 'heading', + name: 'heading', + type: 'string', + description: 'Heading will be displayed in larger font size bellow the title.', + }, + { + title: 'description', + name: 'description', + type: 'text', + }, + { + title: 'Image', + name: 'image', + type: 'image', + } + ] + } + ] + }, + { + title: 'CTA Section', + name: 'ctaSection', + type: 'object', + fields: [ + { + title: 'Heading', + name: 'heading', + type: 'string', + }, + { + title: 'Description', + name: 'description', + type: 'text', + }, + { + title: 'CTA Label', + name: 'ctaLabel', + type: 'string', + }, + { + title: 'CTA Link', + name: 'ctaLink', + type: 'string', + } + ] + }, + { + title: 'Testimonials Section', + name: 'testimonialsSection', + type: 'object', + fields: [ + { + title: 'Title', + name: 'title', + type: 'string', + description: 'Title for the testimonial section, it will be displayed in smaller font size on top the heading.', + }, + { + title: 'Heading', + name: 'heading', + type: 'string', + description: 'Heading for the testimonial section, it will be displayed in larger bellow the title font size.', + }, + { + title: 'Testimonials', + name: 'testimonials', + type: 'array', + of: [ + { + type: 'reference', + to: [ + { + type: 'testimonial', + } + ] + } + ] + } + ] + }, + ] +} diff --git a/sanity/schemas/schema.js b/sanity/schemas/schema.js index a2daa106e..3d17c99ec 100644 --- a/sanity/schemas/schema.js +++ b/sanity/schemas/schema.js @@ -21,6 +21,7 @@ import pricingPage from './pages/pricingPage' import aboutPage from './pages/aboutPage' import homePage from './pages/homePage' import teamsPage from './pages/teamsPage' +import studentsPage from './pages/studentsPage' import changelog from './changelog' import changelogCategory from './changelogCategory' @@ -48,6 +49,7 @@ export default createSchema({ aboutPage, homePage, teamsPage, + studentsPage, changelog, changelogCategory ]), diff --git a/types/schema.ts b/types/schema.ts index b9aca0838..4cd14ef98 100644 --- a/types/schema.ts +++ b/types/schema.ts @@ -1613,6 +1613,188 @@ export type SanityTeamsPage = { } } +export type SanityStudentsPage = { + _type: 'studentsPage' + /** + * Hero — `object` + * + * All information here will be displayed in the hero section of the home page. + */ + hero?: { + _type: 'hero' + /** + * Title — `string` + * + * Title will be displayed in smaller font size on top the heading. + */ + title?: string + + /** + * Heading — `string` + * + * Heading will be displayed in larger font size below the title. + */ + heading?: string + + /** + * Description — `text` + * + * The summary of the Open Sauced should be written here. + */ + description?: string + + /** + * CTA — `array` + * + * + */ + cta?: Array< + SanityKeyed<{ + /** + * CTA Label — `string` + * + * + */ + ctaLabel?: string + + /** + * CTA Link — `string` + * + * + */ + ctaLink?: string + }> + > + + /** + * Hero Image — `image` + * + * This image will be displayed on the right side of the hero section. + */ + image?: { + _type: 'image' + asset: SanityReference + crop?: SanityImageCrop + hotspot?: SanityImageHotspot + } + + /** + * Users — `array` + * + * + */ + users?: Array> + } + + /** + * Features — `array` + * + * All the features of Open Sauced should be displayed here. + */ + features?: Array< + SanityKeyed<{ + _type: 'feature' + /** + * Title — `string` + * + * Title will be displayed in smaller font size on top the heading. + */ + title?: string + + /** + * heading — `string` + * + * Heading will be displayed in larger font size bellow the title. + */ + heading?: string + + /** + * description — `text` + * + * + */ + description?: string + + /** + * Image — `image` + * + * + */ + image?: { + _type: 'image' + asset: SanityReference + crop?: SanityImageCrop + hotspot?: SanityImageHotspot + } + }> + > + + /** + * CTA Section — `object` + * + * + */ + ctaSection?: { + _type: 'ctaSection' + /** + * Heading — `string` + * + * + */ + heading?: string + + /** + * Description — `text` + * + * + */ + description?: string + + /** + * CTA Label — `string` + * + * + */ + ctaLabel?: string + + /** + * CTA Link — `string` + * + * + */ + ctaLink?: string + } + + /** + * Testimonials Section — `object` + * + * + */ + testimonialsSection?: { + _type: 'testimonialsSection' + /** + * Title — `string` + * + * Title for the testimonial section, it will be displayed in smaller font size on top the heading. + */ + title?: string + + /** + * Heading — `string` + * + * Heading for the testimonial section, it will be displayed in larger bellow the title font size. + */ + heading?: string + + /** + * Testimonials — `array` + * + * + */ + testimonials?: Array> + } +} + export type Documents = | SanityAbout | SanityUser