Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add link to logo #634

Closed
wants to merge 8 commits into from
1 change: 1 addition & 0 deletions packages/ui/src/components/loader/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./loader";
23 changes: 23 additions & 0 deletions packages/ui/src/components/loader/loader.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { render, screen } from "@testing-library/react";
import Loader from "./loader";

// Test case for basic rendering and text
test("Renders the Loader component correctly", () => {
render(<Loader />);
const loader = screen.getByTestId("loader");
expect(loader).toBeInTheDocument();
expect(loader).toHaveTextContent("Loading...");
});

// Test case for styling props
test("Renders loader with custom background color", () => {
render(<Loader backgroundColor="amber-500" />);
const loader = screen.getByTestId("loader");
expect(loader).toHaveStyle({ backgroundColor: "rgb(245 158 11)" });
});

test("Renders loader with custom height", () => {
render(<Loader height="40" />);
const loader = screen.getByTestId("loader");
expect(loader).toHaveClass("h-40");
});
60 changes: 60 additions & 0 deletions packages/ui/src/components/loader/loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
interface LoaderProps {
height?: string;
width?: string;
textColor?: string;
spinnerColor?: string;
spinnerSize?: string;
backgroundColor?: string;
}

const Loader: React.FC<LoaderProps> = ({
/**
* The height and width of the loader, using Tailwind CSS sizing classes.
* @default 'h-16' height: 4rem; (64px)
* @default 'w-16' width: 4rem; (64px)
*/
height = "16",
width = "16",
/**
* The color of the text within the loader, using a Tailwind CSS color class.
* @default 'text-blue-500' color: rgb(59 130 246);
*/
textColor = "blue-500",
/**
* The color of the spinner within the loader.
* @default '#1d4ed8' branding color
*/
spinnerColor = "#1d4ed8",
/**
* The size of the spinner, using Tailwind CSS sizing classes.
* @default 'h-12 w-12' height: 3rem; width: 3rem; (48px)
*/
spinnerSize = "12",
/**
* The background color of the loader, using a Tailwind CSS color class.
* @default 'bg-gray-100' background-color: rgb(243 244 246);
*/
backgroundColor = "gray-100",
}) => {
return (
<div
data-testid="loader"
className={`bg-${backgroundColor} h-${height} w-${width} flex flex-col items-center justify-center`}>
<svg
className={`-ml-1 mb-2 mr-3 h-${spinnerSize} w-${spinnerSize} animate-spin text-white`}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path
className="opacity-75"
fill={spinnerColor}
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>

<p className={`text-${textColor} font-medium`}>Loading...</p>
</div>
);
};

export default Loader;
17 changes: 17 additions & 0 deletions packages/website/src/entities/branding/ui/logo.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { MemoryRouter } from "react-router-dom";
import Logo from "./logo";

test("clicking on the logo redirects to the home page", async () => {
render(
<MemoryRouter>
<Logo />
</MemoryRouter>,
);

const logo = screen.getByTestId("logo");
userEvent.click(logo);

expect(window.location.pathname).toBe("/");
});
9 changes: 7 additions & 2 deletions packages/website/src/entities/branding/ui/logo.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import BrandMark from "./brandmark.svg";
import { Link } from "react-router-dom";

export default function Logo() {
return (
<div className="flex items-center space-x-2">
/**
* reloadDocument - A property used in the Link component from React Router to skip client side routing and let the browser handle the transition normally (as if it were an <a href>).
* @typedef {boolean} reloadDocument
*/
<Link to="/" reloadDocument={false} data-testid="logo" className="flex items-center space-x-2">
<img src={BrandMark} alt="Parking Insights brand mark" />

<div className="select-none -space-y-1 font-semibold uppercase text-blue-600">
<p>Parking</p>
<p>Insights</p>
</div>
</div>
</Link>
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import OpenInNewIcon from "@mui/icons-material/OpenInNew";
import { VisualizationStub } from "@/shared/ui/visualization";
import React, { Suspense } from "react";
import Loader from "@lucky-parking/ui/src/components/loader";

interface CitationDataset {
name?: string;
Expand All @@ -15,6 +16,8 @@ interface CitationDataInsightsProps {
title: string;
}

const LazyVisualizationStub = React.lazy(() => import("@/shared/ui/visualization/visualization-stub"));

export default function CitationDataInsights(props: CitationDataInsightsProps) {
const { category, datasets, dates, onClick, stat, title } = props;

Expand All @@ -35,8 +38,10 @@ export default function CitationDataInsights(props: CitationDataInsightsProps) {
{datasets.map(({ name, data }, index) => (
<div className="flex flex-col" key={name || `${title}-${index}`}>
{name && <p className="paragraph-3 text-center font-semibold">{name}</p>}
{/*// @ts-ignore*/}
<VisualizationStub data={data} />
<Suspense fallback={<Loader height="64" width="full" />}>
{/*// @ts-ignore*/}
<LazyVisualizationStub data={data} />
</Suspense>
</div>
))}

Expand Down
Loading