Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2524c88
feat: draft resources section
jacobvjk Mar 24, 2026
a712b2d
update use cases
jacobvjk Mar 25, 2026
13ce687
update methodology page
jacobvjk Mar 25, 2026
a372ce8
update changelog page
jacobvjk Mar 25, 2026
5cfcb26
update contact page
jacobvjk Mar 25, 2026
2992c84
reorder resource pages in dropdown
jacobvjk Mar 25, 2026
366546f
update landing page
jacobvjk Mar 31, 2026
d944909
update page structure
jacobvjk Apr 8, 2026
11a99a3
update the content of how to and methodology pages
jacobvjk Apr 8, 2026
a40d44a
update format
jacobvjk Apr 8, 2026
96b5c70
final draft methodology page
jacobvjk Apr 10, 2026
9945b1f
clean up how to and methodology
jacobvjk Apr 13, 2026
cde056c
rename classifcation group 1
jacobvjk Apr 13, 2026
b17ce90
improve strucutre of methodology apge
jacobvjk Apr 13, 2026
70eea77
update steel technologies in methodology page
jacobvjk Apr 13, 2026
97c67b9
clarify content in methodology section
jacobvjk Apr 14, 2026
dbc14dd
add subtitles to collapsible boxes in methodlogy
jacobvjk Apr 14, 2026
c21bee8
improve callout boxes
jacobvjk Apr 14, 2026
b5a9b25
polish the how to page
jacobvjk Apr 14, 2026
0676bc6
polish the how to page
jacobvjk Apr 15, 2026
763b866
wording in methodology section
jacobvjk Apr 15, 2026
7a75462
update resource pages based on comms feedback
jacobvjk May 7, 2026
eabf71a
Merge branch 'main' into add-resources
jacobvjk May 7, 2026
264a4fb
update wording of updates category
jacobvjk May 11, 2026
66629e4
update the design of the resources, contact, and landing pages
jacobvjk May 13, 2026
98f2960
format
jacobvjk May 13, 2026
a3ceebe
comment out update categories
jacobvjk May 13, 2026
f3c0175
udpate structure of resource pages
jacobvjk May 13, 2026
08c3a68
add update article and adjsut hero design
jacobvjk May 15, 2026
18af5fc
clean up redirects
jacobvjk May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ import LegalPage from "./pages/LegalPage";
import PathwaySearch from "./pages/PathwaySearch";
import PathwayDetailPage from "./pages/PathwayDetailPage";
import LandingPage from "./pages/LandingPage";
import ContactPage from "./pages/ContactPage";
import EnvironmentBanner from "./components/EnvironmentBanner";
import {
ResourcesFaqPage,
ResourcesHowToChooseAPathwayPage,
ResourcesMethodologyPage,
ResourcesUpdatesPage,
ResourcesUseCasesPage,
} from "./pages/resources";

// Export the inner content for testing
export const AppContent = () => {
Expand Down Expand Up @@ -36,6 +44,32 @@ export const AppContent = () => {
path="/legal"
element={<LegalPage />}
/>

<Route
path="/contact"
element={<ContactPage />}
/>

<Route
path="/resources/methodology"
element={<ResourcesMethodologyPage />}
/>
<Route
path="/resources/how-to-choose-a-pathway"
element={<ResourcesHowToChooseAPathwayPage />}
/>
<Route
path="/resources/faq"
element={<ResourcesFaqPage />}
/>
<Route
path="/resources/use-cases"
element={<ResourcesUseCasesPage />}
/>
<Route
path="/resources/updates"
element={<ResourcesUpdatesPage />}
/>
</Routes>
</main>
{!isLandingPage && <Footer />}
Expand Down
29 changes: 29 additions & 0 deletions src/components/Header.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { MemoryRouter } from "react-router-dom";
import Header from "./Header";

Expand Down Expand Up @@ -29,4 +30,32 @@ describe("Header component", () => {
const logo = screen.getByAltText("RMI logo");
expect(logo).toBeInTheDocument();
});

it("shows Resources dropdown links", async () => {
renderHeader();
const user = userEvent.setup();

expect(
screen.getByRole("link", { name: "Contact Us" }),
).toBeInTheDocument();

await user.click(screen.getByRole("button", { name: /resources/i }));

const menuItems = screen.getAllByRole("menuitem");
expect(menuItems[0]).toHaveTextContent("How to choose a pathway");

expect(
screen.getByRole("menuitem", { name: "Methodology" }),
).toBeInTheDocument();
expect(
screen.getByRole("menuitem", { name: "Use cases" }),
).toBeInTheDocument();
expect(
screen.getByRole("menuitem", { name: "How to choose a pathway" }),
).toBeInTheDocument();
expect(screen.getByRole("menuitem", { name: "FAQs" })).toBeInTheDocument();
expect(
screen.getByRole("menuitem", { name: "Updates" }),
).toBeInTheDocument();
});
});
97 changes: 93 additions & 4 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from "react";
import React, { useEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";

export const HeaderBrand: React.FC = () => {
export const HeaderBrand: React.FC<{ to?: string }> = ({ to = "/" }) => {
return (
<Link
to="/pathway"
to={to}
className="flex items-center space-x-3 group transition-all duration-300"
>
<div>
Expand All @@ -25,10 +25,99 @@ export const HeaderBrand: React.FC = () => {
};

const Header: React.FC = () => {
const [resourcesOpen, setResourcesOpen] = useState(false);
const menuRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
if (!resourcesOpen) return;
const onDocClick = (e: MouseEvent) => {
const target = e.target as Node;
if (menuRef.current && !menuRef.current.contains(target)) {
setResourcesOpen(false);
}
};

document.addEventListener("mousedown", onDocClick);
return () => document.removeEventListener("mousedown", onDocClick);
}, [resourcesOpen]);

return (
<header className="bg-bluespruce text-white shadow-md">
<header className="relative z-50 bg-bluespruce text-white shadow-md">
<div className="container mx-auto px-4 py-4 flex flex-col md:flex-row justify-between items-center">
<HeaderBrand />

<nav className="mt-3 md:mt-0 flex items-center gap-2">
<Link
to="/contact"
className="inline-flex items-center gap-2 rounded-md px-3 py-2 text-sm font-semibold text-white/90 hover:text-white hover:bg-white/10 transition-colors"
>
Contact Us
</Link>

<div
ref={menuRef}
className="relative"
>
<button
type="button"
className="inline-flex items-center gap-2 rounded-md px-3 py-2 text-sm font-semibold text-white/90 hover:text-white hover:bg-white/10 transition-colors"
aria-haspopup="menu"
aria-expanded={resourcesOpen}
onClick={() => setResourcesOpen((v) => !v)}
>
Resources
<span className="text-white/70">▾</span>
</button>

{resourcesOpen && (
<div
role="menu"
className="absolute right-0 z-[60] mt-2 w-72 overflow-hidden rounded-md bg-white text-rmigray-800 shadow-lg ring-1 ring-black/5"
>
<Link
role="menuitem"
to="/resources/how-to-choose-a-pathway"
className="block px-4 py-3 text-sm hover:bg-neutral-100"
onClick={() => setResourcesOpen(false)}
>
How to choose a pathway
</Link>
<Link
role="menuitem"
to="/resources/use-cases"
className="block px-4 py-3 text-sm hover:bg-neutral-100"
onClick={() => setResourcesOpen(false)}
>
Use cases
</Link>
<Link
role="menuitem"
to="/resources/methodology"
className="block px-4 py-3 text-sm hover:bg-neutral-100"
onClick={() => setResourcesOpen(false)}
>
Methodology
</Link>
<Link
role="menuitem"
to="/resources/updates"
className="block px-4 py-3 text-sm hover:bg-neutral-100"
onClick={() => setResourcesOpen(false)}
>
Updates
</Link>
<Link
role="menuitem"
to="/resources/faq"
className="block px-4 py-3 text-sm hover:bg-neutral-100"
onClick={() => setResourcesOpen(false)}
>
FAQs
</Link>
</div>
)}
</div>
</nav>
</div>
</header>
);
Expand Down
103 changes: 103 additions & 0 deletions src/pages/ContactPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React from "react";

const ContactPage: React.FC = () => {
return (
<div className="bg-gray-50">
<div className="container mx-auto px-4 py-8 md:py-10">
<section className="relative overflow-hidden rounded-[1.75rem] bg-rmiblue-800 px-6 py-8 text-white shadow-lg md:px-10 md:py-10">
<div className="absolute inset-0 bg-gradient-to-br from-white/8 via-transparent to-energy-700/10" />
<div className="absolute -right-10 top-0 h-32 w-32 rounded-full bg-white/7 blur-2xl" />
<div className="absolute bottom-0 left-0 h-36 w-36 rounded-full bg-energy-500/8 blur-2xl" />

<div className="relative">
<h1 className="text-3xl font-bold tracking-tight md:text-4xl">
Contact
</h1>

<div className="mt-6 space-y-4 text-sm leading-7 text-white/85 md:text-base">
<p>
We are building the Transition Pathways Repository to support
informed transition-related decisions by making pathway data
easier to access, understand, and apply.
</p>
<p>
We actively engage with financial institutions, companies,
policymakers, and other stakeholders to refine the tool, expand
its coverage, and improve its usability. Whether you are using
pathways in analysis, strategy, risk management, or policy
development, your input helps shape how the repository evolves.
</p>
</div>
</div>
</section>

<section className="mx-auto mt-12 max-w-5xl rounded-[2rem] border border-rmiblue-100 bg-rmiblue-50/60 px-6 py-8 shadow-sm md:px-8 md:py-10">
<div className="max-w-5xl">
<h2 className="text-2xl font-semibold text-rmigray-800">
How to reach us
</h2>
<p className="mt-4 text-rmigray-700 leading-7">
We welcome feedback, questions, and opportunities for
collaboration.
</p>
<p className="mt-4 text-rmigray-700 leading-7">
To get in touch, reach out to Tom White or Nayra Herrera at{" "}
<a
href="mailto:tomwhite+pbtar@rmi.org"
className="text-energy-700 underline underline-offset-2 hover:text-energy-800"
>
tomwhite@rmi.org
</a>{" "}
and{" "}
<a
href="mailto:nherrera+pbtar@rmi.org"
className="text-energy-700 underline underline-offset-2 hover:text-energy-800"
>
nherrera@rmi.org
</a>
, or open an issue on our{" "}
<a
href="https://github.com/RMI/pbtar/issues"
className="text-energy-700 underline underline-offset-2 hover:text-energy-800"
>
GitHub repository
</a>{" "}
with a short description of your request.
</p>
</div>

<div className="mt-10 border-t border-rmiblue-100 pt-8">
<h2 className="text-2xl font-semibold text-rmigray-800">
Feedback and suggestions
</h2>
<p className="mt-4 text-rmigray-700 leading-7">
We welcome feedback of all kinds and encourage you to share your
experience, questions, and ideas for improvement.
</p>
<p className="mt-4 text-rmigray-700 leading-7">
We are especially interested in hearing about:
</p>

<ul className="mt-5 list-disc space-y-3 pl-6 text-rmigray-700 marker:text-lg">
<li className="font-semibold leading-7">
Missing pathways or benchmarks
</li>
<li className="font-semibold leading-7">
Unclear classifications or assumptions
</li>
<li className="font-semibold leading-7">
Gaps in sector or regional coverage
</li>
<li className="font-semibold leading-7">Workflow pain points</li>
<li className="font-semibold leading-7">
Requests for training, guidance, or additional support
</li>
</ul>
</div>
</section>
</div>
</div>
);
};

export default ContactPage;
Loading