generated from YashTotale/boilerplate-react-with-redux-and-firebase
-
Notifications
You must be signed in to change notification settings - Fork 2
/
NavController.tsx
102 lines (88 loc) · 2.81 KB
/
NavController.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// React Imports
import React, { FC, useState, useEffect } from "react";
import { Redirect, useLocation } from "react-router";
import { useTitle } from "../../Context/HeadContext";
import { scrollToTop } from "../../Utils/funcs";
// Redux Imports
import { addToHistory, modifyLastHistory } from "../../Redux";
import { useAppDispatch } from "../../Store";
// Material UI Imports
import { Fab, useScrollTrigger, Zoom } from "@mui/material";
import makeStyles from "@mui/styles/makeStyles";
import { KeyboardArrowUp } from "@mui/icons-material";
export const Paths = {
Home: "/",
Experience: "/experience",
SingleExperience: (slug?: string): string => `/experience/${slug ?? ":slug"}`,
Education: "/education",
SingleEducation: (slug?: string): string => `/education/${slug ?? ":slug"}`,
Projects: "/projects",
Project: (slug?: string): string => `/projects/${slug ?? ":slug"}`,
Articles: "/articles",
Article: (slug?: string): string => `/articles/${slug ?? ":slug"}`,
Tags: "/tags",
Tag: (slug?: string): string => `/tags/${slug ?? ":slug"}`,
Certifications: "/certifications",
Books: "/books",
Contact: "/contact",
Colors: "/colors",
Settings: "/settings",
};
const NavController: FC = () => {
const dispatch = useAppDispatch();
const [prevPath, setPrevPath] = useState<string | null>(null);
const location = useLocation();
const pathname = location.pathname;
const title = useTitle();
const withTrailingSlash = pathname.charAt(pathname.length - 1) === "/";
const normalizedPath = withTrailingSlash ? pathname.slice(0, -1) : pathname;
useEffect(() => {
if (normalizedPath === prevPath) {
dispatch(
modifyLastHistory({
pathname: normalizedPath,
title,
})
);
} else {
dispatch(addToHistory({ pathname: normalizedPath, title }));
setPrevPath(normalizedPath);
window.scrollTo(0, 0);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [normalizedPath, title, dispatch]);
if (withTrailingSlash)
return (
<>
<Redirect to={{ ...location, pathname: pathname.slice(0, -1) }} />
<ScrollToTop />
</>
);
return <ScrollToTop />;
};
const useScrollToTopStyles = makeStyles((theme) => ({
scrollToTop: {
position: "fixed",
bottom: theme.spacing(2),
right: theme.spacing(2),
zIndex: 1000,
},
}));
const ScrollToTop: FC = () => {
const classes = useScrollToTopStyles();
const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 100,
});
const onClick = () => scrollToTop();
return (
<Zoom in={trigger}>
<div className={classes.scrollToTop} onClick={onClick}>
<Fab color="secondary" size="small" title="Scroll to Top">
<KeyboardArrowUp />
</Fab>
</div>
</Zoom>
);
};
export default NavController;