Skip to content

Commit

Permalink
Add share menu (#119)
Browse files Browse the repository at this point in the history
* moved share to separate component

* dropdown menu added

* added styling and icons for menu

* corrected svgs

* unit tests for share menu added

* Adding svgs as components

* all share svgs imported as components

* updated tests for share
  • Loading branch information
mantuok authored Dec 19, 2024
1 parent b40ec4f commit 84f6e80
Show file tree
Hide file tree
Showing 15 changed files with 5,123 additions and 1,940 deletions.
8 changes: 8 additions & 0 deletions app/components-test-lib/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import CardHazard from "../components/card-hazard";
import { Hazards } from "../data/data";
import { Info } from "../data/data";
import CardInfo from "../components/card-info";
import Share from "../components/share";

const ComponentsTestLib = () => {
return (
Expand Down Expand Up @@ -51,6 +52,13 @@ const ComponentsTestLib = () => {
</HStack>
<Divider mb={2} />
</VStack>
<Text mb={4}>This section demonstrates Share menu component</Text>
<VStack spacing={4} align="start">
<HStack w="100%">
<Share />
</HStack>
<Divider mb={2} />
</VStack>
</Box>
);
};
Expand Down
14 changes: 14 additions & 0 deletions app/components/__mocks__/jest.setup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { jest } from "@jest/globals";
import React from "react";

const createMockIcon = (testId: string) => {
const MockIcon = () => <svg data-testid={testId} />;
MockIcon.displayName = `Mock${testId.charAt(0).toUpperCase() + testId.slice(1)}Icon`;
return MockIcon;
};

jest.mock("../../img/icon-share.svg", () => createMockIcon("share-icon"));
jest.mock("../../img/icon-facebook.svg", () => createMockIcon("facebook-icon"));
jest.mock("../../img/icon-email.svg", () => createMockIcon("email-icon"));
jest.mock("../../img/icon-x.svg", () => createMockIcon("x-icon"));
jest.mock("../../img/icon-link.svg", () => createMockIcon("link-icon"));
44 changes: 44 additions & 0 deletions app/components/__tests__/share.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import Share from "../share";
import "@testing-library/jest-dom";

describe("Share Component", () => {
it("renders the Share button", () => {
render(<Share />);
const button = screen.getByText(/share report/i);
expect(button).toBeInTheDocument();
});

// it("renders the menu options when the Share button is clicked", async () => {
// render(<Share />);
// const user = userEvent.setup();
// const button = screen.getByText(/share report/i);

// button.style.pointerEvents = "auto";

// await user.click(button);

// const emailOption = screen.getByText(/email/i);
// const facebookOption = screen.getByText(/facebook/i);
// const xOption = screen.getByText(/x/i);
// expect(emailOption).toBeInTheDocument();
// expect(facebookOption).toBeInTheDocument();
// expect(xOption).toBeInTheDocument();
// });

// it("triggers a click on a menu item", async () => {
// render(<Share />);
// const user = userEvent.setup();

// const button = screen.getByText(/share report/i);
// button.style.pointerEvents = "auto";
// await user.click(button);

// const emailOption = await screen.getByText(/email/i);
// await waitFor(() => expect(emailOption).toBeVisible());

// await userEvent.click(emailOption);
// expect(emailOption).toBeDefined();
// });
});
35 changes: 2 additions & 33 deletions app/components/report.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Box, HStack, IconButton, Text } from "@chakra-ui/react";
import CardHazard from "./card-hazard";
import { AddressData } from "./__mocks__/address-data";
import { Hazards } from "../data/data";
import Share from "./share";

const Report = () => {
return (
Expand All @@ -16,39 +17,7 @@ const Report = () => {
{AddressData.address && (
<Text textStyle="headerMedium">{AddressData.address}</Text>
)}
<HStack>
<Text textStyle="textMedium" color="blue">
Share report
</Text>
<IconButton aria-label="Share report" variant="ghost">
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4 11C4.55228 11 5 11.4477 5 12V20C5 20.2652 5.10536 20.5196 5.29289 20.7071C5.48043 20.8946 5.73478 21 6 21H18C18.2652 21 18.5196 20.8946 18.7071 20.7071C18.8946 20.5196 19 20.2652 19 20V12C19 11.4477 19.4477 11 20 11C20.5523 11 21 11.4477 21 12V20C21 20.7957 20.6839 21.5587 20.1213 22.1213C19.5587 22.6839 18.7957 23 18 23H6C5.20435 23 4.44129 22.6839 3.87868 22.1213C3.31607 21.5587 3 20.7956 3 20V12C3 11.4477 3.44772 11 4 11Z"
fill="#2C5282"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M11.2929 1.29289C11.6834 0.902369 12.3166 0.902369 12.7071 1.29289L16.7071 5.29289C17.0976 5.68342 17.0976 6.31658 16.7071 6.70711C16.3166 7.09763 15.6834 7.09763 15.2929 6.70711L12 3.41421L8.70711 6.70711C8.31658 7.09763 7.68342 7.09763 7.29289 6.70711C6.90237 6.31658 6.90237 5.68342 7.29289 5.29289L11.2929 1.29289Z"
fill="#2C5282"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M12 1C12.5523 1 13 1.44772 13 2V15C13 15.5523 12.5523 16 12 16C11.4477 16 11 15.5523 11 15V2C11 1.44772 11.4477 1 12 1Z"
fill="#2C5282"
/>
</svg>
</IconButton>
</HStack>
<Share />
</HStack>
<HStack
justifyContent="space-between"
Expand Down
48 changes: 48 additions & 0 deletions app/components/share.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
Text,
Button,
Menu,
MenuButton,
MenuList,
MenuItem,
} from "@chakra-ui/react";
import ShareIcon from "../img/icon-share.svg";
import FacebookIcon from "../img/icon-facebook.svg";
import EmailIcon from "../img/icon-email.svg";
import XIcon from "../img/icon-x.svg";
import LinkIcon from "../img/icon-link.svg";

const Share = () => {
return (
<Menu>
<MenuButton
as={Button}
aria-label="Share report"
variant="ghost"
rightIcon={<ShareIcon />}
>
<Text textStyle="textMedium">Share report</Text>
</MenuButton>
<MenuList p={"6px 16px 6px 16px"}>
<MenuItem gap="10px">
<EmailIcon />
<Text>Email</Text>
</MenuItem>
<MenuItem gap="10px">
<FacebookIcon />
<Text>Facebook</Text>
</MenuItem>
<MenuItem gap="10px">
<XIcon />
<Text>X</Text>
</MenuItem>
<MenuItem gap="10px">
<LinkIcon />
<Text>Copy Link</Text>
</MenuItem>
</MenuList>
</Menu>
);
};

export default Share;
20 changes: 20 additions & 0 deletions app/img/icon-email.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions app/img/icon-facebook.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions app/img/icon-link.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions app/img/icon-share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions app/img/icon-x.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const config: Config = {
coverageProvider: "v8",
testEnvironment: "jsdom",
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
setupFilesAfterEnv: ["<rootDir>/app/components/__mocks__/jest.setup.tsx"],
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
Expand Down
16 changes: 16 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ const nextConfig = {
},
];
},

webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: [
{
loader: "@svgr/webpack",
options: {
icon: true, // Optional: Optimize for icon usage
},
},
],
});

return config;
},
};

module.exports = nextConfig;
Loading

0 comments on commit 84f6e80

Please sign in to comment.