Skip to content
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

implement sticky navbar && highlight navbar menu items as scroll fea… #259

Open
wants to merge 2 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions src/components/pages/landing-page.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useRef } from 'react';
import { Box, Flex } from '@chakra-ui/react';
import { useLocation } from 'react-router-dom';
import { parse } from 'query-string';
Expand All @@ -11,9 +11,18 @@ import Faq from '../ui/landing-page/faq';
import DonatePage from '../ui/landing-page/donate-page';
import LandingPageHeader from '../ui/landing-page-header';
import SponsorList from '../ui/landing-page/sponsor-list';
import useOnViewport from '../../utils/use-on-viewport';

function LandingPage() {
const location = useLocation();
const splashScreenRef = useRef();
const problemSolutionRef = useRef();
const howItWorksRef = useRef();
const faqRef = useRef();
const isSplashScreenVisible = useOnViewport(splashScreenRef);
const isProblemSolutionVisible = useOnViewport(problemSolutionRef);
const isHowItWorksVisible = useOnViewport(howItWorksRef);
const isFaqVisible = useOnViewport(faqRef);

useEffect(() => {
if (location.state?.redirectedFromAuth) {
Expand All @@ -30,25 +39,33 @@ function LandingPage() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

function activeMenuItem() {
if (isSplashScreenVisible) return '#splash-screen';
if (isProblemSolutionVisible) return '#problem-solution';
if (isHowItWorksVisible) return '#how-it-works';
if (isFaqVisible) return '#faq';
return '';
}

return (
<>
<Helmet>
<title>Uçurtma Projesi</title>
</Helmet>
<Box mt="36px" width="full" bg="white" transition="0.2s ease all">
<LandingPageHeader />
<LandingPageHeader activeMenuItem={activeMenuItem()} />
</Box>
<Flex as="section" id="splash-screen" mt={{ base: 84, lg: 126 }}>
<SplashScreen />
<SplashScreen ref={splashScreenRef} />
</Flex>
<Box as="section" mt={165}>
<FeaturedCampaign />
</Box>
<Flex as="section" id="problem-solution" mt={158} px={{ base: 4, lg: 0 }}>
<ProblemSolution />
<ProblemSolution ref={problemSolutionRef} />
</Flex>
<Flex as="section" px={{ base: 4, lg: 0 }} mt="198px" id="how-it-works">
<HowItWorks />
<HowItWorks ref={howItWorksRef} />
</Flex>
<Box as="section" mt="330px" mb={120}>
<DonatePage />
Expand All @@ -57,7 +74,7 @@ function LandingPage() {
<SponsorList />
</Box>
<Flex as="section" id="faq" mb={210} px={{ base: 4, lg: 0 }}>
<Faq />
<Faq ref={faqRef} />
</Flex>
</>
);
Expand Down
14 changes: 12 additions & 2 deletions src/components/ui/landing-page-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function SupportButton({ ...otherProps }) {
);
}

function LandingPageHeader() {
function LandingPageHeader({ activeMenuItem }) {
const { t } = useTranslation('titles');

const menuItems = [
Expand Down Expand Up @@ -62,6 +62,12 @@ function LandingPageHeader() {
px={{ base: 4, lg: 0 }}
justifyContent="space-between"
alignItems="center"
position="fixed"
top="0"
right="0"
left="0"
bg="white"
zIndex="2"
>
<Box
display={{ base: 'flex', lg: 'block' }}
Expand All @@ -79,7 +85,11 @@ function LandingPageHeader() {
</Flex>
</Box>
<Flex mt={2} py={1} overflowY={{ base: 'auto', lg: 'unset' }}>
<MenuItems alignItems="center" items={menuItems} />
<MenuItems
alignItems="center"
items={menuItems}
activeMenuItem={activeMenuItem}
/>
<SupportButton display={{ base: 'none', lg: 'flex' }} />
<SelectLanguage display={{ base: 'none', lg: 'flex' }} />
</Flex>
Expand Down
108 changes: 55 additions & 53 deletions src/components/ui/landing-page/faq.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { forwardRef } from 'react';
import {
Box,
Heading,
Expand All @@ -16,65 +16,67 @@ import FAQ from './faq.json';
const { studentQuestions, donatorQuestions } = FAQ;
const options = ['student', 'supporter'];

function Faq() {
function Faq(props, ref) {
const [activeFaq, setActiveFaq] = React.useState('student');
const { t } = useTranslation(['faq', 'titles']);
const questionType =
activeFaq === 'student' ? studentQuestions : donatorQuestions;

return (
<Container
py={{ base: 12, lg: 36 }}
px={{ base: 8, lg: 36 }}
bg="gray.900"
borderRadius={{ base: 22, lg: 139 }}
mt={0}
>
<Box width="full" mb={12} textAlign="center" color="white">
<Heading size="xl">{t('titles:FAQ')}</Heading>
<HStack spacing={4} my={10} justify="center">
{options.map(option => (
<Button
key={option}
onClick={() => setActiveFaq(option)}
isActive={activeFaq === option}
bg="gray.200"
color="gray.900"
_active={{ bg: 'blue.700', color: 'white' }}
_hover={{
bg: 'gray.100',
_active: { bg: 'blue.600' },
}}
>
{t(`I am ${option}`)}
</Button>
))}
</HStack>
<Box ref={ref} w="100%">
<Container
py={{ base: 12, lg: 36 }}
px={{ base: 8, lg: 36 }}
bg="gray.900"
borderRadius={{ base: 22, lg: 139 }}
mt={0}
>
<Box width="full" mb={12} textAlign="center" color="white">
<Heading size="xl">{t('titles:FAQ')}</Heading>
<HStack spacing={4} my={10} justify="center">
{options.map(option => (
<Button
key={option}
onClick={() => setActiveFaq(option)}
isActive={activeFaq === option}
bg="gray.200"
color="gray.900"
_active={{ bg: 'blue.700', color: 'white' }}
_hover={{
bg: 'gray.100',
_active: { bg: 'blue.600' },
}}
>
{t(`I am ${option}`)}
</Button>
))}
</HStack>

<Divider maxW={24} borderColor="gray.100" marginX="auto" mt={8} />
</Box>
<Accordion width="full" allowMultiple>
<Grid
templateColumns={{
base: 'inherit',
md: '50% auto',
lg: '40% auto',
xl: 'repeat(2, 1fr)',
}}
width="full"
columnGap={8}
rowGap={4}
>
<QuestionList
questions={questionType.filter((question, i) => i % 2 === 0)}
/>
<QuestionList
questions={questionType.filter((question, i) => i % 2 !== 0)}
/>
</Grid>
</Accordion>
</Container>
<Divider maxW={24} borderColor="gray.100" marginX="auto" mt={8} />
</Box>
<Accordion width="full" allowMultiple>
<Grid
templateColumns={{
base: 'inherit',
md: '50% auto',
lg: '40% auto',
xl: 'repeat(2, 1fr)',
}}
width="full"
columnGap={8}
rowGap={4}
>
<QuestionList
questions={questionType.filter((question, i) => i % 2 === 0)}
/>
<QuestionList
questions={questionType.filter((question, i) => i % 2 !== 0)}
/>
</Grid>
</Accordion>
</Container>
</Box>
);
}

export default Faq;
export default forwardRef(Faq);
118 changes: 60 additions & 58 deletions src/components/ui/landing-page/how-it-works.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import React, { forwardRef } from 'react';
import { Heading, Grid, Text, Box, Divider, Image } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import Container from '../container';
import Card from '../card';

function HowItWorks() {
function HowItWorks(props, ref) {
const { t } = useTranslation(['howItWorks', 'titles']);
const cards = [
{
Expand All @@ -25,63 +25,65 @@ function HowItWorks() {
];

return (
<Container
bg="gray.800"
pt={16}
color="white"
borderTopRadius={{ base: 22, lg: 139 }}
px={4}
>
<Box width="full" textAlign="center">
<Heading size="xl">{t('titles:How it works')}</Heading>
<Text mt={4}>{t('Three Steps')}</Text>
<Divider maxW={24} borderColor="gray.700" marginX="auto" mt={8} />
</Box>
<Grid
templateColumns={{
base: 'inherit',
md: 'repeat(3, 1fr)',
}}
width="full"
px={{ base: 2, lg: 8 }}
gap={{ base: 8, lg: 20 }}
mt="-6rem"
<Box ref={ref} w="100%">
<Container
bg="gray.800"
pt={16}
color="white"
borderTopRadius={{ base: 22, lg: 139 }}
px={4}
>
{cards.map(card => (
<Box
as={Card}
display="flex"
key={card.title}
px={8}
py={6}
borderRadius="51px"
alignItems="center"
flexDir="column"
_last={{ justifyContent: 'center' }}
pos="relative"
top={24}
bg="gray.900"
border="0"
>
<Image
src={card.icon}
maxW={32}
mb={8}
loading="lazy"
htmlWidth="128"
htmlHeight="128"
/>
<Heading fontSize="1.5rem" fontWeight={600}>
{card.title}
</Heading>
<Text textAlign="center" mt={4}>
{card.text}
</Text>
</Box>
))}
</Grid>
</Container>
<Box width="full" textAlign="center">
<Heading size="xl">{t('titles:How it works')}</Heading>
<Text mt={4}>{t('Three Steps')}</Text>
<Divider maxW={24} borderColor="gray.700" marginX="auto" mt={8} />
</Box>
<Grid
templateColumns={{
base: 'inherit',
md: 'repeat(3, 1fr)',
}}
width="full"
px={{ base: 2, lg: 8 }}
gap={{ base: 8, lg: 20 }}
mt="-6rem"
>
{cards.map(card => (
<Box
as={Card}
display="flex"
key={card.title}
px={8}
py={6}
borderRadius="51px"
alignItems="center"
flexDir="column"
_last={{ justifyContent: 'center' }}
pos="relative"
top={24}
bg="gray.900"
border="0"
>
<Image
src={card.icon}
maxW={32}
mb={8}
loading="lazy"
htmlWidth="128"
htmlHeight="128"
/>
<Heading fontSize="1.5rem" fontWeight={600}>
{card.title}
</Heading>
<Text textAlign="center" mt={4}>
{card.text}
</Text>
</Box>
))}
</Grid>
</Container>
</Box>
);
}

export default HowItWorks;
export default forwardRef(HowItWorks);
Loading