Skip to content

Add package-lock.json to fix CI; refactor app, add utils, tests, and styles - #4

Merged
Isaloum merged 3 commits into
mainfrom
codex/build-gympulse-real-time-occupancy-tracker-r63qxw
Feb 10, 2026
Merged

Add package-lock.json to fix CI; refactor app, add utils, tests, and styles#4
Isaloum merged 3 commits into
mainfrom
codex/build-gympulse-real-time-occupancy-tracker-r63qxw

Conversation

@Isaloum

@Isaloum Isaloum commented Feb 10, 2026

Copy link
Copy Markdown
Owner

Motivation

  • Restore CI caching support by adding a supported lockfile so actions/setup-node@v4 can detect dependencies.
  • Improve app structure and reliability by centralizing helpers, adding unit tests, and separating styles.
  • Replace ad-hoc mock logic in the UI with reusable utilities and clearer components for freshness, confidence, and forecasts.

Description

  • Added a generated package-lock.json so the GitHub Actions setup-node step can find a supported lockfile.
  • Updated package.json to include type: "module" and a test script (node --test src/utils.node.test.mjs).
  • Introduced src/utils.js containing occupancy helpers (deriveOccupancyLevel, getConfidenceLabel, isDataStale, generateLiveOccupancy, generateTrendData, generatePredictionData, generateWeeklyHeatmap, getBestVisitWindow).
  • Refactored src/App.jsx to import utilities, add fetching/fallback logic (fetchDashboardData), UI components (FreshnessBadge, StatusCard, TrendChartCard, PredictionChartCard, WeeklyHeatmapCard), improved accessibility, error handling, and a location picker.
  • Added src/App.css for the new styling and src/utils.node.test.mjs with unit tests covering helpers and generators.

Testing

  • Ran npm install successfully to populate the local environment.
  • Ran npm test which executed the node tests; all tests passed (6/6).
  • Ran npm run build which completed successfully with a Vite chunk-size warning about large bundles but produced a working dist build.

Codex Task

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @Isaloum, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the GymPulse application by improving its overall architecture and reliability. It resolves a critical CI issue by introducing a lockfile, modularizes core logic into a new utility file with accompanying unit tests, and refactors the main UI component into more manageable and accessible sub-components. These changes lead to a more robust, maintainable, and user-friendly application experience, including dynamic data fetching, error handling, and location-specific data display.

Highlights

  • CI Stability: Restored CI caching support by adding a package-lock.json file, ensuring consistent dependency installations.
  • Code Structure: Refactored the application by extracting data generation and helper functions into a new src/utils.js module.
  • Testing: Introduced unit tests for the new utility functions in src/utils.node.test.mjs, improving code reliability.
  • UI/UX Enhancements: Improved the main application component (src/App.jsx) with dedicated UI components, better accessibility, error handling, and a location picker.
  • Styling Separation: Moved all application styles into a new dedicated CSS file (src/App.css).
Changelog
  • package-lock.json
    • Added a new dependency lock file to ensure consistent builds across environments.
  • package.json
    • Configured the project to use ES modules by adding "type": "module".
    • Added a new test script to run Node.js unit tests for utility functions.
  • src/App.css
    • Added a new CSS file containing all application-specific styles, separating presentation from logic.
  • src/App.jsx
    • Removed inline mock data generation functions, now imported from src/utils.js.
    • Integrated new UI components: FreshnessBadge, StatusCard, TrendChartCard, PredictionChartCard, and WeeklyHeatmapCard.
    • Implemented fetchDashboardData for asynchronous data loading, including error handling and a simulated network error.
    • Added a location selection dropdown to allow users to switch between different gym locations.
    • Updated chart imports to use Area, Cell, ComposedChart, and Legend from recharts for richer visualizations.
    • Enhanced accessibility by adding role and aria-label attributes to various UI elements.
  • src/utils.js
    • Added STATUS_LEVELS constants and deriveOccupancyLevel function for consistent occupancy classification.
    • Included getConfidenceLabel to provide descriptive labels for prediction confidence.
    • Implemented isDataStale to check the freshness of data based on a timestamp.
    • Introduced clamp helper for value bounding and formatHour for consistent time formatting.
    • Created generateLiveOccupancy, generateTrendData, generatePredictionData, and generateWeeklyHeatmap functions to centralize data generation logic.
    • Added getBestVisitWindow to suggest optimal visiting times based on prediction data.
  • src/utils.node.test.mjs
    • Added unit tests for deriveOccupancyLevel, getConfidenceLabel, isDataStale, getBestVisitWindow, generatePredictionData, and generateWeeklyHeatmap.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request is a significant and well-executed refactor. It introduces a package-lock.json to stabilize CI, separates concerns by moving utility functions into src/utils.js and styles into src/App.css, and adds unit tests which is a fantastic improvement for reliability. The main application component in src/App.jsx has been modernized to use functional components and hooks, with proper state management for loading and error states. My feedback focuses on a few minor areas for improvement, mainly around extracting hardcoded values into constants to enhance maintainability and readability. Overall, this is a high-quality contribution that greatly improves the structure and robustness of the application.

Comment thread src/App.jsx
setPredictionData(generatePredictionData());
}, 300000);
load();
const refresh = setInterval(load, 30_000);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The data refresh interval 30_000 is a magic number. It's better to extract it to a named constant (e.g., const REFRESH_INTERVAL_MS = 30_000;) defined at the top of the file. This improves readability and makes the value easier to find and change.

Suggested change
const refresh = setInterval(load, 30_000);
const refresh = setInterval(load, REFRESH_INTERVAL_MS);

Comment thread src/App.jsx
Comment on lines +227 to +231
<select value={location} onChange={(event) => setLocation(event.target.value)}>
<option>Main Street</option>
<option>Downtown</option>
<option>West End</option>
</select>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To improve maintainability, consider defining the list of locations as a constant array (e.g., const LOCATIONS = ['Main Street', 'Downtown', 'West End'];) at the top of the file, and then map over it to generate the <option> elements. This makes it easier to add or remove locations from a single source of truth.

            <select value={location} onChange={(event) => setLocation(event.target.value)}>
              {['Main Street', 'Downtown', 'West End'].map(loc => <option key={loc}>{loc}</option>)}
            </select>

Comment thread src/utils.js
Comment on lines +7 to +11
export const deriveOccupancyLevel = (percentage) => {
if (percentage < 35) return STATUS_LEVELS.LOW;
if (percentage < 75) return STATUS_LEVELS.MODERATE;
return STATUS_LEVELS.HIGH;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The thresholds 35 and 75 are magic numbers. Extracting them into named constants improves readability and maintainability. These constants could be defined at the module level to be shared or configured easily.

export const deriveOccupancyLevel = (percentage) => {
  const OCCUPANCY_MODERATE_THRESHOLD = 35;
  const OCCUPANCY_HIGH_THRESHOLD = 75;
  if (percentage < OCCUPANCY_MODERATE_THRESHOLD) return STATUS_LEVELS.LOW;
  if (percentage < OCCUPANCY_HIGH_THRESHOLD) return STATUS_LEVELS.MODERATE;
  return STATUS_LEVELS.HIGH;
};

Comment thread src/utils.js
Comment on lines +13 to +17
export const getConfidenceLabel = (confidence) => {
if (confidence >= 80) return 'High confidence';
if (confidence >= 60) return 'Medium confidence';
return 'Low confidence';
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The thresholds 80 and 60 are magic numbers. It's a good practice to extract them into named constants to make the code more self-documenting and easier to adjust. These could be defined at the module level for wider use if needed.

export const getConfidenceLabel = (confidence) => {
  const CONFIDENCE_HIGH_THRESHOLD = 80;
  const CONFIDENCE_MEDIUM_THRESHOLD = 60;
  if (confidence >= CONFIDENCE_HIGH_THRESHOLD) return 'High confidence';
  if (confidence >= CONFIDENCE_MEDIUM_THRESHOLD) return 'Medium confidence';
  return 'Low confidence';
};

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7ba837fb5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/App.jsx
<XAxis dataKey="time" />
<YAxis domain={[0, 100]} unit="%" />
<Tooltip formatter={(value) => [`${value}%`, 'Occupancy']} />
<Line dataKey="occupancy" stroke="#2563eb" strokeWidth={3} dot={false} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Import Line before rendering trend chart

When a dashboard fetch succeeds and TrendChartCard renders, this JSX references Line even though Line is not imported from recharts, which triggers ReferenceError: Line is not defined and crashes the main view in the normal success path. Add Line to the recharts import list so the chart can render.

Useful? React with 👍 / 👎.

Comment thread src/App.jsx
}
const live = generateLiveOccupancy();
if (location === 'Downtown') {
live.percentage = Math.min(100, live.percentage + 12);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Recalculate headcount after Downtown occupancy bump

In the Downtown branch, live.percentage is increased but live.estimatedHeadcount is left unchanged, so the UI can show contradictory values (for example a higher percentage with a lower unchanged member count). This makes the status card numerically inconsistent for Downtown users and should be updated together.

Useful? React with 👍 / 👎.

@Isaloum
Isaloum merged commit 79aedb0 into main Feb 10, 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