Skip to content

Commit 7dec359

Browse files
authored
Merge pull request #140 from mission-minded-llc/develop
feat: support demo theme menu, update Cypress theme tests.
2 parents 27ad171 + 48a3885 commit 7dec359

File tree

11 files changed

+208
-10
lines changed

11 files changed

+208
-10
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
describe("Primary Nav Menu", () => {
2+
it(`should visit 'davids' theme`, () => {
3+
cy.visit("/");
4+
cy.get("[data-testid=NavPrimaryMenuIcon]").click();
5+
cy.get("[data-testid=NavPrimaryMenuDemoThemes]").should("be.visible");
6+
cy.get("[data-testid=NavPrimaryMenuDemoThemes]").click();
7+
cy.get(`a[href='/demo/davids']`).click();
8+
cy.url().should("include", `/demo/davids`);
9+
});
10+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { ThemeDavidsPage } from "../../../pages/themeDavidsPage.cy";
2+
3+
const davidsPage = new ThemeDavidsPage();
4+
5+
describe("Theme Davids", () => {
6+
beforeEach(() => {
7+
davidsPage.getDavidsThemePage();
8+
cy.url().should("include", `/demo/davids`);
9+
});
10+
11+
// https://github.com/mission-minded-llc/ampdresume-theme/issues/40
12+
it.skip("should clear test input when filter change", () => {
13+
const testValue = "Test Skill";
14+
15+
davidsPage.selectFilter("Years of Experience");
16+
davidsPage.getSkillFilter().type(testValue).should("have.value", testValue);
17+
18+
davidsPage.selectFilter("Skill");
19+
20+
davidsPage.getSkillFilter().should("have.value", "");
21+
});
22+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
describe("Primary Nav Menu", () => {
2+
it(`should visit 'default' theme`, () => {
3+
cy.visit("/");
4+
cy.get("[data-testid=NavPrimaryMenuIcon]").click();
5+
cy.get("[data-testid=NavPrimaryMenuDemoThemes]").should("be.visible");
6+
cy.get("[data-testid=NavPrimaryMenuDemoThemes]").click();
7+
cy.get(`a[href='/demo/default']`).click();
8+
cy.url().should("include", `/demo/default`);
9+
});
10+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export class NavigationMenuPage {
2+
visitNavPrimaryMenu() {
3+
cy.visit("/");
4+
return cy.get("[data-testid=NavPrimaryMenuIcon]");
5+
}
6+
7+
getDavidsThemeItem() {
8+
return cy.get("a[href='/demo/davids']");
9+
}
10+
11+
getCloseView() {
12+
return cy.get("button[data-testid='nav-primary-menu-close-button']");
13+
}
14+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export class ThemeDavidsPage {
2+
getDavidsThemePage() {
3+
cy.visit("/demo/davids");
4+
}
5+
6+
getSkillFilter() {
7+
return cy.get('input[type="text"]').scrollIntoView().should("be.visible");
8+
}
9+
10+
getSkillFilterDropDown() {
11+
return cy.get('[data-testid="ArrowDropDownIcon"]').closest("button");
12+
}
13+
14+
getSkillFilterItem(skill) {
15+
return cy.contains("li", skill);
16+
}
17+
18+
selectFilter(skill) {
19+
this.getSkillFilterDropDown().click();
20+
this.getSkillFilterItem(skill).click();
21+
}
22+
}

src/app/components/NavPrimary.tsx

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { useSession } from "next-auth/react";
22
import React, { useState } from "react";
33
import CloseIcon from "@mui/icons-material/Close";
44
import MenuIcon from "@mui/icons-material/Menu";
5+
import ExpandLess from "@mui/icons-material/ExpandLess";
6+
import ExpandMore from "@mui/icons-material/ExpandMore";
57
import Box from "@mui/material/Box";
8+
import Collapse from "@mui/material/Collapse";
69
import Drawer from "@mui/material/Drawer";
710
import IconButton from "@mui/material/IconButton";
811
import List from "@mui/material/List";
@@ -15,6 +18,7 @@ import { MuiLink } from "@/components/MuiLink";
1518
import { useIsLoggedIn } from "@/hooks/useIsLoggedIn";
1619
import { getBaseUrl } from "@/util/url";
1720
import { ThemeAppearanceToggle } from "./ThemeAppearanceToggle";
21+
import { themeDefinitions } from "@/theme";
1822

1923
/**
2024
* The primary navigation component for the application. This nav is shared
@@ -25,6 +29,7 @@ export const NavPrimary = () => {
2529
const isLoggedIn = useIsLoggedIn();
2630

2731
const [isOpen, setIsOpen] = useState(false);
32+
const [demoThemesOpen, setDemoThemesOpen] = useState(false);
2833

2934
const baseUrl = getBaseUrl();
3035

@@ -39,6 +44,10 @@ export const NavPrimary = () => {
3944
setIsOpen(open);
4045
};
4146

47+
const toggleDemoThemes = () => {
48+
setDemoThemesOpen(!demoThemesOpen);
49+
};
50+
4251
const NavItemTitle = ({ text }: { text: string }) => (
4352
<Box
4453
sx={{
@@ -94,6 +103,83 @@ export const NavPrimary = () => {
94103
</MuiLink>
95104
);
96105

106+
const SubmenuItem = ({
107+
text,
108+
icon,
109+
href,
110+
target = "_self",
111+
dataTestId = "",
112+
}: {
113+
text: string;
114+
icon: string;
115+
href: string;
116+
target?: "_self" | "_blank";
117+
dataTestId?: string;
118+
}) => (
119+
<MuiLink
120+
href={href}
121+
target={target}
122+
sx={{
123+
textDecoration: "none",
124+
}}
125+
>
126+
<ListItem
127+
component="div"
128+
onClick={() => {
129+
setIsOpen(false);
130+
}}
131+
sx={(theme) => ({
132+
pl: 4,
133+
"&:hover": {
134+
backgroundColor: "black",
135+
color: "white",
136+
borderRight: `4px solid ${theme.palette.secondary.main}`,
137+
},
138+
})}
139+
{...(dataTestId && { "data-testid": dataTestId })}
140+
>
141+
<ListItemIcon>
142+
<Icon icon={icon} width={24} height={24} />
143+
</ListItemIcon>
144+
<ListItemText primary={text} />
145+
</ListItem>
146+
</MuiLink>
147+
);
148+
149+
const SubmenuHeader = ({
150+
text,
151+
icon,
152+
isOpen,
153+
onClick,
154+
dataTestId = "",
155+
}: {
156+
text: string;
157+
icon: string;
158+
isOpen: boolean;
159+
onClick: () => void;
160+
dataTestId?: string;
161+
}) => (
162+
<ListItem
163+
component="div"
164+
onClick={onClick}
165+
sx={(theme) => ({
166+
cursor: "pointer",
167+
"&:hover": {
168+
backgroundColor: "black",
169+
color: "white",
170+
borderRight: `4px solid ${theme.palette.secondary.main}`,
171+
},
172+
})}
173+
{...(dataTestId && { "data-testid": dataTestId })}
174+
>
175+
<ListItemIcon>
176+
<Icon icon={icon} width={36} height={36} />
177+
</ListItemIcon>
178+
<ListItemText primary={text} />
179+
{isOpen ? <ExpandLess /> : <ExpandMore />}
180+
</ListItem>
181+
);
182+
97183
return (
98184
<Box>
99185
<IconButton
@@ -146,6 +232,25 @@ export const NavPrimary = () => {
146232
href={baseUrl}
147233
dataTestId="NavPrimaryMenuHome"
148234
/>
235+
<SubmenuHeader
236+
text="Demo Themes"
237+
icon="fluent-color:image-48"
238+
isOpen={demoThemesOpen}
239+
onClick={toggleDemoThemes}
240+
dataTestId="NavPrimaryMenuDemoThemes"
241+
/>
242+
<Collapse in={demoThemesOpen} timeout="auto" unmountOnExit>
243+
<List component="div" disablePadding>
244+
{Object.entries(themeDefinitions).map(([key, theme]) => (
245+
<SubmenuItem
246+
text={theme.name}
247+
icon={theme.iconifyIcon}
248+
href={`/demo/${key}`}
249+
key={key}
250+
/>
251+
))}
252+
</List>
253+
</Collapse>
149254
{isLoggedIn ? (
150255
<>
151256
{session?.data?.user?.slug ? (

src/app/demo/[themeName]/page.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ describe("Theme Page", () => {
1919
it("should generate correct metadata for a theme", async () => {
2020
const metadata = await generateMetadata({ params });
2121

22-
expect(metadata.title).toBe(`Theme: ${themeName} ${titleSuffix}`);
22+
expect(metadata.title).toBe(`Theme: ${themeDefinitions[themeName].name} ${titleSuffix}`);
2323
expect(metadata.description).toBe(themeDefinitions[themeName].description);
2424
expect(Array.isArray(metadata.authors) && metadata.authors[0]?.name).toBe(
2525
themeDefinitions.default.authors[0].name,
2626
);
2727
expect(metadata.openGraph).toEqual({
28-
title: `Theme: ${themeName} ${titleSuffix}`,
28+
title: `Theme: ${themeDefinitions[themeName].name} ${titleSuffix}`,
2929
description: themeDefinitions[themeName].description,
3030
images: [],
3131
});

src/app/demo/[themeName]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export async function generateMetadata({
1212
}): Promise<Metadata> {
1313
const { themeName } = await params;
1414

15-
const title = `Theme: ${themeName} ${titleSuffix}`;
15+
const title = `Theme: ${themeDefinitions[themeName as ThemeName]?.name} ${titleSuffix}`;
1616

1717
const description =
1818
themeDefinitions[themeName as ThemeName]?.description ||

src/app/demo/[themeName]/pdf/page.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ describe("PDF Theme Page", () => {
2727
const metadata = await generateMetadata({ params: mockParams });
2828

2929
expect(metadata).toEqual({
30-
title: `PDF Theme: default ${titleSuffix}`,
30+
title: `PDF Theme: Classic ${titleSuffix}`,
3131
description: themeDefinitions.default.description,
3232
authors: themeDefinitions.default.authors.map((author) => ({
3333
name: author.name,
3434
url: author.gitHubUrl || author.linkedInUrl || "",
3535
})),
3636
openGraph: {
37-
title: `PDF Theme: default ${titleSuffix}`,
37+
title: `PDF Theme: Classic ${titleSuffix}`,
3838
description: themeDefinitions.default.description,
3939
images: [],
4040
},
@@ -48,7 +48,7 @@ describe("PDF Theme Page", () => {
4848
const metadata = await generateMetadata({ params: customThemeParams });
4949

5050
expect(metadata).toEqual({
51-
title: `PDF Theme: davids ${titleSuffix}`,
51+
title: `PDF Theme: David's Theme ${titleSuffix}`,
5252
description: themeDefinitions.davids.description,
5353
authors: [
5454
{
@@ -57,7 +57,7 @@ describe("PDF Theme Page", () => {
5757
},
5858
],
5959
openGraph: {
60-
title: `PDF Theme: davids ${titleSuffix}`,
60+
title: `PDF Theme: David's Theme ${titleSuffix}`,
6161
description: themeDefinitions.davids.description,
6262
images: [],
6363
},

src/app/demo/[themeName]/pdf/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export async function generateMetadata({
1212
}): Promise<Metadata> {
1313
const { themeName } = await params;
1414

15-
const title = `PDF Theme: ${themeName} ${titleSuffix}`;
15+
const title = `PDF Theme: ${themeDefinitions[themeName as ThemeName]?.name} ${titleSuffix}`;
1616

1717
const description =
1818
themeDefinitions[themeName as ThemeName]?.description ||

0 commit comments

Comments
 (0)