diff --git a/pages/index.tsx b/pages/index.tsx index 363e4134..d1041eea 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,3 +1,4 @@ + import SEO from "../next-seo.config"; import {DefaultSeo} from "next-seo"; import Footer from '../src/components/global/Footer/Footer'; diff --git a/public/images/landing/landingcover.jpg b/public/images/landing/landingcover.jpg new file mode 100644 index 00000000..f29f8a85 Binary files /dev/null and b/public/images/landing/landingcover.jpg differ diff --git a/public/images/landing/landingcover2.jpg b/public/images/landing/landingcover2.jpg new file mode 100644 index 00000000..a52c17ca Binary files /dev/null and b/public/images/landing/landingcover2.jpg differ diff --git a/public/images/landing/riverside-sample.jpg b/public/images/landing/riverside-sample.jpg new file mode 100644 index 00000000..61a44316 Binary files /dev/null and b/public/images/landing/riverside-sample.jpg differ diff --git a/src/components/global/Navigation/Navigation.tsx b/src/components/global/Navigation/Navigation.tsx index ade7f9b2..ba5f0e49 100644 --- a/src/components/global/Navigation/Navigation.tsx +++ b/src/components/global/Navigation/Navigation.tsx @@ -17,7 +17,7 @@ export interface ListObject { const identifyLink = (url: string) => url.indexOf(`${process.env.HOST}`); const renderLink = (obj: ListObject, opts: object) => { - const {url = undefined} = obj; + const { url = undefined } = obj; return identifyLink(url ? url : '') !== -1 ? {obj.label} @@ -28,8 +28,8 @@ const renderLink = (obj: ListObject, opts: object) => { }; const createListItem = ( - obj: ListObject, - mobile = false, + obj: ListObject, + mobile = false, ) => { const opts = {} as Options; @@ -46,7 +46,7 @@ const createListItem = ( } return ( -
  • @@ -76,15 +76,15 @@ const createListObject = ({ icon = false, children = false, target, -}: ListObject) => ({label, url, icon, children, target}); +}: ListObject) => ({ label, url, icon, children, target }); function Navigation(): JSX.Element { const navigation: Array = [ - {label: "Home", url: "/"}, - {label: "Cohorts", url: "/cohorts"}, - {label: "Blog", url: "https://www.iesd.com/#blog", target: "_blank"}, - {label: "Contact", url: "mailto:community@iesd.com", target: "_blank"}, + { label: "Home", url: "/" }, + { label: "Cohorts", url: "/cohorts" }, + { label: "Blog", url: "https://www.iesd.com/#blog", target: "_blank" }, + { label: "Contact", url: "mailto:community@iesd.com", target: "_blank" }, ].map((item) => createListObject(item)); return ( @@ -107,14 +107,14 @@ function Navigation(): JSX.Element { {/* Right portion for user */} - +
    • - +
    • { navigation.map((link) => diff --git a/src/components/landing/CourseProgramCard.tsx b/src/components/landing/CourseProgramCard.tsx new file mode 100644 index 00000000..4ac33512 --- /dev/null +++ b/src/components/landing/CourseProgramCard.tsx @@ -0,0 +1,33 @@ +import React from 'react'; + +export interface CourseProgramProps { + id: string; + title: string; + contents: string[]; + nextDay: string; + nextMonth: string; + classTimeString: string; +} + +const CourseProgramCard: React.FC> = (props) => ( +
      +
      +
      +

      {props.nextDay}

      +
      {props.nextMonth}
      +

      {props.classTimeString}

      +
      +
      +

      {props.title}

      +
        + {props.contents.map((item, index) => ( +
      • {item}
      • + ), + )} +
      +
      +
      +
      +); + +export default CourseProgramCard; diff --git a/src/components/landing/Landing.scss b/src/components/landing/Landing.scss new file mode 100644 index 00000000..19b5722d --- /dev/null +++ b/src/components/landing/Landing.scss @@ -0,0 +1,268 @@ +$m-breakpoint: 960px; +$l-breakpoint: 1200px; + +// 1440 +.landing-page { + padding: 0; + margin: 0; + + //** Top image **// + + .top-image { + width: 100%; + min-height: 300px; + } + + //** Course-Info **// + + // .course-info {} + + .course-info-top { + font-size: 46px; + font-family: "Heavy", sans-serif; + line-height: 0.7; + margin: 0; + } + + .course-info-mid { + font-size: 32px; + font-family: "Medium", sans-serif; + margin: 0; + } + + .course-info-bottom { + font-size: 14px; + font-family: "Light", sans-serif; + margin: 0; + margin-top: 18px; + } + + .course-info-section { + margin: 0; + display: flex; + flex-direction: column; + justify-content: flex-start; + padding: 24px; + } + + .course-info-description { + padding: 0; + + @media screen and (min-width: $m-breakpoint) { + transform: translate(0, -25%); + max-width: 1200px; + } + + @media screen and (min-width: $l-breakpoint) { + transform: translate(0, -50%); + max-width: 1200px; + } + } + + //** Course-Program **// + .course-program { + margin-top: 0; + margin-bottom: 48px; + max-width: 1200px; + + @media screen and (max-width: ($m-breakpoint - 1px)) { + margin-top: 64px; + margin-bottom: 64px; + } + } + + .course-program-description { + align-items: center; + } + + .course-program-label { + @media screen and (max-width: $m-breakpoint - 1px) { + margin-left: 16px; + margin-right: 16px; + } + } + + .course-program-card { + li { + cursor: pointer; + } + + .uk-slider { + @media screen and (max-width: $m-breakpoint - 1px) { + margin-left: 16px; + margin-right: 16px; + } + } + + .uk-dotnav > .uk-active > * { + background-color: $primary; + } + } + + .course-program-header { + font-size: 32px; + font-family: "Black", sans-serif; + } + + .course-program-header-detail { + font-size: 24px; + font-family: "Book", sans-serif; + } + + .course-program-date-header { + font-size: 54px; + font-family: "Heavy", sans-serif; + margin: 0; + } + + .course-program-date { + font-size: 46px; + font-family: "Book", sans-serif; + margin: 0 0 20px 0; + line-height: 0.7; + } + + .course-program-time { + font-size: 12px; + font-family: "Light", sans-serif; + margin-top: 40px; + } + + .course-program-detail { + font-size: 32px; + font-family: "Medium", sans-serif; + margin: 0 0 5px 0; + padding: 10px 10px 0 10px; + } + + .course-program-detail-list { + font-size: 14px; + padding-left: 0; + margin: 0 0 10px 10px; + } + + .course-program-detail-list > li { + font-family: "Light", sans-serif; + margin-bottom: 6px; + list-style-type: none; + + &::before { + color: $primary; + content: "\2022"; + font-size: 14px; + margin-right: 10px; + } + } + + //** Student Quote **// + + .student-quote { + font-size: 20px; + font-family: "Light", sans-serif; + max-width: 600px; + } + + .student { + font-size: 16px; + font-family: "Light", sans-serif; + } + + // ** Random Quote **// + + // .random-quote-section { + // // width: 100%; + // } + + .random-quote { + font-size: 22px; + font-family: "Light", sans-serif; + max-width: 600px; + } + + .random-author { + font-size: 22px; + font-family: "Light", sans-serif; + position: relative; + top: 65%; + } + + //** Venue **// + + .venue-body { + min-height: 300px; + padding-right: 48px; + } + + .venue-title { + font-size: 48px; + font-family: "Black", sans-serif; + } + + .venue-description { + font-size: 32px; + font-family: "Book", sans-serif; + } + + .venue-image { + min-height: 300px; + } + + .venue-street-address { + font-family: "Medium", sans-serif; + font-size: 32px; + text-align: left; + margin: 36px 0 0 0; + } + + .venue-county-state { + font-family: "Medium", sans-serif; + font-size: 32px; + text-align: left; + margin: 0 0 0 0; + } + + // ** Program ** // + + .program-body { + min-height: 300px; + // padding-left: 48px; + } + + .program-title { + font-size: 48px; + font-family: "Black", sans-serif; + } + // Help with alignment + .program-description { + font-size: 32px; + font-family: "Book", sans-serif; + } + + .request-button { + font-size: 22px; + font-family: "Book", sans-serif; + + &:hover { + background-color: $tertiary; + } + } + + .program-image { + min-height: 300px; + } + + .footer { + text-align: center; + text-align: -webkit-center; + } + + .copywrite { + font-size: 10px; + margin: 20px 0 0 0; + } + + .footer-description { + font-size: 10px; + margin: 0 0 20px 0; + } +} diff --git a/src/components/landing/Landing.stories.tsx b/src/components/landing/Landing.stories.tsx new file mode 100644 index 00000000..ccaa15d4 --- /dev/null +++ b/src/components/landing/Landing.stories.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import {action} from "@storybook/addon-actions"; +import Landing from '../landing/Landing'; +import {CourseProgramProps} from './CourseProgramCard'; + +export default { + title: "Landing Page", + decorators: [], + excludeStories: /.*Data$/, +}; + +const coursesData: CourseProgramProps[] = [ + { + id: "1", + title: "React Fundamentals", + nextDay: "24th", + nextMonth: "June", + classTimeString: "Every Saturday. 1:00 PM - 3:00 PM", + contents: [ + "Basics of React", + "Breakdown of the library", + "Creating web apps with the library", + ], + }, + { + id: "2", + title: "GraphQL", + nextDay: "23th", + nextMonth: "June", + classTimeString: "Every Friday. 3:00 PM - 5:00 PM", + contents: [ + "Understanding queries", + "Creating a GraphQL Server", + "Client-side libaries", + ], + }, + { + id: "3", + title: "Databases", + nextDay: "22th", + nextMonth: "June", + classTimeString: "Every Thursday. 7:00 PM - 9:00 PM", + contents: [ + "SQL Training", + "NoSQL vs SQL", + "Cloud-managed databases", + ], + }, +]; + +const landingDefaultData = { + coverImage: "/images/landing/landingcover.jpg", + venueImage: "/images/landing/riverside-sample.jpg", + programImage: "/images/spark.png", + cohortInfo: { + startDay: "15th", + startMonth: "April", + durationWeeks: 10, + classTimeString: "Every Saturday. 12:00 PM - 3:00 PM", + seats: 16, + }, + courses: coursesData, + studentQuote: "This program changed my life. Oh em gee. The instructor is amazing and the students are all passionate.", + studentQuoteAuthor: "Cutie Pie", + venueDescription: "Our program will take place at one of the fastest growing incubators in the city of Riverside. It can host large meetings, be used as a co-hosting space, and is at the center of the bustling city.", + venueAddress: { + street1: "3499 Tenth St.", + city: "Riverside", + state: "CA", + zip: "92501", + }, + programDescription: "Spark program is a community driven learning program that provides students a working set of skills to get started building useful applications. Our courses are realistically designed and we make no false promises.", + inspirationalQuote: "Education is the passport to the future, for tomorrow belongs to those who prepare for it today.", + inspirationalQuoteAuthor: "Malcom X", +}; + +const actionsData = { + onCourseSelected: action("onCourseSelected"), + onInformationRequested: action("onInformationRequested"), +}; + +export const DefaultLandingPage = () => { + return ; +}; diff --git a/src/components/landing/Landing.tsx b/src/components/landing/Landing.tsx new file mode 100644 index 00000000..482121c6 --- /dev/null +++ b/src/components/landing/Landing.tsx @@ -0,0 +1,159 @@ +import React from 'react'; +import './Landing.scss'; +import CourseProgramCard, {CourseProgramProps} from './CourseProgramCard'; + +export interface LandingProps { + coverImage: string; + venueImage: string; + programImage: string; + cohortInfo: { + startDay: string; + startMonth: string; + durationWeeks: number; + classTimeString: string; + seats: number; + }; + courses: CourseProgramProps[]; + studentQuote: string; + studentQuoteAuthor: string; + venueDescription: string; + venueAddress: { + street1: string; + street2?: string; + city: string; + state: string; + zip: string; + }; + programDescription: string; + inspirationalQuote: string; + inspirationalQuoteAuthor: string; + onCourseSelected: (id: string) => void; + onInformationRequested: () => void; +} + + +const Landing: React.FC = (props) => { + return ( +
      + {/* top background image */} +
      + +
      + {/* course info */} +
      +
      +
      +
      +

      {props.cohortInfo.startDay}

      +
      {props.cohortInfo.startMonth.toLowerCase()}
      +

      Start date for next cohort.

      +
      +
      +

      {props.cohortInfo.durationWeeks}

      +
      weeks
      +

      {props.cohortInfo.classTimeString}

      +
      +
      +

      {props.cohortInfo.seats}

      +
      seats
      +

      Limited number of seats

      +
      +
      +

      100%

      +
      scholarships
      +

      Apply for a full scholoarship.

      +
      +
      +
      +
      + + {/* course program */} +
      + {/* course program description */} +
      +
      +

      Course Program

      +

      Learn more about the details of our upcoming programs.

      +
      +
      +
      +
      +
        + {props.courses.map((course) => ( +
      • props.onCourseSelected(course.id)}> + +
      • ) )} +
      + + +
      +
        +
        +
        +
        +
        + + {/* Student quote || or none?? */} + +
        +
        +

        "{props.studentQuote}"

        +

        -{props.studentQuoteAuthor}

        +
        +
        + + + {/* Venue */} +
        + {/* Background image left */} +
        + Venue Image +
        + + {/* Venue description right */} + +
        +

        Venue

        +

        {props.venueDescription}

        +

        {props.venueAddress.street1}

        + {props.venueAddress.street2 &&

        {props.venueAddress.street2}

        } +

        {props.venueAddress.city}, {props.venueAddress.state} {props.venueAddress.zip}

        +
        + +
        + {/* Random quote */} + +
        +

        {props.inspirationalQuote}" - {props.inspirationalQuoteAuthor}

        +
        + + + {/* Program */} +
        +
        + {/* Program description left */} +
        +

        Program

        +

        {props.programDescription}

        + +
        +
        + {/* Background image right */} +
        + Program Image +
        +
        + + {/* footer */} +
        +

        © 2020 Spark.

        +

        An open source LMS project

        +
        +
        + ); +}; + +export default Landing; diff --git a/src/components/layouts/DashboardLayout.scss b/src/components/layouts/DashboardLayout.scss old mode 100644 new mode 100755 diff --git a/src/components/layouts/DashboardLayout.tsx b/src/components/layouts/DashboardLayout.tsx old mode 100644 new mode 100755 index f187aea6..b772bfd9 --- a/src/components/layouts/DashboardLayout.tsx +++ b/src/components/layouts/DashboardLayout.tsx @@ -1,18 +1,18 @@ -import {useContext} from 'react'; -import {useRouter} from 'next/router'; -import {Context, SidebarOptions} from '../../context'; -import {DefaultSeo} from "next-seo"; +import { useContext } from 'react'; +import { useRouter } from 'next/router'; +import { Context, SidebarOptions } from '../../context'; +import { DefaultSeo } from "next-seo"; import SEO from "../../../next-seo.config"; import Sidebar from '../../components/global/Sidebar/Sidebar'; import Navigation from '../../components/global/Navigation/Navigation'; import "./DashboardLayout.scss"; -const Dashboard: React.FC = function(props) { +const Dashboard: React.FC = function (props) { const context = useContext(Context); const router = useRouter(); - const {user, sidebarIsOpen} = context; - const {children} = props; - const {account, main} = SidebarOptions; // TODO: add ability to save data into DB and retrieve for menu generaetion + const { user, sidebarIsOpen } = context; + const { children } = props; + const { account, main } = SidebarOptions; // TODO: add ability to save data into DB and retrieve for menu generaetion const onNavigate = (path: string) => { context.setContextProperty({ @@ -29,7 +29,7 @@ const Dashboard: React.FC = function(props) { // TODO: Create system to pull contents of correct panel based on context. const menuToggleIcon = sidebarIsOpen ? - null: ( + null : (
        handleOpenSidebar()} @@ -44,7 +44,7 @@ const Dashboard: React.FC = function(props) { return (
        - + {/* // TODO: Need to make it so we just need to call - low priority. */}