Skip to content

Add Projects section and new AppShell/Navbar components for new home …#885

Open
Mahimahto wants to merge 3 commits intotattle-made:mainfrom
Mahimahto:feat/navbar-appshell-new
Open

Add Projects section and new AppShell/Navbar components for new home …#885
Mahimahto wants to merge 3 commits intotattle-made:mainfrom
Mahimahto:feat/navbar-appshell-new

Conversation

@Mahimahto
Copy link
Copy Markdown
Collaborator

@Mahimahto Mahimahto commented Jan 30, 2026

Summary

This PR introduces the new Projects section and adds new AppShell and Navbar components for the redesigned home page, without modifying or overwriting any existing components.

What this PR includes

  • Created a new Projects parent component as per the Figma design
  • Implemented reusable ProjectCard components and rendered them dynamically
  • Added a config file to manage project data such as title, content, image, and links
  • Used the config list to pass data to ProjectCard components via props
  • Implemented the ProjectCard UI using background/border-image based styling as suggested in issue Get familiar with using background images for designer borders #875
  • Rendered the new Projects section on the new home page as part of the new route mentioned in issue Add new Route for the new design #873

New components added

  • NavbarNew: Created by copying the existing Navbar and updating it according to the new design
  • AppShellNew: Created by copying the existing AppShell to use the new Navbar in the redesigned layout

Important note

  • Existing Navbar and AppShell components have not been modified
  • All changes are isolated to newly created components to avoid impacting current pages

Summary by CodeRabbit

  • New Features
    • Redesigned navigation bar with improved responsive layout, centered logo, and streamlined links
    • New page shell providing dynamic page titles, enhanced metadata (including Open Graph) and analytics
    • New projects showcase section with styled project cards, images, descriptions and CTAs
    • New footer with newsletter signup mockup and contact links
    • New Resources and Updates sections presenting curated lists and decorative layout
    • Improved language initialization from local settings for multi-language support

@Mahimahto Mahimahto requested a review from maanasb01 January 30, 2026 09:55
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Adds a new page shell and navigation (AppShellNew, NavBarNew), a Projects showcase (ProjectCard, Projects, projects config), a Resources and Updates section, a new Footer, and updates new-home to use AppShellNew.

Changes

Cohort / File(s) Summary
Shell & Navigation
uli-website/src/components/molecules/AppShellNew.jsx, uli-website/src/components/molecules/NavBarNew.jsx, uli-website/src/components/molecules/FooterNew.jsx
Adds AppShellNew (Grommet wrapper, i18n init, dynamic title via Helmet, layout composition), a responsive NavBarNew with centered logo and links, and a new FooterNew component.
Projects feature
uli-website/src/components/molecules/ProjectCard.jsx, uli-website/src/components/molecules/Projects.jsx, uli-website/src/config/projects.js
Introduces ProjectCard (stylized card with image, title, description, CTAs), Projects section mapping projects config to cards with decorative SVG borders, and a projects array config (4 entries).
Resources & Updates
uli-website/src/components/molecules/ResourcesSection.jsx, uli-website/src/components/molecules/UpdatesSection.jsx
Adds ResourcesSection and UpdatesSection components rendering static lists with decorative borders and structured layouts.
Page update
uli-website/src/pages/new-home.js
Replaces previous shell with AppShellNew, removes placeholder header/description, preserves AnnouncementBanner content and adjusts surrounding structure.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • Issue #877: Implements ProjectCard, Projects, and projects config referenced by the issue.

Possibly related PRs

  • PR #882: Both modify src/pages/new-home.js — this PR replaces prior placeholder content with AppShellNew.
  • PR #883: Overlaps on src/pages/new-home.js and AnnouncementBanner integration.

Suggested reviewers

  • maanasb01

Poem

🐇 A new shell hops in, with nav and footer near,
Cards parade in rows, each project proud and clear.
Borders hum their tune, resources line the way,
The homepage springs alive — a rabbit cheers today! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding a Projects section and new AppShell/Navbar components for the redesigned home page.
Description check ✅ Passed The description provides a clear summary, lists new components, explains the approach, and notes that existing components remain unmodified, but omits testing steps and expected behavior details from the template.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
uli-website/src/pages/new-home.js (1)

9-20: ⚠️ Potential issue | 🟡 Minor

Avoid nesting <main> inside AppShellNew.
AppShellNew already provides a <main>, so this creates invalid HTML and can confuse screen readers. Use <section> or <div> here instead.

✅ Suggested fix
-    <AppShellNew>
-      <main>
+    <AppShellNew>
+      <section>
...
-      </main>
+      </section>
     </AppShellNew >
🤖 Fix all issues with AI agents
In `@uli-website/src/components/molecules/AppShellNew.jsx`:
- Around line 49-56: In AppShellNew.jsx inside the Helmet block, replace the
incorrect <meta name="icon" ... /> usage with a proper favicon link element;
locate the Helmet component in the AppShellNew.jsx file and change the meta tag
that sets name="icon" to a link element with rel="icon" and the same href
(optionally add type="image/png") so browsers register the favicon correctly.
- Around line 24-38: The computed title derived from location.pathname can be an
empty string for the root path ("/"), causing blank page/OG titles; modify the
logic around fullPath/title in AppShellNew.jsx (variables fullPath and title) to
detect when title === "" (or fullPath === "/") and set a default like "Uli"
before the language check and capitalization steps so the root page gets a
proper fallback title.

In `@uli-website/src/components/molecules/NavBarNew.jsx`:
- Around line 48-56: The centered logo Box is only clickable via mouse (onClick
=> navigate("/")) and must be keyboard-accessible; replace the Box with the same
NavLink/NavLink-like component used for left/right navigation or add proper
semantics: give the element tabIndex={0}, role="link" (or use a button/Link),
and handle onKeyDown to call navigate("/") for Enter/Space, ensuring focus
styles remain; update the element around the navigate("/") call (the Box) to
match NavLink usage so keyboard and screen-reader users can activate it.

In `@uli-website/src/components/molecules/ProjectCard.jsx`:
- Around line 52-55: ProjectCard currently renders two static "Install" buttons;
change this to accept CTA props (e.g., primaryCta, secondaryCta) that include
label and either href or onClick, use the existing btnStyle for styling, and
render each button conditionally only when its prop is present; for link CTAs
render an anchor (<a>) with href and rel/target as needed, otherwise render a
<button> with the onClick handler, and update the JSX where btnStyle is used so
labels come from primaryCta.label / secondaryCta.label instead of hardcoded
text.
🧹 Nitpick comments (1)
uli-website/src/components/molecules/ProjectCard.jsx (1)

38-42: Consider meaningful alt text (or mark the image decorative).
If the image conveys project info, pass an alt prop (e.g., {title} logo). If it’s purely decorative, add aria-hidden="true" to avoid empty alt noise.

Comment on lines +24 to +38
let fullPath = location.pathname;
if (fullPath.endsWith("/")) {
fullPath = fullPath.slice(0, -1);
}

let title = fullPath.split("/").at(-1);

if (["hi", "en", "ta", "ma"].includes(title)) {
title = "Uli";
}

title = title
.split("-")
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
.join(" ");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Ensure a default title for the root path.
When pathname === "/", title becomes an empty string, so the page title/OG title is blank. Add a fallback (e.g., “Uli”).

✅ Suggested fix
-  let title = fullPath.split("/").at(-1);
+  let title = fullPath.split("/").filter(Boolean).at(-1) || "Uli";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let fullPath = location.pathname;
if (fullPath.endsWith("/")) {
fullPath = fullPath.slice(0, -1);
}
let title = fullPath.split("/").at(-1);
if (["hi", "en", "ta", "ma"].includes(title)) {
title = "Uli";
}
title = title
.split("-")
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
.join(" ");
let fullPath = location.pathname;
if (fullPath.endsWith("/")) {
fullPath = fullPath.slice(0, -1);
}
let title = fullPath.split("/").filter(Boolean).at(-1) || "Uli";
if (["hi", "en", "ta", "ma"].includes(title)) {
title = "Uli";
}
title = title
.split("-")
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
.join(" ");
🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/AppShellNew.jsx` around lines 24 - 38,
The computed title derived from location.pathname can be an empty string for the
root path ("/"), causing blank page/OG titles; modify the logic around
fullPath/title in AppShellNew.jsx (variables fullPath and title) to detect when
title === "" (or fullPath === "/") and set a default like "Uli" before the
language check and capitalization steps so the root page gets a proper fallback
title.

Comment on lines +49 to +56
<Helmet>
<meta charSet="utf-8" />
<title>{title}</title>
<link rel="stylesheet" href="/layout.css" />
<link rel="stylesheet" href="https://use.typekit.net/twt1ywc.css" />
<meta property="og:title" content={title} />
<meta name="icon" href="images/favicon-32x32.png" />
<script
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use <link rel="icon"> instead of a meta tag.
<meta name="icon"> won’t register a favicon in browsers.

✅ Suggested fix
-          <meta name="icon" href="images/favicon-32x32.png" />
+          <link rel="icon" href="images/favicon-32x32.png" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Helmet>
<meta charSet="utf-8" />
<title>{title}</title>
<link rel="stylesheet" href="/layout.css" />
<link rel="stylesheet" href="https://use.typekit.net/twt1ywc.css" />
<meta property="og:title" content={title} />
<meta name="icon" href="images/favicon-32x32.png" />
<script
<Helmet>
<meta charSet="utf-8" />
<title>{title}</title>
<link rel="stylesheet" href="/layout.css" />
<link rel="stylesheet" href="https://use.typekit.net/twt1ywc.css" />
<meta property="og:title" content={title} />
<link rel="icon" href="images/favicon-32x32.png" />
<script
🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/AppShellNew.jsx` around lines 49 - 56,
In AppShellNew.jsx inside the Helmet block, replace the incorrect <meta
name="icon" ... /> usage with a proper favicon link element; locate the Helmet
component in the AppShellNew.jsx file and change the meta tag that sets
name="icon" to a link element with rel="icon" and the same href (optionally add
type="image/png") so browsers register the favicon correctly.

Comment on lines +48 to +56
<Box
style={{
position: size === "small" ? "static" : "absolute",
left: "50%",
transform: size === "small" ? "none" : "translateX(-50%)",
cursor: "pointer",
}}
onClick={() => navigate("/")}
>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "NavBarNew.jsx" -type f

Repository: tattle-made/Uli

Length of output: 111


🏁 Script executed:

cat -n uli-website/src/components/molecules/NavBarNew.jsx | head -80

Repository: tattle-made/Uli

Length of output: 2810


Make the center logo keyboard-accessible.
The clickable Box only handles mouse clicks, so keyboard users cannot activate it. Add keyboard semantics and handlers, or use a proper link/button element. The left and right navigation use NavLink for consistency—this should too.

✅ Suggested fix
          <Box
            style={{
              position: size === "small" ? "static" : "absolute",
              left: "50%",
              transform: size === "small" ? "none" : "translateX(-50%)",
              cursor: "pointer",
            }}
+           role="link"
+           tabIndex={0}
+           aria-label="Uli home"
            onClick={() => navigate("/")}
+           onKeyDown={(e) => {
+             if (e.key === "Enter" || e.key === " ") navigate("/");
+           }}
          >

This violates WCAG 2.1 Level A (2.1.1 Keyboard accessibility) since interactive elements must be operable via keyboard.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Box
style={{
position: size === "small" ? "static" : "absolute",
left: "50%",
transform: size === "small" ? "none" : "translateX(-50%)",
cursor: "pointer",
}}
onClick={() => navigate("/")}
>
<Box
style={{
position: size === "small" ? "static" : "absolute",
left: "50%",
transform: size === "small" ? "none" : "translateX(-50%)",
cursor: "pointer",
}}
role="link"
tabIndex={0}
aria-label="Uli home"
onClick={() => navigate("/")}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") navigate("/");
}}
>
🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/NavBarNew.jsx` around lines 48 - 56, The
centered logo Box is only clickable via mouse (onClick => navigate("/")) and
must be keyboard-accessible; replace the Box with the same NavLink/NavLink-like
component used for left/right navigation or add proper semantics: give the
element tabIndex={0}, role="link" (or use a button/Link), and handle onKeyDown
to call navigate("/") for Enter/Space, ensuring focus styles remain; update the
element around the navigate("/") call (the Box) to match NavLink usage so
keyboard and screen-reader users can activate it.

Comment on lines +52 to +55
<div style={{ display: "flex", gap: "18px" }}>
<button style={btnStyle}>Install</button>
<button style={btnStyle}>Install</button>
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Wire CTA buttons to real actions instead of hardcoded labels.
Both buttons are static and don’t trigger navigation or actions. If these are meant to be real CTAs (per the “links” requirement), thread labels + href/onClick through props and render them conditionally.

🛠️ Example approach
-const ProjectCard = ({ title, description, reverse }) => {
+const ProjectCard = ({ title, description, reverse, primaryCta, secondaryCta }) => {
...
-            <div style={{ display: "flex", gap: "18px" }}>
-              <button style={btnStyle}>Install</button>
-              <button style={btnStyle}>Install</button>
-            </div>
+            <div style={{ display: "flex", gap: "18px" }}>
+              {primaryCta && (
+                <a href={primaryCta.href} style={btnStyle}>
+                  {primaryCta.label}
+                </a>
+              )}
+              {secondaryCta && (
+                <a href={secondaryCta.href} style={btnStyle}>
+                  {secondaryCta.label}
+                </a>
+              )}
+            </div>
🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/ProjectCard.jsx` around lines 52 - 55,
ProjectCard currently renders two static "Install" buttons; change this to
accept CTA props (e.g., primaryCta, secondaryCta) that include label and either
href or onClick, use the existing btnStyle for styling, and render each button
conditionally only when its prop is present; for link CTAs render an anchor
(<a>) with href and rel/target as needed, otherwise render a <button> with the
onClick handler, and update the JSX where btnStyle is used so labels come from
primaryCta.label / secondaryCta.label instead of hardcoded text.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@uli-website/src/components/molecules/FooterNew.jsx`:
- Around line 29-32: The footer contains placeholder text in the FooterNew
component ("Short Statement about what Uli is") which will ship to production;
locate that JSX fragment in FooterNew.jsx and either replace the placeholder
with the final user-facing copy (e.g., a concise sentence describing Uli: "Uli
helps redact slurs and abusive content, archive problematic material, and
coordinate responses to online gender‑based violence.") or, if final copy isn't
available, wrap or remove the placeholder by adding an explicit TODO comment and
a safe fallback (empty string or non-visible comment) so the placeholder text is
not rendered in production; update the JSX in FooterNew accordingly.
- Around line 64-90: The footer currently uses placeholder text and hard-coded
horizontal layouts which will overflow on small screens; update the FooterNew
component to accept props/config for contact text (e.g., contactText) and an
array of links (e.g., links) and render them instead of the hard-coded "Link
1/2/3" and "Email & Other contacts"; also make the two Box containers that
currently use direction="row" (the outer Box with justify="between" and the
inner Box with gap="medium") responsive—switch to a column layout on small
viewports by using Grommet’s ResponsiveContext or a responsive direction prop
(e.g., direction={['column','row']} or compute direction from ResponsiveContext)
so items stack vertically on narrow screens while remaining row-aligned on
larger screens.
- Around line 36-60: The email subscription area in FooterNew.jsx currently uses
non-interactive Box/Text elements and must be replaced or wrapped with real form
controls: add a <form> element with an <input type="email"> (give it a
name/placeholder and aria-label) and replace the subscribe Box with a <button>
(or Anchor with role/button) so it is keyboard-focusable; implement an onSubmit
handler (e.g., handleSubscribe) on the form that validates the email and
triggers the subscription logic or a noop/coming-soon state, and ensure
accessible attributes (aria-live for success/error, required, and proper focus
styles) are included. Use the existing Box/Text layout but swap the static
subscribe Box for an actual button and wire input/button to the handler so
screen readers and keyboard users can interact.
🧹 Nitpick comments (1)
uli-website/src/components/molecules/FooterNew.jsx (1)

14-22: Hardcoded 48px font size may not scale well on mobile.

Consider using a Grommet responsive size (e.g., "xlarge") or a CSS clamp/media-query approach instead of the fixed 48px, so the heading adapts to smaller screens.

Comment on lines +29 to +32
Short Statement about what Uli is <br />
Use Uli to redact slurs and abusive content, archive problematic
content, and collectively push back against online gender based
violence.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Placeholder copy will ship to production.

Line 29 reads like a design-file placeholder ("Short Statement about what Uli is"), not final user-facing text. Please replace it with the intended copy or gate it behind a TODO so it isn't accidentally released.

🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/FooterNew.jsx` around lines 29 - 32, The
footer contains placeholder text in the FooterNew component ("Short Statement
about what Uli is") which will ship to production; locate that JSX fragment in
FooterNew.jsx and either replace the placeholder with the final user-facing copy
(e.g., a concise sentence describing Uli: "Uli helps redact slurs and abusive
content, archive problematic material, and coordinate responses to online
gender‑based violence.") or, if final copy isn't available, wrap or remove the
placeholder by adding an explicit TODO comment and a safe fallback (empty string
or non-visible comment) so the placeholder text is not rendered in production;
update the JSX in FooterNew accordingly.

Comment on lines +36 to +60
<Box
direction="row"
align="center"
width="medium"
pad="small"
background="#f6efe6"
round="xsmall"
justify="between"
>
<Text size="large">✉️</Text>

<Text size="small" color="#666">
your email address
</Text>

<Box
pad={{ horizontal: "medium", vertical: "xsmall" }}
background="#000"
round="xsmall"
>
<Text size="small" color="white">
subscribe
</Text>
</Box>
</Box>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Email subscription section is non-functional and inaccessible.

This renders a visual mockup of an email input and subscribe button, but there is no actual <input> element, no <form>, and no click/submit handler. Users (and screen readers) will see what looks like an interactive subscription form but cannot interact with it.

If this is intentionally a placeholder for a future feature, consider either:

  • Adding a TODO comment and visually indicating it's "coming soon," or
  • Wiring it up with a real <input> and <button>/<Anchor> so it's keyboard-navigable and functional.

As-is, the subscribe Box (line 51) is not focusable or activatable via keyboard.

Minimal sketch using real form elements
-        <Box
-          direction="row"
-          align="center"
-          width="medium"
-          pad="small"
-          background="#f6efe6"
-          round="xsmall"
-          justify="between"
-        >
-          <Text size="large">✉️</Text>
-
-          <Text size="small" color="#666">
-            your email address
-          </Text>
-
-          <Box
-            pad={{ horizontal: "medium", vertical: "xsmall" }}
-            background="#000"
-            round="xsmall"
-          >
-            <Text size="small" color="white">
-              subscribe
-            </Text>
-          </Box>
-        </Box>
+        {/* TODO: wire up subscription handler */}
+        <Box
+          as="form"
+          direction="row"
+          align="center"
+          width="medium"
+          pad="small"
+          background="#f6efe6"
+          round="xsmall"
+          justify="between"
+          onSubmit={(e) => { e.preventDefault(); /* handle subscribe */ }}
+        >
+          <Text size="large" aria-hidden="true">✉️</Text>
+          <input
+            type="email"
+            placeholder="your email address"
+            aria-label="Email address"
+            style={{ border: "none", background: "transparent", flex: 1, outline: "none" }}
+          />
+          <button
+            type="submit"
+            style={{
+              padding: "4px 16px",
+              background: "#000",
+              color: "#fff",
+              border: "none",
+              borderRadius: "4px",
+              cursor: "pointer",
+            }}
+          >
+            subscribe
+          </button>
+        </Box>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Box
direction="row"
align="center"
width="medium"
pad="small"
background="#f6efe6"
round="xsmall"
justify="between"
>
<Text size="large">✉️</Text>
<Text size="small" color="#666">
your email address
</Text>
<Box
pad={{ horizontal: "medium", vertical: "xsmall" }}
background="#000"
round="xsmall"
>
<Text size="small" color="white">
subscribe
</Text>
</Box>
</Box>
{/* TODO: wire up subscription handler */}
<Box
as="form"
direction="row"
align="center"
width="medium"
pad="small"
background="#f6efe6"
round="xsmall"
justify="between"
onSubmit={(e) => { e.preventDefault(); /* handle subscribe */ }}
>
<Text size="large" aria-hidden="true">✉️</Text>
<input
type="email"
placeholder="your email address"
aria-label="Email address"
style={{ border: "none", background: "transparent", flex: 1, outline: "none" }}
/>
<button
type="submit"
style={{
padding: "4px 16px",
background: "#000",
color: "#fff",
border: "none",
borderRadius: "4px",
cursor: "pointer",
}}
>
subscribe
</button>
</Box>
🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/FooterNew.jsx` around lines 36 - 60, The
email subscription area in FooterNew.jsx currently uses non-interactive Box/Text
elements and must be replaced or wrapped with real form controls: add a <form>
element with an <input type="email"> (give it a name/placeholder and aria-label)
and replace the subscribe Box with a <button> (or Anchor with role/button) so it
is keyboard-focusable; implement an onSubmit handler (e.g., handleSubscribe) on
the form that validates the email and triggers the subscription logic or a
noop/coming-soon state, and ensure accessible attributes (aria-live for
success/error, required, and proper focus styles) are included. Use the existing
Box/Text layout but swap the static subscribe Box for an actual button and wire
input/button to the handler so screen readers and keyboard users can interact.

Comment on lines +64 to +90
<Box
direction="row"
justify="between"
align="center"
margin={{ top: "large" }}
>
<Box>
<Text weight="bold" color="white">
Uli by Tattle
</Text>
<Text size="small" color="#cccccc">
Email & Other contacts
</Text>
</Box>

<Box direction="row" gap="medium">
<Text size="small" color="white">
Link 1
</Text>
<Text size="small" color="white">
Link 2
</Text>
<Text size="small" color="white">
Link 3
</Text>
</Box>
</Box>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bottom section uses placeholder links and won't stack on small viewports.

  1. "Link 1 / 2 / 3" and "Email & Other contacts" are clearly placeholder text — please replace with real content or wire them to config/props.
  2. The direction="row" layout on lines 64 and 79 will overflow or get cramped on narrow screens. Consider making it responsive:
Responsive direction example
      <Box
-       direction="row"
+       direction="row-responsive"
        justify="between"
        align="center"
        margin={{ top: "large" }}
      >
🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/FooterNew.jsx` around lines 64 - 90, The
footer currently uses placeholder text and hard-coded horizontal layouts which
will overflow on small screens; update the FooterNew component to accept
props/config for contact text (e.g., contactText) and an array of links (e.g.,
links) and render them instead of the hard-coded "Link 1/2/3" and "Email & Other
contacts"; also make the two Box containers that currently use direction="row"
(the outer Box with justify="between" and the inner Box with gap="medium")
responsive—switch to a column layout on small viewports by using Grommet’s
ResponsiveContext or a responsive direction prop (e.g.,
direction={['column','row']} or compute direction from ResponsiveContext) so
items stack vertically on narrow screens while remaining row-aligned on larger
screens.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@uli-website/src/components/molecules/AppShellNew.jsx`:
- Around line 69-72: AppShellNew currently hardcodes Projects, UpdatesSection,
and ResourcesSection after {children}, causing those sections to appear on every
page; remove these components from AppShellNew and either (a) move them into the
new home page component (e.g., new-home.js) so only that page renders them, or
(b) add a clear prop/flag on AppShellNew (e.g., showBottomSections) and
conditionally render Projects, UpdatesSection, and ResourcesSection based on
that prop; update the new-home.js page to pass the prop or to include the
sections itself and ensure any references to children in AppShellNew remain
unchanged.

In `@uli-website/src/components/molecules/ResourcesSection.jsx`:
- Around line 5-30: The resources array currently contains duplicate placeholder
items; add a clear TODO comment above the resources constant noting these are
placeholders to avoid being forgotten, and update each item object in the
resources array to include a url (or href) field with real links (or sensible
example URLs) and unique titles per section instead of repeating "Make It Real -
Mapping AI-Facilitated Gendered Harm"; then update the rendering in
ResourcesSection (the component that consumes the resources constant) to render
item.title as an anchor using item.url/item.href so resources become clickable
links.
- Line 48: In ResourcesSection.jsx the Box component using width="1100px" causes
horizontal overflow on small viewports; update the Box (the element that
currently has width="1100px") to use a responsive sizing approach—replace the
fixed width with maxWidth="1100px" and allow it to shrink (e.g., set
width="100%" or use sx to set width: "100%" and maxWidth: "1100px"), and
optionally center with mx="auto" so the layout remains fluid on narrow screens.

In `@uli-website/src/components/molecules/UpdatesSection.jsx`:
- Around line 6-11: The updates array in UpdatesSection.jsx currently contains
four identical static placeholder objects (symbol: updates) which risks being
left in production; replace these with real data or at minimum annotate the
array with a clear TODO comment and/or load real entries from props or a data
source (e.g., accept a prop like updates or fetchUpdates and map those into the
component) so each entry is unique and not a duplicated placeholder; ensure any
temporary placeholders are marked "TODO: replace placeholder updates" and update
the component (e.g., UpdatesSection) to use the prop/fetch instead of the
hardcoded updates.
🧹 Nitpick comments (2)
uli-website/src/components/molecules/UpdatesSection.jsx (1)

17-24: Decorative border pattern is duplicated across multiple components.

The top/bottom SVG border pattern (background-image, repeat-x, size, rotate) is repeated identically in ResourcesSection.jsx and Projects.jsx. Consider extracting a small DecorativeBorder component to reduce duplication.

Also applies to: 56-64

uli-website/src/components/molecules/AppShellNew.jsx (1)

17-23: Missing i18n in the useEffect dependency array.

The effect references i18n but the dependency array is empty. React's exhaustive-deps rule will warn. Since i18n is stable this is unlikely to cause a bug, but it should be listed for correctness.

Suggested fix
-  }, []);
+  }, [i18n]);

Comment on lines +69 to +72
<Box flex="grow">{children}</Box>
<Projects/>
<UpdatesSection/>
<ResourcesSection/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Page-specific sections are hardcoded inside the app shell.

Projects, UpdatesSection, and ResourcesSection are rendered after {children} on every page that uses AppShellNew. If only the new home page should display these sections, they belong in the page component (e.g., new-home.js), not in the shared shell. Otherwise, navigating to any other page wrapped in AppShellNew will also render these sections.

🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/AppShellNew.jsx` around lines 69 - 72,
AppShellNew currently hardcodes Projects, UpdatesSection, and ResourcesSection
after {children}, causing those sections to appear on every page; remove these
components from AppShellNew and either (a) move them into the new home page
component (e.g., new-home.js) so only that page renders them, or (b) add a clear
prop/flag on AppShellNew (e.g., showBottomSections) and conditionally render
Projects, UpdatesSection, and ResourcesSection based on that prop; update the
new-home.js page to pass the prop or to include the sections itself and ensure
any references to children in AppShellNew remain unchanged.

Comment on lines +5 to +30
const resources = [
{
heading: "For Platforms",
items: [
{ type: "Report", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
{ type: "Guidelines", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
{ type: "Database", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
],
},
{
heading: "For Educators",
items: [
{ type: "Report", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
{ type: "Guidelines", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
{ type: "Database", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
],
},
{
heading: "For Technologists",
items: [
{ type: "Report", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
{ type: "Guidelines", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
{ type: "Database", title: "Make It Real - Mapping AI-Facilitated Gendered Harm" },
],
},
];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

All resource items appear to be placeholder data.

Every section has identical items with the same title ("Make It Real - Mapping AI-Facilitated Gendered Harm"). If this is intentional placeholder content, consider adding a TODO comment so it's not forgotten. Also, resource items likely need a url/href field and should be rendered as links.

🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/ResourcesSection.jsx` around lines 5 -
30, The resources array currently contains duplicate placeholder items; add a
clear TODO comment above the resources constant noting these are placeholders to
avoid being forgotten, and update each item object in the resources array to
include a url (or href) field with real links (or sensible example URLs) and
unique titles per section instead of repeating "Make It Real - Mapping
AI-Facilitated Gendered Harm"; then update the rendering in ResourcesSection
(the component that consumes the resources constant) to render item.title as an
anchor using item.url/item.href so resources become clickable links.


{/* Centered Content Wrapper */}
<Box width="100%" align="center" pad={{ vertical: "large" }}>
<Box width="1100px">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fixed width="1100px" breaks on smaller viewports.

This will cause horizontal overflow on screens narrower than 1100px. Use maxWidth instead and let the content shrink gracefully.

Suggested fix
-        <Box width="1100px">
+        <Box width={{ max: "1100px", width: "100%" }}>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Box width="1100px">
<Box width="100%" maxWidth="1100px">
Suggested change
<Box width="1100px">
<Box sx={{ width: "100%", maxWidth: "1100px" }}>
🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/ResourcesSection.jsx` at line 48, In
ResourcesSection.jsx the Box component using width="1100px" causes horizontal
overflow on small viewports; update the Box (the element that currently has
width="1100px") to use a responsive sizing approach—replace the fixed width with
maxWidth="1100px" and allow it to shrink (e.g., set width="100%" or use sx to
set width: "100%" and maxWidth: "1100px"), and optionally center with mx="auto"
so the layout remains fluid on narrow screens.

Comment on lines +6 to +11
const updates = [
{ date: "03 Nov 2023", title: "Make It Real - Mapping AI-Facilitated" },
{ date: "03 Nov 2023", title: "Make It Real - Mapping AI-Facilitated" },
{ date: "03 Nov 2023", title: "Make It Real - Mapping AI-Facilitated" },
{ date: "03 Nov 2023", title: "Make It Real - Mapping AI-Facilitated" },
];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Static placeholder data — all four entries are identical.

Same date and truncated title across all entries. If this is scaffolding, add a TODO so real data integration isn't overlooked.

🤖 Prompt for AI Agents
In `@uli-website/src/components/molecules/UpdatesSection.jsx` around lines 6 - 11,
The updates array in UpdatesSection.jsx currently contains four identical static
placeholder objects (symbol: updates) which risks being left in production;
replace these with real data or at minimum annotate the array with a clear TODO
comment and/or load real entries from props or a data source (e.g., accept a
prop like updates or fetchUpdates and map those into the component) so each
entry is unique and not a duplicated placeholder; ensure any temporary
placeholders are marked "TODO: replace placeholder updates" and update the
component (e.g., UpdatesSection) to use the prop/fetch instead of the hardcoded
updates.

@github-actions github-actions bot added the stale label Mar 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant