mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
ec077c6191
Fix for #348 - migrate our NextJS project to a pure webpack project w/ a single bundle - [x] Switch from `next/link` to `react-router-dom`'s link > This part was easy - just change the import to `import { Link } from "react-router-dom"` and `<Link href={...} />` to `<Link to={...} />` - [x] Switch from `next/router` to `react-router-dom`'s paradigms (`useNavigation`, `useLocation`, and `useParams`) > `router.push` can be converted to `navigate(...)` (provided by the `useNavigate` hook) > `router.replace` can be converted `navigate(..., {replace: true})` > Query parameters (`const { query } = useRouter`) can be converted to `const query = useParams()`) - [x] Implement client-side routing with `react-router-dom` > Parameterized routes in NextJS like `projects/[organization]/[project]` would look like: > ``` > <Route path="projects"> > <Route path=":organization/:project"> > <Route index element={<ProjectPage />} /> > </Route> > </Route> > ``` I've hooked up a `build:analyze` command that spins up a server to show the bundle size: <img width="1303" alt="image" src="https://user-images.githubusercontent.com/88213859/157496889-87c5fdcd-fad1-4f2e-b7b6-437aebf99641.png"> The bundle looks OK, but there are some opportunities for improvement - the heavy-weight dependencies, like React, ReactDOM, Material-UI, and lodash could be brought in via a CDN: https://stackoverflow.com/questions/50645796/how-to-import-reactjs-material-ui-using-a-cdn-through-webpacks-externals
71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
import React from "react"
|
|
import Button from "@material-ui/core/Button"
|
|
import { makeStyles } from "@material-ui/core/styles"
|
|
import { Link } from "react-router-dom"
|
|
|
|
import { User } from "../../contexts/UserContext"
|
|
import { Logo } from "../Icons"
|
|
import { UserDropdown } from "./UserDropdown"
|
|
|
|
export interface NavbarProps {
|
|
user?: User
|
|
onSignOut: () => void
|
|
}
|
|
|
|
export const Navbar: React.FC<NavbarProps> = ({ user, onSignOut }) => {
|
|
const styles = useStyles()
|
|
return (
|
|
<div className={styles.root}>
|
|
<div className={styles.fixed}>
|
|
<Link to="/">
|
|
<Button className={styles.logo} variant="text">
|
|
<Logo fill="white" opacity={1} />
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
<div className={styles.fullWidth} />
|
|
<div className={styles.fixed}>{user && <UserDropdown user={user} onSignOut={onSignOut} />}</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const useStyles = makeStyles((theme) => ({
|
|
root: {
|
|
position: "relative",
|
|
display: "flex",
|
|
flex: "0",
|
|
flexDirection: "row",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
height: "56px",
|
|
background: theme.palette.navbar.main,
|
|
marginTop: 0,
|
|
transition: "margin 150ms ease",
|
|
"@media (display-mode: standalone)": {
|
|
borderTop: `1px solid ${theme.palette.divider}`,
|
|
},
|
|
borderBottom: `1px solid #383838`,
|
|
},
|
|
fixed: {
|
|
flex: "0",
|
|
},
|
|
fullWidth: {
|
|
flex: "1",
|
|
},
|
|
logo: {
|
|
flex: "0",
|
|
height: "56px",
|
|
paddingLeft: theme.spacing(4),
|
|
paddingRight: theme.spacing(2),
|
|
borderRadius: 0,
|
|
"& svg": {
|
|
display: "block",
|
|
width: 125,
|
|
},
|
|
},
|
|
title: {
|
|
flex: "1",
|
|
textAlign: "center",
|
|
},
|
|
}))
|