diff --git a/package.json b/package.json index 5a3f31ad89792964ea65f7fa957214b653b79005..28b64034a6ebd87b60f0b498f9874921e16c78b0 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "antd": "^4.16.6", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-intersection-observer": "^8.32.0", "react-scripts": "4.0.3", "sass": "^1.35.1", "web-vitals": "^1.0.1" diff --git a/src/js/components/MultiColoredText/MultiColoredText.js b/src/js/components/MultiColoredText/MultiColoredText.js index b12b35f8c9b59023aaf4a46b4d5039b5bc5f6cd1..085481fcb02a7f4555f195bfa46da5007d060c28 100644 --- a/src/js/components/MultiColoredText/MultiColoredText.js +++ b/src/js/components/MultiColoredText/MultiColoredText.js @@ -1,10 +1,9 @@ const MultiColoredText = (props) => { const {content} = props; - // content = [{text, color}] return ( <div> {content.map((part) => { - return <span style={{color: part.color}}>{part.text}</span> + return <span key={part.text} style={{color: part.color}}>{part.text}</span> }) } </div> diff --git a/src/js/components/TopBar/TopBar.js b/src/js/components/TopBar/TopBar.js new file mode 100644 index 0000000000000000000000000000000000000000..fdc32f4b35000c5430cec5bb1d16ab59aaf01c22 --- /dev/null +++ b/src/js/components/TopBar/TopBar.js @@ -0,0 +1,36 @@ +import './TopBar.module.scss'; +import TopLinks from "../TopLinks/TopLInks"; +import {Header} from "antd/lib/layout/layout"; +import {useEffect, useState} from "react"; + + +const beige = "#FDE7D3"; +const blue = "#6FACC6"; + +const TopBar = (props) => { + + const [section, setSection] = useState("landingSection"); + + + useEffect(() => { + const newSectionMap = Object.entries(props.currentSection); + if (props.currentSection !== section && newSectionMap.filter(([key, value]) => value)[0]) { + setSection(Object.fromEntries(newSectionMap.filter(([key, value]) => value))) + + } + }, [props.currentSection]); + + + const topBarStyle = { + background: section.vscodeSection || section.statsSection || section.featuresSection || section.towerSection || section.octopusSection || section.bottomSection ? blue : beige + }; + + + return ( + <Header className={"top-bar"} style={topBarStyle}> + <TopLinks section={section}/> + </Header> + ); +} + +export default TopBar; \ No newline at end of file diff --git a/src/js/components/TopBar/TopBar.module.scss b/src/js/components/TopBar/TopBar.module.scss new file mode 100644 index 0000000000000000000000000000000000000000..a5090aff96a96121bca351f7fb78d4119f774d8f --- /dev/null +++ b/src/js/components/TopBar/TopBar.module.scss @@ -0,0 +1,3 @@ +@import '../../../style/colors'; +@import '../../../style/fonts'; + diff --git a/src/js/components/TopLinks/TopLInks.js b/src/js/components/TopLinks/TopLInks.js index bdad68297e479bcfb4d43bc8d62f8be99b410170..b8d409b78e5b3ff9a0fb910dd17819e03192aee2 100644 --- a/src/js/components/TopLinks/TopLInks.js +++ b/src/js/components/TopLinks/TopLInks.js @@ -1,16 +1,53 @@ -import Link from "../Link/Link"; +import styles from "./TopLinks.module.scss"; +import {useEffect, useState} from "react"; + +const chosenSectionStyle = { + textDecoration: "none", + background: "#CB2F73", + color: "white", + padding: "5px 15px", + borderRadius: "20px", + +}; + +const TopLinks = (props) => { + + const {section} = props; -const TopLinks = () => { return ( - <div className="top-links"> - <div className="logo">DEADLOCK</div> - <Link>Un IDE complet</Link> - <Link>L'algorithme est votre mâitre mot ?</Link> - <Link>Comment suivre vos étudiants ?</Link> - <Link>Apprendre de manière ludique</Link> - <Link>Article</Link> - <Link>Contact</Link> + <div className={styles.TopLinks}> + <a href={"#LandingSection"} className={styles.Logo}> + <div className="logo">DEADLOCK</div> + </a> + <div className={styles.Links}> + <div className={styles.Link}> + <a href={"#VscodeSection"} style={section.vscodeSection ? chosenSectionStyle : {}}>Un IDE complet</a> + + </div> + <div className={styles.Link}> + <a href={"#CloudSection"} style={section.cloudSection ? chosenSectionStyle : {}}>L'algorithme est votre maître mot ?</a> + + </div> + <div className={styles.Link}> + <a href={"#StatsSection"} + style={section.statsSection || section.featuresSection ? chosenSectionStyle : {}}>Comment suivre vos étudiants ?</a> + + </div> + <div className={styles.Link}> + <a href={"#TowerSection"} style={section.towerSection ? chosenSectionStyle : {}}>Apprendre de manière ludique</a> + + </div> + <div className={styles.Link}> + <a href={"#BottomSection"} + style={section.bottomSection && !section.contactSection ? chosenSectionStyle : {}}>Article</a> + + </div> + <div className={styles.Link}> + <a href={"#Contact"} style={section.contactSection ? chosenSectionStyle : {}}>Contact</a> + + </div> + </div> </div> ); } diff --git a/src/js/components/TopLinks/TopLinks.module.scss b/src/js/components/TopLinks/TopLinks.module.scss index e6f725ad1feda997f693ebfef21f6a5647dc3a09..76907fd31f12304eef5b0d8554344dbc5d293b77 100644 --- a/src/js/components/TopLinks/TopLinks.module.scss +++ b/src/js/components/TopLinks/TopLinks.module.scss @@ -1,15 +1,49 @@ @import '../../../style/colors'; @import '../../../style/fonts'; -.logo { - float: left; - max-width: 5vw; - max-height: 3vh; - font-size: 3rem; + +.TopLinks { + + display: flex; font-family: $primary_font; + font-weight: $primary_font_weight; + color: $primary_black; + + .Logo { + float: left; + font-size: 2rem; + color: $primary_black; + text-decoration: none; + + } + + .Links { + padding-left: 5%; + + display: flex; + flex-direction: row; + + + + .Link { + text-align: center; + margin-left: 3%; + min-width: fit-content; + + a { + font-size: 0.9vw; + color: $primary_black; + + } + } + + + + a:hover{ + color: $primary_pink; + } + } + + } -.top-links { - font-family: $primary_font; - font-size: 3rem; -} \ No newline at end of file diff --git a/src/js/pages/MainPage,module.scss b/src/js/pages/MainPage,module.scss index e0f549157550f4928db01ccbe3770e68d2fc69bd..d2b8868e246b85d226a6afa51e858d7155a3fd4a 100644 --- a/src/js/pages/MainPage,module.scss +++ b/src/js/pages/MainPage,module.scss @@ -1,7 +1,9 @@ @import '../../style/colors'; @import '../../style/fonts'; - +html { + scroll-behavior: smooth; +} .top-bar{ background: $primary_beige; @@ -9,19 +11,6 @@ z-index: 1; width: 100%; - .logo { - float: left; - width: 120px; - height: 31px; - font-size: 12px; - font-family: $primary_font; - } - - .top-links { - font-family: $primary_font; - font-size: 12px; - } - } .site-layout { diff --git a/src/js/pages/MainPage.js b/src/js/pages/MainPage.js index 0ee297db46a90515b612d740b51fc920229d5cad..c7dc8feb5e414881dfaa5e9775cb9d8fda7ec44a 100644 --- a/src/js/pages/MainPage.js +++ b/src/js/pages/MainPage.js @@ -12,25 +12,99 @@ import FeatureSection from "../sections/FeatureSection/FeatureSection"; import TowerSection from "../sections/TowerSection/TowerSection"; import OctopusSection from "../sections/OctopusSection/OctopusSection"; import BottomSection from "../sections/BottomSection/BottomSection"; +import React from "react"; +import {useElementOnScreen} from "../utils/utils"; +import TopBar from "../components/TopBar/TopBar"; +import {Content} from "antd/lib/layout/layout"; + +const {HContent, Footer} = Layout; + -const {Header, Content, Footer} = Layout; const MainPage = () => { + + const currentSection = {}; + + const landingSectionRef = React.createRef(); + currentSection["landingSection"] = useElementOnScreen(landingSectionRef, { + root: null, + rootMargin: "0px", + threshold: 1.0 + }); + + const vscodeSectionRef = React.createRef(); + currentSection["vscodeSection"] = useElementOnScreen(vscodeSectionRef, { + root: null, + rootMargin: "0px", + threshold: 1.0 + }); + + const cloudSectionRef = React.createRef(); + currentSection["cloudSection"] = useElementOnScreen(cloudSectionRef, { + root: null, + rootMargin: "0px", + threshold: 0.9 + }); + + const statsSectionRef = React.createRef(); + currentSection["statsSection"] = useElementOnScreen(statsSectionRef, { + root: null, + rootMargin: "0px", + threshold: 0.8 + }); + + const featuresSectionRef = React.createRef(); + currentSection["featuresSection"] = useElementOnScreen(featuresSectionRef, { + root: null, + rootMargin: "0px", + threshold: 1.0 + }); + + const towerSectionRef = React.createRef(); + currentSection["towerSection"] = useElementOnScreen(towerSectionRef, { + root: null, + rootMargin: "0px", + threshold: 1.0 + }); + + const octopusSectionRef = React.createRef(); + currentSection["octopusSection"] = useElementOnScreen(octopusSectionRef, { + root: null, + rootMargin: "0px", + threshold: 1.0 + }); + + const bottomSectionRef = React.createRef(); + currentSection["bottomSection"] = useElementOnScreen(bottomSectionRef, { + root: null, + rootMargin: "0px", + threshold: 0.5 + }); + + const contactSectionRef = React.createRef(); + currentSection["contactSection"] = useElementOnScreen(contactSectionRef, { + root: null, + rootMargin: "0px", + threshold: 0.8 + }); + + + return ( <Layout> - <Header className={"top-bar"}> - <TopLinks/> - </Header> + + <TopBar currentSection={currentSection} /> + <Content className="site-layout"> - <LandingSection/> - <VscodeSection/> - <CloudSection/> - <StatsSection/> - <FeatureSection/> - <TowerSection/> - <OctopusSection/> - <BottomSection/> + <LandingSection innerRef={landingSectionRef}/> + <VscodeSection innerRef={vscodeSectionRef}/> + <CloudSection innerRef={cloudSectionRef}/> + <StatsSection innerRef={statsSectionRef}/> + <FeatureSection innerRef={featuresSectionRef}/> + <TowerSection innerRef={towerSectionRef}/> + <OctopusSection innerRef={octopusSectionRef}/> + <BottomSection innerRef={bottomSectionRef} contactRef={contactSectionRef}/> </Content> <Footer className="footer"> <Link>Contact</Link> @@ -41,4 +115,5 @@ const MainPage = () => { ); } + export default MainPage; \ No newline at end of file diff --git a/src/js/sections/BottomSection/BottomSection.js b/src/js/sections/BottomSection/BottomSection.js index c2bf7efb2c8bc5ed38b76b8b19f39ea7c025377a..6ebdf4edea5a874604f4b1a567a025cd0b95b77a 100644 --- a/src/js/sections/BottomSection/BottomSection.js +++ b/src/js/sections/BottomSection/BottomSection.js @@ -6,10 +6,10 @@ import logoEpf from "../../../assets/props/epf_logo.png" -const BottomSection = () => { +const BottomSection = ({innerRef, contactRef}) => { return ( - <div className={styles.BottomSection}> - <div className={styles.MiddleBlock}> + <div ref={innerRef} id={"BottomSection"} className={styles.BottomSection}> + <div id="Article" className={styles.MiddleBlock}> <p className={styles.Title}> On en parle à l'INSA de Rouen avec Takima </p> @@ -27,7 +27,7 @@ const BottomSection = () => { </div> </div> - <div className={styles.BottomBlock}> + <div ref={contactRef} className={styles.BottomBlock}> <div className={styles.Logos}> <img src={logoInsa} alt={"insa logo"}/> <img src={logoEpf} alt={"epf logo"}/> @@ -35,7 +35,7 @@ const BottomSection = () => { Ils ont déjà expérimenté notre plateforme. </p> </div> - <div className={styles.ContactLinks}> + <div id="Contact" className={styles.ContactLinks}> <p className={styles.BigCaption}> Offrez à vos étudiants les meilleurs outils pour apprendre. </p> diff --git a/src/js/sections/CloudSection/CloudSection.js b/src/js/sections/CloudSection/CloudSection.js index c00bb96797c4d8ae1a881f292fa109f1294997d9..7a07495af9ed4ce594a0bebe931180776232859d 100644 --- a/src/js/sections/CloudSection/CloudSection.js +++ b/src/js/sections/CloudSection/CloudSection.js @@ -20,9 +20,9 @@ const bottomBlockTitle = [ ]; -const CloudSection = () => { +const CloudSection = ({innerRef}) => { return ( - <div className={styles.CloudSection}> + <div ref={innerRef} id={"CloudSection"} className={styles.CloudSection}> <div className={styles.UpperBlock}> <MultiColoredText content={upperBlockContent} /> diff --git a/src/js/sections/FeatureSection/FeatureSection.js b/src/js/sections/FeatureSection/FeatureSection.js index a1238acf20d0d4747e5314407fbd258eb4c01dc2..d783397139fa3e75fc71ce80c4010b88235943d2 100644 --- a/src/js/sections/FeatureSection/FeatureSection.js +++ b/src/js/sections/FeatureSection/FeatureSection.js @@ -16,9 +16,9 @@ const feature2 = [ {text: "sur la plateforme sans devoir configurer plein de machines.", color: black} ]; -const FeatureSection = () => { +const FeatureSection = ({innerRef}) => { return( - <div className={styles.FeatureSection}> + <div ref={innerRef} id="FeatureSection" className={styles.FeatureSection}> <Row> <Col span={12}> <div className={styles.LeftSide}> diff --git a/src/js/sections/LandingSection/LandingSection.js b/src/js/sections/LandingSection/LandingSection.js index 8a5cfb4f526635b447f980d130bbd30a90fd29a5..c14fec81795cf3c89c477c1975cd409ae2fff6ca 100644 --- a/src/js/sections/LandingSection/LandingSection.js +++ b/src/js/sections/LandingSection/LandingSection.js @@ -12,9 +12,9 @@ const landingPageMessage = [ ]; -const LandingSection = () => { +const LandingSection = ({innerRef}) => { return ( - <div className={styles.LandingSection}> + <div ref={innerRef} id={"LandingSection"} className={styles.LandingSection}> <Row> <Col span={12}> <div className={styles.LeftSide}> @@ -23,8 +23,11 @@ const LandingSection = () => { </Col> <Col span={12}> <div className={styles.RightSide}> - <p className={styles.Title}>DEADLOCK <br/> - <span className={styles.Caption}><MultiColoredText content={landingPageMessage}/></span></p> + <div className={styles.Title}>DEADLOCK <br/> + <span className={styles.Caption}> + <MultiColoredText content={landingPageMessage}/> + </span> + </div> </div> </Col> </Row> diff --git a/src/js/sections/OctopusSection/OctopusSection.js b/src/js/sections/OctopusSection/OctopusSection.js index 4cf8a9c1a81b13ca704debdefddc4c23aa7671e5..d7356753ce0720eb896fa610f495e25b775d2928 100644 --- a/src/js/sections/OctopusSection/OctopusSection.js +++ b/src/js/sections/OctopusSection/OctopusSection.js @@ -3,9 +3,9 @@ import styles from "./OctopusSection.module.scss"; import octopusImage from "../../../assets/main/poulpe_ludique_big.png"; -const OctopusSection = () => { +const OctopusSection = ({innerRef}) => { return ( - <div className={styles.OctopusSection}> + <div ref={innerRef} id={"OctopusSection"} className={styles.OctopusSection}> <img src={octopusImage} alt="octopus" className={styles.OctopusImage}/> </div> ); diff --git a/src/js/sections/StatsSection/StatsSection.js b/src/js/sections/StatsSection/StatsSection.js index ced055621d2195e3c7bd1a796f7fa574d186877b..c2a0dee56e6f70a6a92f4e0d9202b5abfcae1954 100644 --- a/src/js/sections/StatsSection/StatsSection.js +++ b/src/js/sections/StatsSection/StatsSection.js @@ -12,15 +12,15 @@ const title = [ {text: "vos étudiants ? ", color: black}, ]; -const StatsSection = () => { +const StatsSection = ({innerRef}) => { return ( - <div className={styles.StatsSection}> + <div ref={innerRef} id={"StatsSection"} className={styles.StatsSection}> <Row> <Col span={12}> <div className={styles.LeftSide}> - <p className={styles.Title}> + <div className={styles.Title}> <MultiColoredText content={title}/> - </p> + </div> <p className={styles.Caption}> Vous pouvez relire le code de vos étudiants, les évaluer, leur faire des retours </p> diff --git a/src/js/sections/StatsSection/StatsSection.module.scss b/src/js/sections/StatsSection/StatsSection.module.scss index cb529d45dcaa745858a29de980b48be3f11ac3de..17fa01b6262f44e18686657222a1cd178078bcfe 100644 --- a/src/js/sections/StatsSection/StatsSection.module.scss +++ b/src/js/sections/StatsSection/StatsSection.module.scss @@ -33,6 +33,7 @@ font-size: 1.5em; line-height: 1em; color: white; + padding-top: 5%; } } diff --git a/src/js/sections/TowerSection/TowerSection.js b/src/js/sections/TowerSection/TowerSection.js index a437312c52dc537ec1d7e1b08d22af5985b86e06..f6e3a8c7633f86f71c32b4bac3b9433bb8e226be 100644 --- a/src/js/sections/TowerSection/TowerSection.js +++ b/src/js/sections/TowerSection/TowerSection.js @@ -3,6 +3,7 @@ import {Col, Row} from "antd"; import MultiColoredText from "../../components/MultiColoredText/MultiColoredText"; import towerImage from "../../../assets/props/donjon.svg"; +import {useElementOnScreen} from "../../utils/utils"; const black = "#1D2C38"; const white = "white"; @@ -13,9 +14,12 @@ const title = [ {text: "favorise l'investissement des étudiants.", color: white} ]; -const TowerSection = () => { + +const TowerSection = ({innerRef}) => { + + return ( - <div className={styles.TowerSection}> + <div ref={innerRef} id={"TowerSection"} className={styles.TowerSection}> <Row> <Col span={12}> <div className={styles.LeftSide}> @@ -24,12 +28,12 @@ const TowerSection = () => { </Col> <Col span={12}> <div className={styles.RightSide}> - <p className={styles.Title}> + <div className={styles.Title}> <MultiColoredText content={title}/> - </p> - <p className={styles.Caption}> + </div> + <div className={styles.Caption}> C'est pourquoi nous avons ajouté plusieurs éléments de jeux au sein de notre palteforme. - </p> + </div> </div> </Col> </Row> diff --git a/src/js/sections/TowerSection/TowerSection.module.scss b/src/js/sections/TowerSection/TowerSection.module.scss index 88c3b451b6cafcc998b809bb2a9ee269f3f33cd2..4e5c1383aa2382b482dc9d1d0d4938ee5166e636 100644 --- a/src/js/sections/TowerSection/TowerSection.module.scss +++ b/src/js/sections/TowerSection/TowerSection.module.scss @@ -22,7 +22,7 @@ color: $primary_black; font-weight: $primary_font_weight; font-family: $primary_font; - padding-top: 15%; + padding-top: 20%; padding-right: 30%; vertical-align: middle; line-height: 4em; @@ -36,6 +36,7 @@ font-size: 1.5em; line-height: 1em; color: white; + padding-top: 5%; } } diff --git a/src/js/sections/VscodeSection/VscodeSection.js b/src/js/sections/VscodeSection/VscodeSection.js index c3f711ccbf70cd743bcb147bbcea4008b49c43a7..02902606d7ca2a40fd9da9a14ee1c5a9dd30e8da 100644 --- a/src/js/sections/VscodeSection/VscodeSection.js +++ b/src/js/sections/VscodeSection/VscodeSection.js @@ -3,6 +3,7 @@ import {Col, Row} from "antd"; import MultiColoredText from "../../components/MultiColoredText/MultiColoredText"; import vscodeImage from "../../../assets/main/vscode_screen.png"; +import {useEffect, useRef, useState} from "react"; const black = "#1D2C38"; const white = "white"; @@ -13,9 +14,10 @@ const vscodeTitle = [ {text: "pour chacun de vos étudiants", color: white} ]; -const VscodeSection = () => { +const VscodeSection = ({innerRef}) => { + return ( - <div className={styles.VscodeSection}> + <div ref={innerRef} id="VscodeSection" className={styles.VscodeSection}> <Row> <Col span={16}> <div className={styles.LeftSide}> @@ -24,12 +26,12 @@ const VscodeSection = () => { </Col> <Col span={8}> <div className={styles.RightSide}> - <p className={styles.Title}> + <div className={styles.Title}> <MultiColoredText content={vscodeTitle}/> - </p> - <p className={styles.Caption}> + </div> + <div className={styles.Caption}> Plus besoin de se soucier de l'environnement, de la machine, un navigateur connecté suffit. - </p> + </div> </div> </Col> </Row> diff --git a/src/js/sections/VscodeSection/VscodeSection.module.scss b/src/js/sections/VscodeSection/VscodeSection.module.scss index aa7fe19c33b073aeb0887810a08ee3f95305a12c..b7743ee833b3cbb0f96cea46a38c6515c1f0f751 100644 --- a/src/js/sections/VscodeSection/VscodeSection.module.scss +++ b/src/js/sections/VscodeSection/VscodeSection.module.scss @@ -22,7 +22,7 @@ color: $primary_black; font-weight: $primary_font_weight; font-family: $primary_font; - padding-top: 35%; + padding-top: 40%; padding-right: 30%; text-align: left; vertical-align: middle; @@ -36,6 +36,7 @@ font-size: 1.5em; line-height: 1em; color: white; + padding-top: 5%; } } diff --git a/src/js/utils/utils.js b/src/js/utils/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..ee19cb5c01cad618d3a6b344bda40113e2cd3b3f --- /dev/null +++ b/src/js/utils/utils.js @@ -0,0 +1,20 @@ +import {useEffect, useRef, useState} from "react"; + +export const useElementOnScreen = (ref, options) => { + const [isVisible, setVisible] = useState(false); + + const callbackFunction = (entries) => { + const [entry] = entries; + setVisible(entry.isIntersecting); + } + + useEffect(() => { + const observer = new IntersectionObserver(callbackFunction, options); + if(ref.current) observer.observe(ref.current) + return () => { + if(ref.current) observer.unobserve(ref.current) + } + }, [ref, options]); + + return isVisible; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 45bdbd8bcc28f96aafad823073b0358c2f55ec28..540872b4779632ebd4a9de5eb2b786bae071a772 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9474,6 +9474,11 @@ react-error-overlay@^6.0.9: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== +react-intersection-observer@^8.32.0: + version "8.32.0" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.32.0.tgz#47249332e12e8bb99ed35a10bb7dd10446445a7b" + integrity sha512-RlC6FvS3MFShxTn4FHAy904bVjX5Nn4/eTjUkurW0fHK+M/fyQdXuyCy9+L7yjA+YMGogzzSJNc7M4UtfSKvtw== + react-is@^16.12.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"