Skip to content

Commit fa02c77

Browse files
committed
feat: add scroll-down arrows to each section for smooth section-to-section navigation; refs #50
1 parent c7c0ee8 commit fa02c77

File tree

4 files changed

+114
-56
lines changed

4 files changed

+114
-56
lines changed

src/components/HomePageComponents/Section1.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const Section1: React.FC = () => {
2828
backgroundSize: "cover",
2929
overflow: "auto",
3030
width: "100%",
31-
minHeight: "calc(100vh - 6rem)",
31+
minHeight: "calc(90vh - 6rem)",
3232
}}
3333
>
3434
<Grid

src/components/HomePageComponents/Section2.tsx

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
12
import ArrowForwardOutlinedIcon from "@mui/icons-material/ArrowForwardOutlined";
2-
import { Typography, Box, Button, CircularProgress } from "@mui/material";
3+
import {
4+
Typography,
5+
Box,
6+
Button,
7+
CircularProgress,
8+
IconButton,
9+
} from "@mui/material";
310
import FilterMenu from "components/NodesFilter/FilterMenu";
411
import { Colors } from "design/theme";
512
import NeuroJsonGraph from "modules/universe/NeuroJsonGraph";
@@ -15,6 +22,7 @@ interface Section2Props {
1522
setFilterKeyword: (keyword: string) => void;
1623
setSelectedModalities: (modalities: string[]) => void;
1724
onNodeClick: (node: NodeObject) => void;
25+
scrollToNext: () => void;
1826
}
1927

2028
const Section2: React.FC<Section2Props> = ({
@@ -25,6 +33,7 @@ const Section2: React.FC<Section2Props> = ({
2533
setFilterKeyword,
2634
setSelectedModalities,
2735
onNodeClick,
36+
scrollToNext,
2837
}) => {
2938
const navigate = useNavigate();
3039

@@ -38,9 +47,10 @@ const Section2: React.FC<Section2Props> = ({
3847
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' viewBox='0 0 1200 800'%3E%3Cdefs%3E%3CradialGradient id='a' cx='0' cy='800' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%2371feed'/%3E%3Cstop offset='1' stop-color='%2371feed' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='b' cx='1200' cy='800' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23abb2f9'/%3E%3Cstop offset='1' stop-color='%23abb2f9' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='600' cy='0' r='600' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%231fa0f6'/%3E%3Cstop offset='1' stop-color='%231fa0f6' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='d' cx='600' cy='800' r='600' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23FFFFFF'/%3E%3Cstop offset='1' stop-color='%23FFFFFF' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='e' cx='0' cy='0' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%2302DEC4'/%3E%3Cstop offset='1' stop-color='%2302DEC4' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='f' cx='1200' cy='0' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%235865F2'/%3E%3Cstop offset='1' stop-color='%235865F2' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect fill='url(%23a)' width='1200' height='800'/%3E%3Crect fill='url(%23b)' width='1200' height='800'/%3E%3Crect fill='url(%23c)' width='1200' height='800'/%3E%3Crect fill='url(%23d)' width='1200' height='800'/%3E%3Crect fill='url(%23e)' width='1200' height='800'/%3E%3Crect fill='url(%23f)' width='1200' height='800'/%3E%3C/svg%3E")`,
3948
backgroundAttachment: "fixed",
4049
backgroundSize: "cover",
41-
overflow: "auto",
50+
// overflow: "auto",
4251
padding: "1rem",
43-
paddingLeft: "7rem",
52+
// paddingLeft: "7rem",
53+
minHeight: "100vh",
4454
}}
4555
>
4656
<Box // tri-colors card
@@ -109,7 +119,7 @@ const Section2: React.FC<Section2Props> = ({
109119
{/* top buttons: show only on large screens */}
110120
<Box
111121
sx={{
112-
display: { xs: "none", md: "none", lg: "flex" },
122+
display: { xs: "flex", md: "flex", lg: "flex" },
113123
flexDirection: "column",
114124
width: { xs: "100%", sm: "50%", md: "30%", lg: "15%" },
115125
maxWidth: "200px",
@@ -118,22 +128,6 @@ const Section2: React.FC<Section2Props> = ({
118128
zIndex: 10, // Higher than text and graph
119129
}}
120130
>
121-
<Button
122-
variant="outlined"
123-
sx={{
124-
color: Colors.lightGray,
125-
borderColor: Colors.lightGray,
126-
transition: "all 0.3s ease",
127-
marginTop: 5,
128-
"&:hover": {
129-
transform: "scale(1.05)",
130-
borderColor: Colors.lightGray,
131-
},
132-
}}
133-
>
134-
Start exploring
135-
<ArrowForwardOutlinedIcon />
136-
</Button>
137131
<Button
138132
variant="outlined"
139133
sx={{
@@ -179,7 +173,7 @@ const Section2: React.FC<Section2Props> = ({
179173
</Box>
180174

181175
{/* Bottom Buttons - Show only on smaller screens */}
182-
<Box
176+
{/* <Box
183177
sx={{
184178
display: { xs: "flex", md: "flex", lg: "none" },
185179
justifyContent: "center",
@@ -189,23 +183,6 @@ const Section2: React.FC<Section2Props> = ({
189183
width: "100%",
190184
}}
191185
>
192-
<Button
193-
variant="outlined"
194-
sx={{
195-
color: Colors.lightGray,
196-
borderColor: Colors.lightGray,
197-
transition: "all 0.3s ease",
198-
marginBottom: 2,
199-
width: "200px",
200-
"&:hover": {
201-
transform: "scale(1.05)",
202-
borderColor: Colors.lightGray,
203-
},
204-
}}
205-
>
206-
Start exploring
207-
<ArrowForwardOutlinedIcon />
208-
</Button>
209186
<Button
210187
variant="outlined"
211188
sx={{
@@ -222,7 +199,28 @@ const Section2: React.FC<Section2Props> = ({
222199
>
223200
View All Databases
224201
</Button>
225-
</Box>
202+
</Box> */}
203+
</Box>
204+
205+
{/* Scroll Arrow - fixed inside Section2 */}
206+
<Box
207+
sx={{
208+
position: "absolute",
209+
bottom: "1rem",
210+
left: 0,
211+
right: 0,
212+
width: "100%",
213+
display: "flex",
214+
justifyContent: "center",
215+
alignItems: "center",
216+
paddingBottom: "2rem",
217+
mt: 4,
218+
zIndex: 1000,
219+
}}
220+
>
221+
<IconButton onClick={scrollToNext}>
222+
<ArrowDownwardIcon sx={{ fontSize: 40, color: Colors.darkPurple }} />
223+
</IconButton>
226224
</Box>
227225
</Box>
228226
);

src/components/HomePageComponents/Section3.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
import { Typography, Box, Button } from "@mui/material";
1+
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
2+
import { Typography, Box, Button, IconButton } from "@mui/material";
23
import { Colors } from "design/theme";
34
import React from "react";
45

5-
const Section3: React.FC = () => {
6+
interface Section3Props {
7+
scrollToNext: () => void;
8+
}
9+
10+
const Section3: React.FC<Section3Props> = ({ scrollToNext }) => {
611
return (
712
<Box // white background
813
sx={{
@@ -13,7 +18,7 @@ const Section3: React.FC = () => {
1318
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2000 1500'%3E%3Cdefs%3E%3CradialGradient id='a' gradientUnits='objectBoundingBox'%3E%3Cstop offset='0' stop-color='%23000000'/%3E%3Cstop offset='1' stop-color='%235865F2'/%3E%3C/radialGradient%3E%3ClinearGradient id='b' gradientUnits='userSpaceOnUse' x1='0' y1='750' x2='1550' y2='750'%3E%3Cstop offset='0' stop-color='%232c3379'/%3E%3Cstop offset='1' stop-color='%235865F2'/%3E%3C/linearGradient%3E%3Cpath id='s' fill='url(%23b)' d='M1549.2 51.6c-5.4 99.1-20.2 197.6-44.2 293.6c-24.1 96-57.4 189.4-99.3 278.6c-41.9 89.2-92.4 174.1-150.3 253.3c-58 79.2-123.4 152.6-195.1 219c-71.7 66.4-149.6 125.8-232.2 177.2c-82.7 51.4-170.1 94.7-260.7 129.1c-90.6 34.4-184.4 60-279.5 76.3C192.6 1495 96.1 1502 0 1500c96.1-2.1 191.8-13.3 285.4-33.6c93.6-20.2 185-49.5 272.5-87.2c87.6-37.7 171.3-83.8 249.6-137.3c78.4-53.5 151.5-114.5 217.9-181.7c66.5-67.2 126.4-140.7 178.6-218.9c52.3-78.3 96.9-161.4 133-247.9c36.1-86.5 63.8-176.2 82.6-267.6c18.8-91.4 28.6-184.4 29.6-277.4c0.3-27.6 23.2-48.7 50.8-48.4s49.5 21.8 49.2 49.5c0 0.7 0 1.3-0.1 2L1549.2 51.6z'/%3E%3Cg id='g'%3E%3Cuse href='%23s' transform='scale(0.12) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.2) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.25) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(0.3) rotate(-20)'/%3E%3Cuse href='%23s' transform='scale(0.4) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(0.5) rotate(20)'/%3E%3Cuse href='%23s' transform='scale(0.6) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.7) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.835) rotate(-40)'/%3E%3Cuse href='%23s' transform='scale(0.9) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(1.05) rotate(25)'/%3E%3Cuse href='%23s' transform='scale(1.2) rotate(8)'/%3E%3Cuse href='%23s' transform='scale(1.333) rotate(-60)'/%3E%3Cuse href='%23s' transform='scale(1.45) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(1.6) rotate(10)'/%3E%3C/g%3E%3C/defs%3E%3Cg transform='translate(100 0)'%3E%3Cg transform='translate(0 210)'%3E%3Ccircle fill='url(%23a)' r='3000'/%3E%3Cg opacity='0.5'%3E%3Ccircle fill='url(%23a)' r='2000'/%3E%3Ccircle fill='url(%23a)' r='1800'/%3E%3Ccircle fill='url(%23a)' r='1700'/%3E%3Ccircle fill='url(%23a)' r='1651'/%3E%3Ccircle fill='url(%23a)' r='1450'/%3E%3Ccircle fill='url(%23a)' r='1250'/%3E%3Ccircle fill='url(%23a)' r='1175'/%3E%3Ccircle fill='url(%23a)' r='900'/%3E%3Ccircle fill='url(%23a)' r='750'/%3E%3Ccircle fill='url(%23a)' r='500'/%3E%3Ccircle fill='url(%23a)' r='380'/%3E%3Ccircle fill='url(%23a)' r='250'/%3E%3C/g%3E%3Cg transform='rotate(-176.4 0 0)'%3E%3Cuse href='%23g' transform='rotate(10)'/%3E%3Cuse href='%23g' transform='rotate(120)'/%3E%3Cuse href='%23g' transform='rotate(240)'/%3E%3C/g%3E%3Ccircle fill='url(%23a)' r='3000'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`,
1419
backgroundAttachment: "fixed",
1520
backgroundSize: "cover",
16-
overflow: "auto",
21+
// overflow: "auto",
1722
padding: "5rem 7rem",
1823
}}
1924
>
@@ -97,6 +102,21 @@ const Section3: React.FC = () => {
97102
</Typography>
98103
</Box>
99104
</Box>
105+
{/* Scroll Arrow to Section4 */}
106+
<Box
107+
sx={{
108+
display: "flex",
109+
justifyContent: "center",
110+
alignItems: "center",
111+
paddingTop: "2rem",
112+
// paddingBottom: "1rem",
113+
zIndex: 3,
114+
}}
115+
>
116+
<IconButton onClick={scrollToNext}>
117+
<ArrowDownwardIcon sx={{ fontSize: 40, color: Colors.lightGray }} />
118+
</IconButton>
119+
</Box>
100120
</Box>
101121
);
102122
};

src/pages/Home.tsx

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Box, Typography, Button, Container } from "@mui/material";
1+
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
2+
import { Box, Typography, Button, Container, IconButton } from "@mui/material";
23
import Section1 from "components/HomePageComponents/Section1";
34
import Section2 from "components/HomePageComponents/Section2";
45
import Section3 from "components/HomePageComponents/Section3";
@@ -7,14 +8,23 @@ import { Colors } from "design/theme";
78
import { useAppDispatch } from "hooks/useAppDispatch";
89
import { useAppSelector } from "hooks/useAppSelector";
910
import { NodeObject } from "modules/universe/NeuroJsonGraph";
10-
import React, { useEffect, useState, useCallback, useMemo } from "react";
11+
import React, {
12+
useEffect,
13+
useState,
14+
useCallback,
15+
useMemo,
16+
useRef,
17+
} from "react";
1118
import { useNavigate } from "react-router-dom";
1219
import { fetchRegistry } from "redux/neurojson/neurojson.action";
1320
import { NeurojsonSelector } from "redux/neurojson/neurojson.selector";
1421

1522
const Home: React.FC = () => {
1623
const navigate = useNavigate();
1724
const dispatch = useAppDispatch();
25+
const section2Ref = useRef<HTMLDivElement>(null);
26+
const section3Ref = useRef<HTMLDivElement>(null);
27+
const section4Ref = useRef<HTMLDivElement>(null);
1828
const { registry, loading } = useAppSelector(NeurojsonSelector);
1929

2030
// State for selected node and panel visibility
@@ -65,24 +75,54 @@ const Home: React.FC = () => {
6575
}}
6676
>
6777
{/* section 1 */}
68-
<Section1 />
78+
<Box sx={{ position: "relative" }}>
79+
<Section1 />
80+
<Box
81+
sx={{
82+
display: "flex",
83+
justifyContent: "center",
84+
mt: 2,
85+
mb: 2,
86+
}}
87+
>
88+
<IconButton
89+
onClick={() =>
90+
section2Ref.current?.scrollIntoView({ behavior: "smooth" })
91+
}
92+
>
93+
<ArrowDownwardIcon sx={{ fontSize: 40, color: Colors.lightGray }} />
94+
</IconButton>
95+
</Box>
96+
</Box>
6997

7098
{/* section 2 */}
71-
<Section2
72-
registry={registry}
73-
filteredRegistry={filteredRegistry}
74-
filterKeyword={filterKeyword}
75-
selectedModalities={selectedModalities}
76-
setFilterKeyword={setFilterKeyword}
77-
setSelectedModalities={setSelectedModalities}
78-
onNodeClick={handleNodeClick}
79-
/>
99+
<Box ref={section2Ref} sx={{ position: "relative" }}>
100+
<Section2
101+
registry={registry}
102+
filteredRegistry={filteredRegistry}
103+
filterKeyword={filterKeyword}
104+
selectedModalities={selectedModalities}
105+
setFilterKeyword={setFilterKeyword}
106+
setSelectedModalities={setSelectedModalities}
107+
onNodeClick={handleNodeClick}
108+
scrollToNext={() =>
109+
section3Ref.current?.scrollIntoView({ behavior: "smooth" })
110+
}
111+
/>
112+
</Box>
80113

81114
{/* section 3 */}
82-
<Section3 />
115+
<Box ref={section3Ref} sx={{ position: "relative" }}>
116+
<Section3
117+
scrollToNext={() =>
118+
section4Ref.current?.scrollIntoView({ behavior: "smooth" })
119+
}
120+
/>
121+
</Box>
83122

84123
{/* footer*/}
85124
<Box
125+
ref={section4Ref}
86126
sx={{
87127
zIndex: "2",
88128
position: "relative",

0 commit comments

Comments
 (0)