Skip to content

Commit

Permalink
Merge pull request #865 from CodeForAfrica/feat/blog_app_navbar
Browse files Browse the repository at this point in the history
@/engineeringblog App Navbar
  • Loading branch information
kilemensi authored Sep 2, 2024
2 parents 1daa3e4 + 36c35ab commit 13b879a
Show file tree
Hide file tree
Showing 31 changed files with 468 additions and 121 deletions.
17 changes: 0 additions & 17 deletions apps/engineeringblog/app/StyledRoot.tsx

This file was deleted.

Binary file added apps/engineeringblog/app/apple-touch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/engineeringblog/app/favicon.ico
Binary file not shown.
Binary file added apps/engineeringblog/app/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 21 additions & 11 deletions apps/engineeringblog/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import Navbar from "@/engineeringblog/components/Navbar";
import { CssBaseline, ThemeProvider } from "@mui/material";
import { AppRouterCacheProvider } from "@mui/material-nextjs/v13-appRouter";
import StyledRoot from "./StyledRoot";
import type { Metadata } from "next";

const inter = Inter({ subsets: ["latin"] });
import NavBar from "@/engineeringblog/components/NavBar";
import theme from "@/engineeringblog/theme";

// TODO: blurWidth/blueHeight https://github.com/vercel/next.js/issues/56511
import logoLight from "@/engineeringblog/assets/images/logo-light.png";

export const metadata: Metadata = {
title: "Code For Africa Engineering",
description: "The homepage of CFA engineering blog",
title: "Technology | Code for Africa",
description:
"Tech adventures in Africa's civic labs: Coding, innovating, and disrupting for good across the continent.",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const logo = {
...logoLight,
alt: "Technology | Code for Africa",
title: "Technology",
};

return (
<html lang="en">
<body className={inter.className}>
<body>
<AppRouterCacheProvider>
<StyledRoot>
<Navbar />
<ThemeProvider theme={theme}>
<CssBaseline enableColorScheme />
<NavBar logo={logo} />
{children}
</StyledRoot>
</ThemeProvider>
</AppRouterCacheProvider>
</body>
</html>
Expand Down
Binary file added apps/engineeringblog/app/openGraphImage.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion apps/engineeringblog/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { Box, Container } from "@mui/material";

export default function index() {
return <div>Homepage</div>;
return (
<Container>
<Box minHeight="1000px">Homepage</Box>
</Container>
);
}
6 changes: 6 additions & 0 deletions apps/engineeringblog/app/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Disallow specifies the paths that are not allowed to be crawled by the robot.
User-agent: *
Disallow: /


# Generatedy by RoboShield (https://roboshield.trustlab.africa)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file added apps/engineeringblog/assets/images/logo-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file added apps/engineeringblog/assets/images/logo-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
105 changes: 105 additions & 0 deletions apps/engineeringblog/components/Logo/Logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Link, Stack, SvgIcon } from "@mui/material";
import { SxProps, Theme } from "@mui/material/styles";
import Image, { ImageProps } from "next/image";
import React from "react";

import PreviousIcon from "@/engineeringblog/assets/icons/Type=chevron-left, Size=24, Color=CurrentColor.svg";

export interface LogoProps extends ImageProps {
href?: string;
sx?: SxProps<Theme>;
title?: string;
}

const Logo = React.forwardRef(function Logo(
props: LogoProps,
ref: React.ForwardedRef<HTMLDivElement>,
) {
const {
alt,
href: hrefProp,
src,
sx,
title,
...other // All next/image supported props
} = props;
const logoHref = title?.length ? "https://codeforafrica.org" : "/";

return (
<Stack
direction="row"
spacing={1}
sx={{
color: "inherit",
alignItems: "center",
position: "relative",
...sx,
}}
ref={ref}
>
<Link
color="inherit"
href={logoHref}
sx={(theme) => ({
"&>svg,&>img": {
transition: theme.transitions.create(["opacity", "transform"]),
},
"&:hover": {
"&>svg,&>img": {
opacity: 0.65,
},
"&>svg": {
transform: "translateX(-5px)",
},
},
})}
>
{title?.length ? (
<SvgIcon
sx={(theme) => ({
fill: { xs: "none" },
fontSize: 32,
left: -24,
opacity: 0,
position: "absolute",
right: 0,
})}
>
<PreviousIcon />
</SvgIcon>
) : null}
<Image
{...other}
alt={alt}
priority
src={src}
style={{
height: 32,
width: "auto",
}}
/>
</Link>
{title?.length ? (
<Link
color="text.primary"
href="/"
textTransform="uppercase"
typography="h4"
underline="none"
sx={({ transitions, typography }) => ({
display: "flex",
fontFamily: typography.fontFamilyMono,
transition: transitions.create(["opacity", "transform"]),
"&:hover": {
opacity: 0.65,
},
})}
>
Technology
</Link>
) : null}
</Stack>
);
});

export default Logo;
5 changes: 5 additions & 0 deletions apps/engineeringblog/components/Logo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { LogoProps } from "./Logo";
import Logo from "./Logo";

export type { LogoProps };
export default Logo;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Grid } from "@mui/material";
import React from "react";

import Logo from "@/engineeringblog/components/Logo";
import type NavBarProps from "@/engineeringblog/components/NavBar/NavBarProps";

const DesktopNavBar = React.forwardRef(function DesktopNavBar(
props: NavBarProps,
ref: React.ForwardedRef<HTMLDivElement>,
) {
const { logo, sx } = props;

return (
<Grid
container
justifyContent="space-between"
alignItems="center"
sx={sx}
ref={ref}
>
<Grid item>
<Logo {...logo} />
</Grid>
</Grid>
);
});

export default DesktopNavBar;
3 changes: 3 additions & 0 deletions apps/engineeringblog/components/NavBar/DesktopNavBar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import DesktopNavBar from "./DesktopNavBar";

export default DesktopNavBar;
107 changes: 107 additions & 0 deletions apps/engineeringblog/components/NavBar/MobileNavBar/MobileNavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {
Dialog,
DialogContent,
Grid,
IconButton,
Slide,
SlideProps,
SvgIcon,
} from "@mui/material";
import { styled } from "@mui/material/styles";
import React from "react";

import type NavBarProps from "@/engineeringblog/components/NavBar/NavBarProps";
import Logo from "@/engineeringblog/components/Logo";
import CloseIcon from "@/engineeringblog/assets/icons/Type=x, Size=24, Color=CurrentColor.svg";
import MenuIcon from "@/engineeringblog/assets/icons/Type=menu, Size=24, Color=CurrentColor.svg";

const DialogContainer = styled(Dialog)(({ theme: { palette, spacing } }) => ({
marginTop: "49px", // NavBar has 1px bottom border
"& .MuiDialog-container": {
height: "100%",
},
"& .MuiBackdrop-root": {
background: "transparent",
},
"& .MuiDialogContent-root": {
padding: spacing(5),
color: palette.text.primary,
background: palette.background.default,
},
}));

interface TransitionProps extends SlideProps {}

const Transition = React.forwardRef(function Transition(
props: TransitionProps,
ref,
) {
return <Slide direction="up" ref={ref} {...props} />;
});

const MobileNavBar = React.forwardRef(function MobileNavBar(
props: NavBarProps,
ref: React.ForwardedRef<HTMLDivElement>,
) {
const { logo, sx } = props;
const [open, setOpen] = React.useState(false);

const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const MenuActionIcon = open ? CloseIcon : MenuIcon;

return (
<Grid
container
justifyContent="space-between"
alignItems="center"
sx={{
color: "text.primary",
...sx,
}}
ref={ref}
>
<Grid item>
<Logo {...logo} />
</Grid>
<Grid item>
<IconButton color="inherit" onClick={handleClickOpen} sx={{ p: 0 }}>
<SvgIcon
sx={{
fill: { xs: "none" },
fontSize: 32,
}}
>
<MenuActionIcon />
</SvgIcon>
</IconButton>
<DialogContainer
PaperProps={{ elevation: 0 }}
fullScreen
onClose={handleClose}
TransitionComponent={Transition}
aria-labelledby="mobile-navbar-dialog"
open={open}
>
<DialogContent
id="mobile-navbar-dialog"
sx={{
m: 0,
p: 0,
display: "flex",
color: "inherit",
justifyContent: "space-between",
alignItems: "flex-start",
}}
></DialogContent>
</DialogContainer>
</Grid>
</Grid>
);
});

export default MobileNavBar;
3 changes: 3 additions & 0 deletions apps/engineeringblog/components/NavBar/MobileNavBar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import MobileNavBar from "./MobileNavBar";

export default MobileNavBar;
Loading

0 comments on commit 13b879a

Please sign in to comment.