Skip to content

Commit

Permalink
#150 Add connections page (#157)
Browse files Browse the repository at this point in the history
Co-authored-by: Neven Dyulgerov <neven.diulgerov@gmail.com>
Co-authored-by: Bruno Menezes <brunodmenezes@gmail.com>
  • Loading branch information
nevendyulgerov and brunomenezes committed Apr 30, 2024
1 parent 13eae66 commit 289b538
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 90 deletions.
25 changes: 25 additions & 0 deletions apps/web/src/app/connections/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Stack } from "@mantine/core";
import { Metadata } from "next";
import ConnectionView from "../../components/connection/connectionView";
import Breadcrumbs from "../../components/breadcrumbs";

export const metadata: Metadata = {
title: "Connections",
};

export default function InputsPage() {
return (
<Stack>
<Breadcrumbs
breadcrumbs={[
{
href: "/",
label: "Home",
},
]}
/>

<ConnectionView />
</Stack>
);
}
2 changes: 1 addition & 1 deletion apps/web/src/components/connection/connectionInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const ConnectionInfo: FC<ConnectionInfoProps> = ({ connection }) => {
const { removeConnection } = useConnectionConfig();
const theme = useMantineTheme();
return (
<Card withBorder py="lg" my="md" radius="sm" shadow="sm">
<Card withBorder py="lg" radius="sm" shadow="sm">
<Card.Section inheritPadding withBorder>
<Flex justify="space-between">
<Address value={connection.address} shorten icon />
Expand Down
57 changes: 21 additions & 36 deletions apps/web/src/components/connection/connectionView.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
"use client";
import {
Avatar,
Button,
Collapse,
Grid,
Group,
ScrollArea,
Text,
Title,
VisuallyHidden,
useMantineTheme,
VisuallyHidden,
} from "@mantine/core";
import { useDisclosure, useViewportSize } from "@mantine/hooks";
import { TbChevronDown, TbChevronUp, TbPlus } from "react-icons/tb";
import { TbPlus } from "react-icons/tb";
import { useConnectionConfig } from "../../providers/connectionConfig/hooks";
import ConnectionInfo from "./connectionInfo";

const ConnectionView = () => {
const [showConnectionList, { toggle: toggleConnectionList }] =
useDisclosure(true);
const { showConnectionModal } = useConnectionConfig();
const { height: viewportHeight } = useViewportSize();
const { listConnections, showConnectionModal } = useConnectionConfig();
const theme = useMantineTheme();
const { listConnections } = useConnectionConfig();
const connections = listConnections();
const hasConnections = connections.length > 0;

Expand All @@ -36,43 +31,33 @@ const ConnectionView = () => {
<TbPlus />
<VisuallyHidden>Create connection</VisuallyHidden>
</Button>

<Title size="h2">Connections</Title>
{hasConnections && (
<Avatar size="sm" color={theme.primaryColor}>
{connections.length}
</Avatar>
)}
</Group>
<Button variant="transparent" onClick={toggleConnectionList}>
{showConnectionList ? (
<>
<TbChevronUp size={theme.other.iconSize} />
<VisuallyHidden>Hide connections</VisuallyHidden>
</>
) : (
<>
<TbChevronDown size={theme.other.iconSize} />
<VisuallyHidden>Show connections</VisuallyHidden>
</>
)}
</Button>
</Group>
<Collapse in={showConnectionList}>
<ScrollArea h={viewportHeight / 2} type="never">

{hasConnections ? (
<Grid gutter="sm">
{connections.map((connection) => (
<ConnectionInfo
<Grid.Col
key={connection.address}
connection={connection}
/>
span={{ base: 12, sm: 6 }}
mt="md"
>
<ConnectionInfo connection={connection} />
</Grid.Col>
))}

{!hasConnections && (
<Text c="dimmed" py="sm">
Create your first connection.
</Text>
)}
</ScrollArea>
</Collapse>
</Grid>
) : (
<Text c="dimmed" py="sm" ta="center">
No connections found.
</Text>
)}
</>
);
};
Expand Down
48 changes: 26 additions & 22 deletions apps/web/src/components/layout/shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,22 @@ import { ConnectButton } from "@rainbow-me/rainbowkit";
import Link from "next/link";
import { FC, ReactNode } from "react";
import {
TbAdjustmentsHorizontal,
TbApps,
TbArrowsDownUp,
TbDotsVertical,
TbHome,
TbInbox,
TbMoonStars,
TbPlugConnected,
TbSun,
} from "react-icons/tb";
import { useAccount } from "wagmi";
import CartesiLogo from "../../components/cartesiLogo";
import ConnectionView from "../../components/connection/connectionView";
import Footer from "../../components/layout/footer";
import SendTransaction from "../../components/sendTransaction";

const Shell: FC<{ children: ReactNode }> = ({ children }) => {
const [opened, { toggle }] = useDisclosure();
const [menuOpened, { toggle: toggleMenu }] = useDisclosure(false);
const [opened, { toggle: toggleMobileMenu }] = useDisclosure();
const [
transaction,
{
Expand All @@ -51,7 +50,9 @@ const Shell: FC<{ children: ReactNode }> = ({ children }) => {
`(min-width:${theme.breakpoints.sm}) and (max-width:${50}em)`,
);
const { isConnected } = useAccount();
const { colorScheme, toggleColorScheme } = useMantineColorScheme();
const { colorScheme, toggleColorScheme } = useMantineColorScheme({
keepTransitions: true,
});
const themeDefaultProps = theme.components?.AppShell?.defaultProps ?? {};

return (
Expand All @@ -64,13 +65,6 @@ const Shell: FC<{ children: ReactNode }> = ({ children }) => {
mobile: !opened,
},
}}
aside={{
...themeDefaultProps?.aside,
collapsed: {
desktop: !menuOpened,
mobile: !menuOpened,
},
}}
padding="md"
>
<Modal
Expand All @@ -85,7 +79,7 @@ const Shell: FC<{ children: ReactNode }> = ({ children }) => {
<Burger
data-testid="burger-menu-btn"
opened={opened}
onClick={toggle}
onClick={toggleMobileMenu}
hiddenFrom="sm"
size="sm"
/>
Expand Down Expand Up @@ -141,29 +135,23 @@ const Shell: FC<{ children: ReactNode }> = ({ children }) => {
/>
</Group>
</Group>
<Button variant="subtle" onClick={toggleMenu}>
<TbDotsVertical size={theme.other.iconSize} />
</Button>
</Group>
</AppShell.Header>
<AppShell.Aside p="md" zIndex={102}>
<ConnectionView />
</AppShell.Aside>
<AppShell.Navbar py="md" px={4} data-testid="navbar">
<Stack px={13}>
<NavLink
component={Link}
label="Home"
href="/"
leftSection={<TbHome />}
onClick={toggle}
onClick={toggleMobileMenu}
data-testid="home-link"
/>

<NavLink
component={Link}
label="Applications"
onClick={toggle}
onClick={toggleMobileMenu}
href="/applications"
leftSection={<TbApps />}
data-testid="applications-link"
Expand All @@ -172,12 +160,28 @@ const Shell: FC<{ children: ReactNode }> = ({ children }) => {
<NavLink
component={Link}
label="Inputs"
onClick={toggle}
onClick={toggleMobileMenu}
href="/inputs"
leftSection={<TbInbox />}
data-testid="inputs-link"
/>

<NavLink
label="Settings"
leftSection={<TbAdjustmentsHorizontal />}
data-testid="settings-link"
childrenOffset="xs"
>
<NavLink
component={Link}
onClick={toggleMobileMenu}
label="Connections"
leftSection={<TbPlugConnected />}
href="/connections"
data-testid="connections-link"
/>
</NavLink>

<NavLink
component="button"
data-testid="menu-item-send-transaction"
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/providers/theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const themeOverride: MantineThemeOverride = createTheme({
breakpoint: "sm",
},
aside: {
width: 400,
width: 0,
breakpoint: "sm",
},
},
Expand Down
30 changes: 1 addition & 29 deletions apps/web/test/components/connection/connectionView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ describe("Connection view component", () => {

expect(screen.getByText("Create connection")).toBeInTheDocument();
expect(screen.getByText("Connections")).toBeInTheDocument();
expect(
screen.getByText("Create your first connection."),
).toBeInTheDocument();
expect(screen.getByText("No connections found.")).toBeInTheDocument();
});

it("should call the creation form when clicking the plus sign", () => {
Expand Down Expand Up @@ -79,30 +77,4 @@ describe("Connection view component", () => {

expect(removeConnection).toHaveBeenCalledWith(connections[0].address);
});

it("should hide the connections when clicking the chevron-up icon", () => {
const { listConnections } = useConnectionConfigReturnStub;
listConnections.mockReturnValue(connections);

render(<View />);

expect(screen.queryByText(connections[0].url)).toBeVisible();

fireEvent.click(screen.getByText("Hide connections"));

expect(screen.queryByText(connections[0].url)).not.toBeVisible();
});

it("should show the connections when clicking the chevron-down icon", () => {
const { listConnections } = useConnectionConfigReturnStub;
listConnections.mockReturnValue(connections);

render(<View />);

fireEvent.click(screen.getByText("Hide connections"));
expect(screen.queryByText(connections[0].url)).not.toBeVisible();

fireEvent.click(screen.getByText("Show connections"));
expect(screen.queryByText(connections[0].url)).toBeVisible();
});
});
40 changes: 39 additions & 1 deletion apps/web/test/components/layout/shell.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { render, screen, within } from "@testing-library/react";
import {
fireEvent,
render,
screen,
waitFor,
within,
} from "@testing-library/react";
import { afterAll, describe, it } from "vitest";
import withMantineTheme from "../../utils/WithMantineTheme";
import Shell from "../../../src/components/layout/shell";
Expand Down Expand Up @@ -169,5 +175,37 @@ describe("Shell component", () => {

expect(navbar).toBeVisible();
});

it("should display settings menu in navbar", () => {
render(<Component>Children</Component>);

expect(
within(screen.getByTestId("navbar")).getByTestId(
"settings-link",
),
).toBeInTheDocument();
});

it("should display connections link in settings menu", async () => {
render(<Component>Children</Component>);

const settingsMenu = within(
screen.getByTestId("navbar"),
).getByTestId("settings-link");

fireEvent.click(settingsMenu);

await waitFor(() =>
expect(
screen.getByTestId("connections-link"),
).toBeInTheDocument(),
);

await waitFor(() =>
expect(
screen.getByTestId("connections-link").getAttribute("href"),
).toBe("/connections"),
);
});
});
});

0 comments on commit 289b538

Please sign in to comment.