Skip to content

About Us: replace hardcoded contributor list with live API fetch + clickable profile modal#63

Open
himanshujha05 wants to merge 3 commits intoReduxISU:ReduxAPI_GUIfrom
himanshujha05:ReduxAPI_GUI
Open

About Us: replace hardcoded contributor list with live API fetch + clickable profile modal#63
himanshujha05 wants to merge 3 commits intoReduxISU:ReduxAPI_GUIfrom
himanshujha05:ReduxAPI_GUI

Conversation

@himanshujha05
Copy link
Copy Markdown
Collaborator

@himanshujha05 himanshujha05 commented Jan 22, 2026

What this PR does

The About Us page previously had a hardcoded array of 26 contributor names baked directly into the frontend source code. This meant that every time a new student joined the project, someone had to manually edit pages/aboutus/index.js, commit it, and redeploy the frontend — just to get a name to show up on the page.

This PR removes that hardcoded array entirely and replaces it with a live fetch from the backend. It also adds a clickable profile modal so visitors can see a contributor's personal info, GitHub profile, and contribution breakdown without leaving the page.


The problem with the old approach

// Old code — every new contributor required a frontend code change
const contributors = [
  "Kaden Marchetti",
  "Caleb Eardley",
  // ... 24 more names hardcoded here
];

This created an unnecessary coupling between the contributor list and the frontend codebase. It also meant the list could silently fall out of date if someone forgot to update it.


What changed

1. Contributor names are now fetched from the backend

On page load, a single call goes to:

GET /Navigation/ContributorProfile/directory

This endpoint returns an array of entries like { name, githubUsername }. The component extracts the names for the list and builds a githubMap (name → GitHub username) for use in the modal. No more hardcoded array.

2. Profiles load lazily — only when you click a name

Previously, the page was firing off 26 individual API calls on mount to pre-fetch every contributor's full profile data. Now nothing is fetched until a user actually clicks a name. This makes the initial page load significantly lighter.

// Profile fetch is triggered only on click
const handleContributorClick = (name) => {
  fetch(`${reduxBaseUrl}Navigation/ContributorProfile/${encodeURIComponent(name)}`)
    ...
};

3. Clickable contributor names open a profile modal

Each name in the contributors list is now a styled, clickable link (orange, underlined, with a hover lighten effect). Clicking it opens a MUI Dialog showing:

  • Email, education, major, and bio
  • A GitHub profile link (if githubUsername is present in the JSON)
  • A GitHub avatar pulled from github.com/<username>.png
  • Contribution counts broken down by problems, solvers, and reductions

4. API base URL uses the environment variable

All fetch calls use process.env.NEXT_PUBLIC_REDUX_BASE_URL, which is already configured in .env.development (http://localhost:27000/) and .env.production (https://api.redux.portneuf.cose.isu.edu/). The previously hardcoded localhost:27000 URL and the hardcoded Swagger link in Learn More are both fixed.


How the new contributor flow works

  1. A new contributor adds their entry to contributorInfo.json on the backend
  2. Backend is restarted
  3. Their name automatically appears on the About Us page — no frontend changes needed

Files changed

  • pages/aboutus/index.js — only file changed

Testing done

  • Built locally with npm run build — no errors
  • Ran the dev server and verified contributor names load from the API
  • Clicked several contributor names and confirmed the modal opens with correct data
  • Verified the modal closes cleanly and resets state on each open/close
  • Confirmed the page renders an empty list gracefully when the backend is unreachable (the .catch(() => {}) swallows the error silently)

Reviewer notes

  • This PR depends on the backend exposing a GET /Navigation/ContributorProfile/directory endpoint that returns [{ name: string, githubUsername?: string }]. Please confirm this route exists and is deployed before merging.
  • The GitHub avatar (github.com/<username>.png) is loaded directly from GitHub's CDN — no auth needed, but it will silently show nothing if the username is wrong or the user has no avatar set.

Added contributor data fetching and dynamic rendering of contributor names with links.
Copilot AI review requested due to automatic review settings January 22, 2026 18:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds contributor profile fetching and updates the About Us page to render contributor names as clickable links.

Changes:

  • Added client-side fetching of contributor profile metadata from the backend on page load
  • Added state to store fetched contributor profile data
  • Updated the contributor list UI to render each contributor name as a Next.js link

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pages/aboutus/index.js Outdated
Comment on lines +189 to +191
{contributors.map((name, index) => {
const data = contributorData[name];
const nameSlug = name.replace(/\s+/g, '-').toLowerCase();
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

contributorData is fetched and stored, but the only read is const data = contributorData[name]; and data is never used. This results in extra network traffic and state updates with no UI impact. Either use the fetched data to drive rendering (e.g., link target/label) or remove the fetch/state entirely.

Copilot uses AI. Check for mistakes.
Comment thread pages/aboutus/index.js Outdated
Comment on lines +195 to +201
• <Link href={`/contributor/${nameSlug}`} legacyBehavior>
<a
style={{ color: "#f47920", textDecoration: "underline", cursor: "pointer" }}
>
{name}
</a>
</Link>
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

This Link points to /contributor/${nameSlug}, but there is no pages/contributor/* route in the current codebase, so these links will 404. Either add the corresponding Next.js page route (e.g., a dynamic contributor page) or change the link to an existing route/URL.

Copilot uses AI. Check for mistakes.
Comment thread pages/aboutus/index.js
};

fetchAllContributorData();
}, []);
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The effect depends on contributors but the dependency array is empty. With next/core-web-vitals, this typically raises a react-hooks/exhaustive-deps warning and can become a real bug if the contributors list ever changes. Consider moving contributors outside the component or including it in the dependency array.

Copilot uses AI. Check for mistakes.
Comment thread pages/aboutus/index.js Outdated
import ResponsiveAppBar from "../../components/widgets/ResponsiveAppBar";
import { createTheme, ThemeProvider, Container, Box } from "@mui/material";
import "bootstrap/dist/css/bootstrap.min.css";
import { createTheme, ThemeProvider, Container, Box, Button, Collapse } from "@mui/material";
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

Button and Collapse are imported from @mui/material but not used in this file, which can trigger lint failures during next build and adds noise. Remove the unused imports or use them in the JSX.

Suggested change
import { createTheme, ThemeProvider, Container, Box, Button, Collapse } from "@mui/material";
import { createTheme, ThemeProvider, Container, Box } from "@mui/material";

Copilot uses AI. Check for mistakes.
Comment thread pages/aboutus/index.js Outdated
Comment on lines +29 to +31
const encodedName = encodeURIComponent(name);
const response = await fetch(`https://api.redux.portneuf.cose.isu.edu/Navigation/ContributorProfile/${encodedName}`);
if (response.ok) {
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

This fetch hard-codes the production API host. The repo already defines NEXT_PUBLIC_REDUX_BASE_URL (see pages/index.js:42 and .env.*), so use that base URL here to avoid breaking local/dev/staging environments and to keep configuration centralized.

Copilot uses AI. Check for mistakes.
Comment thread pages/aboutus/index.js Outdated
Comment on lines +27 to +38
for (const name of contributors) {
try {
const encodedName = encodeURIComponent(name);
const response = await fetch(`https://api.redux.portneuf.cose.isu.edu/Navigation/ContributorProfile/${encodedName}`);
if (response.ok) {
const data = await response.json();
dataMap[name] = data;
}
} catch (error) {
console.warn(`Failed to fetch data for ${name}:`, error);
}
}
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

Contributor profiles are fetched sequentially inside a for...of with await, which will make page load time grow linearly with the number of contributors. Consider issuing requests concurrently (e.g., build an array of promises and await them together) or adding a backend batch endpoint.

Copilot uses AI. Check for mistakes.
Refactor contributor data fetching and modal handling. Update publication titles for clarity and add Dialog component for contributor profiles.
@Andrija-Sevaljevic Andrija-Sevaljevic self-assigned this Mar 19, 2026
Copy link
Copy Markdown
Collaborator

@Andrija-Sevaljevic Andrija-Sevaljevic left a comment

Choose a reason for hiding this comment

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

https://github.com/ReduxISU/Redux_GUI/actions/runs/21261813477/job/61190943937

238:134 Error: ' can be escaped with &apos;, &lsquo;, &#39;, &rsquo;. react/no-unescaped-entities

Jobs don't pass checks. Please review compilation issues and resubmit.

@himanshujha05 himanshujha05 changed the title Implement contributor data fetching and display About Us: replace hardcoded contributor list with live API fetch + clickable profile modal Apr 24, 2026
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.

3 participants