Skip to content

feat: add New Arrivals widget to Home#2169

Open
stackingsaunter wants to merge 1 commit intomasterfrom
feat/new-arrivals-widget
Open

feat: add New Arrivals widget to Home#2169
stackingsaunter wants to merge 1 commit intomasterfrom
feat/new-arrivals-widget

Conversation

@stackingsaunter
Copy link
Copy Markdown
Contributor

@stackingsaunter stackingsaunter commented Mar 25, 2026

Summary

  • add a dedicated NewArrivalsWidget card for Home
  • show up to 3 curated latest app entries (and fewer automatically if fewer resolve)
  • place the widget in the left column above the Alby Go card

Test plan

  • Run cd frontend && yarn tsc:compile
  • Verify Home renders the New Arrivals card with up to 3 apps
  • Verify each item links to /internal-apps/:id or /appstore/:id correctly

Made with Cursor

Summary by CodeRabbit

New Features

  • Added a "New Arrivals" widget to the home dashboard featuring up to three of the latest applications with their logos, titles, descriptions, and direct access links to enhance app discovery.

Show up to three curated latest apps in a New Arrivals card.
Place it in the left Home column above Alby Go.

Made-with: Cursor
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

A new NewArrivalsWidget component is added to display up to three latest apps from a predefined set. The component filters app data, renders each app with logo, title, and description in a card layout, and is integrated into the Home screen's left column dashboard.

Changes

Cohort / File(s) Summary
New Arrivals Widget Component
frontend/src/components/home/widgets/NewArrivalsWidget.tsx
New React component that maps app IDs to appStoreApps entries, filters out missing apps, limits results to three, and renders a card with app information including logos, titles, clamped descriptions, and navigation links.
Home Screen Integration
frontend/src/screens/Home.tsx
Imports NewArrivalsWidget and adds it to the left-column dashboard grid alongside existing widgets.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • im-adithya
  • rolznz

Poem

🐰 A widget hops in, fresh and new,
Three apps arrive in morning dew,
With logos bright and stories to tell,
The arrivals shine, they welcome well! ✨

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding a new widget component to the Home page.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/new-arrivals-widget

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
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/home/widgets/NewArrivalsWidget.tsx`:
- Around line 46-50: The <img> uses app.logo which is optional on AppStoreApp
and can produce broken images; update NewArrivalsWidget (where app is
mapped/rendered) to either filter out apps with no logo before rendering or
render conditionally and supply a fallback (e.g., a defaultLogoUrl or a
placeholder component) when app.logo is undefined; ensure you reference the
mapped variable (app) and the <img> that currently uses src={app.logo} and
alt={`${app.title} logo`} so the UI never tries to load an undefined src.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9799f903-9dfe-43ed-bd47-3a371d44dce8

📥 Commits

Reviewing files that changed from the base of the PR and between c0e8df6 and 93d59ac.

📒 Files selected for processing (2)
  • frontend/src/components/home/widgets/NewArrivalsWidget.tsx
  • frontend/src/screens/Home.tsx

Comment on lines +46 to +50
<img
src={app.logo}
alt={`${app.title} logo`}
className="size-[60px] rounded-[9px] object-cover"
/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Handle potentially undefined app.logo.

According to the AppStoreApp type definition, logo is optional (logo?: string). If an app doesn't have a logo defined, this will render a broken image. Consider adding a fallback or filtering out apps without logos.

🛡️ Proposed fix with fallback
-              <img
-                src={app.logo}
-                alt={`${app.title} logo`}
-                className="size-[60px] rounded-[9px] object-cover"
-              />
+              {app.logo ? (
+                <img
+                  src={app.logo}
+                  alt={`${app.title} logo`}
+                  className="size-[60px] rounded-[9px] object-cover"
+                />
+              ) : (
+                <div className="size-[60px] rounded-[9px] bg-muted flex items-center justify-center text-muted-foreground text-xs">
+                  {app.title.charAt(0)}
+                </div>
+              )}

Alternatively, filter out apps without logos in the data processing:

   const latestApps = latestAppStoreAppIds
     .map((id) => appStoreApps.find((app) => app.id === id))
-    .filter((app): app is AppStoreApp => !!app)
+    .filter((app): app is AppStoreApp => !!app && !!app.logo)
     .slice(0, 3);
📝 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
<img
src={app.logo}
alt={`${app.title} logo`}
className="size-[60px] rounded-[9px] object-cover"
/>
{app.logo ? (
<img
src={app.logo}
alt={`${app.title} logo`}
className="size-[60px] rounded-[9px] object-cover"
/>
) : (
<div className="size-[60px] rounded-[9px] bg-muted flex items-center justify-center text-muted-foreground text-xs">
{app.title.charAt(0)}
</div>
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/home/widgets/NewArrivalsWidget.tsx` around lines 46 -
50, The <img> uses app.logo which is optional on AppStoreApp and can produce
broken images; update NewArrivalsWidget (where app is mapped/rendered) to either
filter out apps with no logo before rendering or render conditionally and supply
a fallback (e.g., a defaultLogoUrl or a placeholder component) when app.logo is
undefined; ensure you reference the mapped variable (app) and the <img> that
currently uses src={app.logo} and alt={`${app.title} logo`} so the UI never
tries to load an undefined src.

CardTitle,
} from "src/components/ui/card";

const latestAppStoreAppIds = [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Did you check these?

"wherostr",
] as const;

function getAppDestination(app: AppStoreApp) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems duplicated, isn't there a utility method somewhere?

const latestApps = latestAppStoreAppIds
.map((id) => appStoreApps.find((app) => app.id === id))
.filter((app): app is AppStoreApp => !!app)
.slice(0, 3);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why do we slice here? then shouldn't we just have a list of 3 apps?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants