Skip to content

feat: scaffold initial frontend project structure and marketing layou…#57

Open
muntasiractive wants to merge 3 commits into
7-Blocks:mainfrom
muntasiractive:main
Open

feat: scaffold initial frontend project structure and marketing layou…#57
muntasiractive wants to merge 3 commits into
7-Blocks:mainfrom
muntasiractive:main

Conversation

@muntasiractive

@muntasiractive muntasiractive commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Description

Redesigned the Home Page to match the About Page’s design language, resolving the merging issues.

Related Issue

Fixed #46

Checklist

  • I have read the contributing guidelines
  • My code follows the project guidelines
  • I have completed testing of my changes
  • Documentation has been updated (if applicable)

Screenshots / Screen Recordings

screencapture-localhost-5173-2026-07-16-20_51_20

Breaking Changes

None


ECSoC26 Submission

ECSoC26 contributors only — select your difficulty level by checking exactly one box below.
Leaving all boxes unchecked, or checking more than one, will cause the automation to fail.

  • ECSoC26-L1 – Beginner
  • ECSoC26-L2 – Intermediate
  • ECSoC26-L3 – Advanced

Summary by CodeRabbit

  • New Features
    • Added a shader-driven Lightfall WebGL background to the landing page.
    • Added motion/GSAP-powered landing sections, including process cards, stats reveal, and an animated closing CTA with an About link.
    • Introduced a new animated GlobeBackground satellite globe.
  • Style
    • Updated marketing navigation link states and improved mobile menu icon animations.
    • Expanded theme color variables and enhanced global scrollbar styling.
  • Bug Fixes
    • Improved reduced-motion handling and animation lifecycle cleanup; refined resize timeout typing.

Greptile Summary

This PR redesigns the landing page to align with the About page's design language, replacing the previous SVG orbital field with a Lightfall WebGL background and a new GlobeBackground component that renders live low-Earth-orbit satellite positions from a TLE dataset.

  • Lightfall (Lightfall.tsx): New OGL-powered WebGL component providing an animated falling-light effect; three new dependencies (ogl, globe.gl, satellite.js) are added to support it and the globe.
  • GlobeBackground (GlobeBackground.tsx): Fetches and propagates real satellite TLE data each animation frame; contains a data-wrapping bug that prevents particles from rendering (see inline comment).
  • LandingPage (LandingPage.tsx): Replaces the static SVG orbits with the above components, adds Framer Motion parallax/scroll effects, GSAP scroll-triggered entrance animations, a scroll-progress bar, and a new closing CTA section.

Confidence Score: 4/5

Safe to merge after fixing the GlobeBackground particle data bug; the rest of the changes are additive UI work.

The GlobeBackground component passes [validSats] (an array-wrapped array) to particlesData, meaning globe.gl sees a single element whose lat/lng/alt fields are all undefined — no satellite particles will ever be rendered. Everything else (Lightfall, LandingPage scroll effects, MarketingLayout branding update) is additive and works correctly.

frontend/src/components/GlobeBackground.tsx — the one-line particlesData fix should be applied before merging to make the satellite visualisation work as intended.

Important Files Changed

Filename Overview
frontend/src/components/GlobeBackground.tsx New component rendering a 3D satellite globe; particlesData([validSats]) wraps the data in an extra array so no particles are ever displayed, and the initial setTimeout is not cancelled on unmount.
frontend/src/components/ui/Lightfall.tsx New WebGL Lightfall background component using OGL; the entire scene is torn down/rebuilt when any prop changes (including paused and colors) due to the broad useEffect dependency array — flagged in prior reviews.
frontend/src/pages/LandingPage.tsx Landing page fully redesigned with Framer Motion parallax, GSAP scroll animations, the new Lightfall and GlobeBackground components, and a closing CTA section; logic is sound aside from the unused useState import noted in a prior review.
frontend/src/components/layouts/MarketingLayout.tsx Minor formatting change to template-literal class strings and a footer branding update from "Kepler" to "7Blocks"; no functional issues.
frontend/src/styles/index.css Adds three theme colour tokens and a global scrollbar override; the * Firefox scrollbar rule applies app-wide (flagged in prior review).
frontend/src/components/ui/globe.tsx Import updated from motion/react to framer-motion for consistency; no logic changes.
frontend/src/components/ui/particles.tsx Single-line type fix: NodeJS.TimeoutReturnType<typeof setTimeout> for better portability.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser
    participant LandingPage
    participant GlobeBackground
    participant SpaceTrackTXT as /datasets/space-track-leo.txt
    participant GlobeGL as globe.gl

    Browser->>LandingPage: mount
    LandingPage->>GlobeBackground: render
    GlobeBackground->>GlobeGL: new Globe(container)
    GlobeBackground->>SpaceTrackTXT: fetch TLE data
    SpaceTrackTXT-->>GlobeBackground: raw TLE text
    GlobeBackground->>GlobeBackground: "parse & filter SatDataItem[]"
    loop rAF (per frame)
        GlobeBackground->>GlobeBackground: propagate satellite positions
        GlobeBackground->>GlobeGL: particlesData(validSats) currently [validSats]
        GlobeGL-->>Browser: render globe with particles
    end
    Browser->>LandingPage: unmount
    LandingPage->>GlobeBackground: cleanup
    GlobeBackground->>GlobeBackground: cancelAnimationFrame, clear container
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Browser
    participant LandingPage
    participant GlobeBackground
    participant SpaceTrackTXT as /datasets/space-track-leo.txt
    participant GlobeGL as globe.gl

    Browser->>LandingPage: mount
    LandingPage->>GlobeBackground: render
    GlobeBackground->>GlobeGL: new Globe(container)
    GlobeBackground->>SpaceTrackTXT: fetch TLE data
    SpaceTrackTXT-->>GlobeBackground: raw TLE text
    GlobeBackground->>GlobeBackground: "parse & filter SatDataItem[]"
    loop rAF (per frame)
        GlobeBackground->>GlobeBackground: propagate satellite positions
        GlobeBackground->>GlobeGL: particlesData(validSats) currently [validSats]
        GlobeGL-->>Browser: render globe with particles
    end
    Browser->>LandingPage: unmount
    LandingPage->>GlobeBackground: cleanup
    GlobeBackground->>GlobeBackground: cancelAnimationFrame, clear container
Loading

Comments Outside Diff (3)

  1. frontend/src/components/ui/Lightfall.tsx, line 284-434 (link)

    P1 paused in useEffect dependency array destroys WebGL context on toggle

    paused is listed in the useEffect dependency array, so every time it transitions false → true or back, the entire WebGL setup (renderer, program, geometry, mesh, canvas) is torn down and rebuilt from scratch. The intended semantic is to skip rendering in the animation loop — not to reset the scene. A consumer that toggles paused will see the canvas flash and lose any mid-animation state on every toggle. paused should be tracked in a ref so the loop can read the latest value without triggering a full teardown.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: frontend/src/components/ui/Lightfall.tsx
    Line: 284-434
    
    Comment:
    **`paused` in `useEffect` dependency array destroys WebGL context on toggle**
    
    `paused` is listed in the `useEffect` dependency array, so every time it transitions `false → true` or back, the entire WebGL setup (renderer, program, geometry, mesh, canvas) is torn down and rebuilt from scratch. The intended semantic is to skip rendering in the animation loop — not to reset the scene. A consumer that toggles `paused` will see the canvas flash and lose any mid-animation state on every toggle. `paused` should be tracked in a ref so the loop can read the latest value without triggering a full teardown.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

  2. frontend/src/components/ui/Lightfall.tsx, line 415-434 (link)

    P2 colors array compared by reference in dependency array

    colors is an array and is compared by reference in the dependency array. The usage in Hero passes an inline literal — colors={['#00e5ff', '#00707cff', '#9ddfe7ff', '#00e5ff']} — which produces a new reference on every render of Hero. If the parent ever re-renders, the entire WebGL context will be torn down and rebuilt. The array should either be memoized at the call site with useMemo, or Lightfall should do a deep comparison of the colors values internally before re-initialising.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: frontend/src/components/ui/Lightfall.tsx
    Line: 415-434
    
    Comment:
    **`colors` array compared by reference in dependency array**
    
    `colors` is an array and is compared by reference in the dependency array. The usage in `Hero` passes an inline literal — `colors={['#00e5ff', '#00707cff', '#9ddfe7ff', '#00e5ff']}` — which produces a new reference on every render of `Hero`. If the parent ever re-renders, the entire WebGL context will be torn down and rebuilt. The array should either be memoized at the call site with `useMemo`, or `Lightfall` should do a deep comparison of the `colors` values internally before re-initialising.
    
    How can I resolve this? If you propose a fix, please make it concise.
  3. frontend/src/styles/index.css, line 1132-1137 (link)

    P2 Global * scrollbar rule affects the entire application

    The scrollbar-width: thin; scrollbar-color: ... rule is applied to the * selector, which overrides scrollbar styling for every element in the app — including the dashboard and any admin UI. Scope this to a marketing-specific class (e.g., .marketing-layout *) to avoid unintended bleed into non-marketing pages.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: frontend/src/styles/index.css
    Line: 1132-1137
    
    Comment:
    **Global `*` scrollbar rule affects the entire application**
    
    The `scrollbar-width: thin; scrollbar-color: ...` rule is applied to the `*` selector, which overrides scrollbar styling for every element in the app — including the dashboard and any admin UI. Scope this to a marketing-specific class (e.g., `.marketing-layout *`) to avoid unintended bleed into non-marketing pages.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
frontend/src/components/GlobeBackground.tsx:126
The `particlesData` call wraps `validSats` in an extra array, so globe.gl receives a single-element array whose sole item is the whole `SatDataItem[]` array. When globe.gl iterates the data and tries to read `d["lat"]` / `d["lng"]` / `d["alt"]` on that array, it gets `undefined` for all fields, so no satellite particles will ever be rendered.

```suggestion
          world.particlesData(validSats);
```

Reviews (2): Last reviewed commit: "Merge branch '7-Blocks:main' into main" | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@codeant-ai

codeant-ai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Skipping CodeAnt AI review — this PR is a back-merge between long-lived branches (mainmain). The diff here has already been reviewed when the underlying commits landed on the source branch, so re-running analysis would produce duplicate findings on already-reviewed code.

If you want to analyze this anyway (e.g. you resolved conflicts with new logic), comment @codeant-ai : review and CodeAnt will start a review.

@github-actions github-actions Bot added ECSoC26 Official label for ECSoC26 event contributions. ECSoC26-L2 Level 2 contribution for the ECSoC26 event. bug Something isn't working documentation Improvements or additions to documentation frontend Frontend development size/XL Very large or complex contribution. type:bug Fixes an existing bug or unexpected behavior. type:documentation Improves project documentation. type:frontend Changes frontend or client-side code. labels Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The landing page now uses configurable WebGL and satellite visualizations, Framer Motion and GSAP animations, a closing CTA, reduced-motion handling, updated marketing copy, and additional theme and scrollbar styling.

Changes

Landing animation experience

Layer / File(s) Summary
Lightfall renderer and dependency
frontend/package.json, frontend/src/components/ui/Lightfall.tsx
Adds OGL and introduces a configurable shader-driven canvas with resizing, pointer interaction, animation controls, and cleanup.
Satellite globe rendering
frontend/src/components/GlobeBackground.tsx
Adds a globe visualization that loads TLE data, propagates satellite positions, updates particles, rotates the globe, and cleans up animation resources.
Landing page motion flow
frontend/src/pages/LandingPage.tsx
Adds the Lightfall hero, magnetic CTA, animated workflow cards, scroll-triggered statistics and CTA reveals, scroll progress, and reduced-motion handling.
Marketing shell and frontend visual support
frontend/src/components/layouts/MarketingLayout.tsx, frontend/src/components/ui/globe.tsx, frontend/src/components/ui/particles.tsx, frontend/src/styles/index.css
Updates marketing navigation and footer text, aligns motion and timeout typings, and adds theme variables and scrollbar styles.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Visitor
  participant LandingPage
  participant Lightfall
  participant OGL
  participant GSAPScrollTrigger
  Visitor->>LandingPage: Open and scroll landing page
  LandingPage->>Lightfall: Render animated hero background
  Lightfall->>OGL: Initialize shader renderer and canvas
  LandingPage->>GSAPScrollTrigger: Register section reveal animations
  GSAPScrollTrigger->>LandingPage: Animate hero, cards, stats, and CTA
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Issue #46 asks for a dedicated About Kepler page, but this PR mainly redesigns the Home Page and adds unrelated WebGL/marketing changes. Implement the About Kepler page content and sections required by #46, or retarget the issue if the home-page redesign is the intended scope.
Out of Scope Changes check ⚠️ Warning Several changes are out of scope for #46, including the home-page WebGL redesign, global scrollbar CSS, and new runtime dependencies. Remove unrelated homepage/global styling changes or expand the issue scope before merging.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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 is partly aligned with the changes, but it overstates an initial project scaffold and only broadly mentions the marketing layout redesign.
Description check ✅ Passed The description includes all required sections, a linked issue, screenshots, breaking changes, and exactly one ECSoC26 box.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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


interface OrbitalFieldProps {
prefersReducedMotion: boolean;
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";

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 Unused useState import

useState is imported but never used after refactoring the prefersReducedMotion state to useReducedMotion() from Framer Motion. This will produce a lint/TypeScript warning and should be removed.

Suggested change
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
import React, { useEffect, useLayoutEffect, useRef } from "react";
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/pages/LandingPage.tsx
Line: 1

Comment:
**Unused `useState` import**

`useState` is imported but never used after refactoring the `prefersReducedMotion` state to `useReducedMotion()` from Framer Motion. This will produce a lint/TypeScript warning and should be removed.

```suggestion
import React, { useEffect, useLayoutEffect, useRef } from "react";
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@github-actions github-actions Bot added AI Artificial Intelligence and Machine Learning enhancement New feature or request type:feature Introduces a new feature or enhancement. labels Jul 16, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/components/ui/Lightfall.tsx`:
- Around line 228-235: Update the renderer initialization in the Lightfall
effect to detect WebGL availability before calling new Renderer, and handle the
unavailable-context case by exiting through the existing decorative-background
fallback path. Ensure rendererRef and subsequent WebGL-dependent setup are only
used after a valid context is available.
- Around line 306-331: Update the animation loop in Lightfall’s loop callback so
paused state renders one static frame instead of continuously scheduling RAF
callbacks or skipping rendering. Schedule the next requestAnimationFrame only
while active, while preserving the existing render guards and mouse-dampening
behavior.

In `@frontend/src/pages/LandingPage.tsx`:
- Around line 116-133: Update the Lightfall container in LandingPage to render
Lightfall only when prefersReducedMotion is false, rather than merely disabling
mouseInteraction. Remove pointer-events-none from the container so the canvas
can receive pointermove events and restore pointer interaction for
motion-enabled users.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ac0fce54-8031-4390-9d4d-8c292bad4440

📥 Commits

Reviewing files that changed from the base of the PR and between bf4a923 and a883076.

⛔ Files ignored due to path filters (1)
  • frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • frontend/package.json
  • frontend/src/components/layouts/MarketingLayout.tsx
  • frontend/src/components/ui/Lightfall.tsx
  • frontend/src/components/ui/globe.tsx
  • frontend/src/components/ui/particles.tsx
  • frontend/src/pages/LandingPage.tsx
  • frontend/src/styles/index.css

Comment on lines +228 to +235
const renderer = new Renderer({
dpr: dpr ?? (typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1),
alpha: true,
antialias: true
});
rendererRef.current = renderer;
const gl = renderer.gl;
const canvas = gl.canvas as HTMLCanvasElement;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
curl -fsSL https://unpkg.com/ogl@1.0.11/src/core/Renderer.js |
  rg -n -C2 'getContext|unable to create webgl context|this\.gl\.renderer'

Repository: 7-Blocks/Kepler

Length of output: 685


🏁 Script executed:

#!/bin/bash
sed -n '180,280p' frontend/src/components/ui/Lightfall.tsx

Repository: 7-Blocks/Kepler

Length of output: 3182


Handle missing WebGL context before creating Renderer. new Renderer() can throw when WebGL is unavailable, so this decorative effect won’t fall back to the section background.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/ui/Lightfall.tsx` around lines 228 - 235, Update the
renderer initialization in the Lightfall effect to detect WebGL availability
before calling new Renderer, and handle the unavailable-context case by exiting
through the existing decorative-background fallback path. Ensure rendererRef and
subsequent WebGL-dependent setup are only used after a valid context is
available.

Comment on lines +306 to +331
const loop = (t: number) => {
rafRef.current = requestAnimationFrame(loop);
uniforms.iTime.value = t * 0.001;
if (mouseDampening > 0) {
if (!lastTimeRef.current) lastTimeRef.current = t;
const dt = (t - lastTimeRef.current) / 1000;
lastTimeRef.current = t;
const tau = Math.max(1e-4, mouseDampening);
let factor = 1 - Math.exp(-dt / tau);
if (factor > 1) factor = 1;
const target = mouseTargetRef.current;
const cur = uniforms.iMouse.value as number[];
cur[0] += (target[0] - cur[0]) * factor;
cur[1] += (target[1] - cur[1]) * factor;
} else {
lastTimeRef.current = t;
}
if (!paused && programRef.current && meshRef.current) {
try {
renderer.render({ scene: meshRef.current });
} catch (e) {
console.error(e);
}
}
};
rafRef.current = requestAnimationFrame(loop);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make paused stop the RAF without blanking the canvas.

Line 307 schedules callbacks continuously, but Line 323 skips every render while paused. Render one static frame when paused and only schedule RAF while active.

Proposed fix
     const loop = (t: number) => {
-      rafRef.current = requestAnimationFrame(loop);
       uniforms.iTime.value = t * 0.001;
       // existing mouse dampening logic...
-      if (!paused && programRef.current && meshRef.current) {
+      if (programRef.current && meshRef.current) {
         try {
           renderer.render({ scene: meshRef.current });
         } catch (e) {
           console.error(e);
         }
       }
+      rafRef.current = requestAnimationFrame(loop);
     };
-    rafRef.current = requestAnimationFrame(loop);
+
+    if (paused) {
+      renderer.render({ scene: mesh });
+    } else {
+      rafRef.current = requestAnimationFrame(loop);
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/ui/Lightfall.tsx` around lines 306 - 331, Update the
animation loop in Lightfall’s loop callback so paused state renders one static
frame instead of continuously scheduling RAF callbacks or skipping rendering.
Schedule the next requestAnimationFrame only while active, while preserving the
existing render guards and mouse-dampening behavior.

Comment thread frontend/src/pages/LandingPage.tsx
@krishkhinchi

Copy link
Copy Markdown
Member

Thank you @muntasiractive for your contribution, we really appreciate the effort you've put into this redesign. The new design looks clean, and we especially like the direction you took with it.

However, we already have a strong 3D homepage design (see the attached screenshot), so we aren't planning to replace it at this time. Because of that, I can't merge this PR.

image

We'd love for you to open another PR that focuses on making the rest of the Kepler web app match the same theme, colors, and overall design language as the current homepage. Please make sure to use Magic UI components throughout where applicable, as that's a requirement for the project.

Also, the 7Blocks team really likes the Kepler logo you created, and we'd like to move forward with that logo. Great work on it!

Thanks again for your contribution, and we look forward to your next PR.

@muntasiractive

Copy link
Copy Markdown
Contributor Author

So, you want me to recreate the home page with a 3D globe in the hero section?

@muntasiractive

Copy link
Copy Markdown
Contributor Author

Checkout this @krishkhinchi

screencapture-localhost-5173-2026-07-16-22_39_01

const validSats = satData.filter(
(d) => !isNaN(d.lat) && !isNaN(d.lng) && !isNaN(d.alt)
);
world.particlesData([validSats]);

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 The particlesData call wraps validSats in an extra array, so globe.gl receives a single-element array whose sole item is the whole SatDataItem[] array. When globe.gl iterates the data and tries to read d["lat"] / d["lng"] / d["alt"] on that array, it gets undefined for all fields, so no satellite particles will ever be rendered.

Suggested change
world.particlesData([validSats]);
world.particlesData(validSats);
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/components/GlobeBackground.tsx
Line: 126

Comment:
The `particlesData` call wraps `validSats` in an extra array, so globe.gl receives a single-element array whose sole item is the whole `SatDataItem[]` array. When globe.gl iterates the data and tries to read `d["lat"]` / `d["lng"]` / `d["alt"]` on that array, it gets `undefined` for all fields, so no satellite particles will ever be rendered.

```suggestion
          world.particlesData(validSats);
```

How can I resolve this? If you propose a fix, please make it concise.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/components/GlobeBackground.tsx`:
- Around line 96-135: Update the frameTicker loop to accept RAF timestamps and
calculate elapsed time, using that delta to scale globe rotation consistently
across refresh rates. Accumulate elapsed time and only propagate the satellite
catalog and call world.particlesData when the fixed update interval has elapsed,
while continuing to schedule RAF frames and preserving the existing validity
filtering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: beae4ef5-ba7d-4a73-a591-9fc0fdc4d7f0

📥 Commits

Reviewing files that changed from the base of the PR and between a883076 and 5652f12.

⛔ Files ignored due to path filters (1)
  • frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • frontend/package.json
  • frontend/public/datasets/space-track-leo.txt
  • frontend/src/components/GlobeBackground.tsx
  • frontend/src/pages/LandingPage.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/pages/LandingPage.tsx
  • frontend/package.json

Comment on lines +96 to +135
// Time ticker loop
let time = new Date();

const frameTicker = () => {
if (!isMounted) return;

time = new Date(+time + TIME_STEP);

// Update satellite positions
const gmst = satellite.gstime(time);
satData.forEach((d) => {
const eci = satellite.propagate(d.satrec, time);
if (eci && typeof eci === "object" && eci.position) {
const position = eci.position as satellite.PositionAndVelocity["position"];
if (typeof position === "object" && "x" in position) {
const gdPos = satellite.eciToGeodetic(position, gmst);
d.lat = radiansToDegrees(gdPos.latitude);
d.lng = radiansToDegrees(gdPos.longitude);
d.alt = gdPos.height / EARTH_RADIUS_KM;
}
} else {
d.lat = NaN;
d.lng = NaN;
d.alt = NaN;
}
});

const validSats = satData.filter(
(d) => !isNaN(d.lat) && !isNaN(d.lng) && !isNaN(d.alt)
);
world.particlesData([validSats]);

// Rotate globe slowly
const currentPov = world.pointOfView();
world.pointOfView({
lng: currentPov.lng + 0.05,
});

animationFrameRef.current = requestAnimationFrame(frameTicker);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
awk 'substr($0, 1, 2) == "1 " { count++ } END { print count }' \
  frontend/public/datasets/space-track-leo.txt

Repository: 7-Blocks/Kepler

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- GlobeBackground.tsx (relevant range) ---'
nl -ba frontend/src/components/GlobeBackground.tsx | sed -n '1,220p'

echo
echo '--- satellite dataset line count / sample shape ---'
python3 - <<'PY'
from pathlib import Path
p = Path('frontend/public/datasets/space-track-leo.txt')
count = 0
sample = []
with p.open() as f:
    for i, line in enumerate(f, 1):
        if i <= 6:
            sample.append(line.rstrip('\n'))
        if line.startswith('1 '):
            count += 1
print('line_count_starting_with_1_space =', count)
print('first_lines:')
for s in sample:
    print(repr(s))
PY

Repository: 7-Blocks/Kepler

Length of output: 238


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the satellite data loader and animation setup in the component.
ast-grep outline frontend/src/components/GlobeBackground.tsx --view expanded

Repository: 7-Blocks/Kepler

Length of output: 496


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the surrounding effect setup to understand how often this runs.
sed -n '1,260p' frontend/src/components/GlobeBackground.tsx | nl -ba | sed -n '1,260p'

Repository: 7-Blocks/Kepler

Length of output: 193


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the component around the animation loop only.
nl -ba frontend/src/components/GlobeBackground.tsx | sed -n '80,160p'

Repository: 7-Blocks/Kepler

Length of output: 193


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- GlobeBackground.tsx around the animation loop ---'
sed -n '1,220p' frontend/src/components/GlobeBackground.tsx | sed -n '1,220p' | awk '{printf "%4d  %s\n", NR, $0}' | sed -n '70,170p'

echo
echo '--- Find the dataset loader / fetch path ---'
rg -n "space-track-leo|particlesData|requestAnimationFrame|TIME_STEP|pointOfView|SatDataItem" frontend/src/components/GlobeBackground.tsx frontend/src -S

Repository: 7-Blocks/Kepler

Length of output: 6131


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('frontend/src/components/GlobeBackground.tsx')
for i, line in enumerate(p.read_text().splitlines(), 1):
    if 80 <= i <= 170:
        print(f"{i:4d}  {line}")
PY

Repository: 7-Blocks/Kepler

Length of output: 3227


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('frontend/src/components/GlobeBackground.tsx')
for i, line in enumerate(p.read_text().splitlines(), 1):
    if 1 <= i <= 220:
        if 'particlesData' in line or 'requestAnimationFrame' in line or 'TIME_STEP' in line or 'pointOfView' in line or 'space-track-leo' in line:
            print(f"{i:4d}  {line}")
PY

Repository: 7-Blocks/Kepler

Length of output: 579


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('frontend/public/datasets/space-track-leo.txt')
count = 0
valid = 0
with p.open() as f:
    for line in f:
        if line.startswith('1 '):
            count += 1
        if line.startswith('2 '):
            valid += 1
print('line_count_starting_with_1_space =', count)
print('line_count_starting_with_2_space =', valid)
PY

Repository: 7-Blocks/Kepler

Length of output: 235


Throttle globe updates to elapsed time. This propagates the full 16,071-satellite catalog and calls particlesData on every RAF, so the work scales with refresh rate and the animation runs faster on high-Hz displays. Use RAF delta time for rotation and throttle satellite propagation/data uploads to a fixed interval.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/GlobeBackground.tsx` around lines 96 - 135, Update
the frameTicker loop to accept RAF timestamps and calculate elapsed time, using
that delta to scale globe rotation consistently across refresh rates. Accumulate
elapsed time and only propagate the satellite catalog and call
world.particlesData when the fixed update interval has elapsed, while continuing
to schedule RAF frames and preserving the existing validity filtering.

@krishkhinchi

Copy link
Copy Markdown
Member

@muntasiractive, Do not change the Home page. Instead, use the Home page's design, layout, and styling as the design standard for all other pages to maintain a consistent UI/UX. Additionally, Magic UI must be used throughout the project wherever applicable: its components are mandatory, not optional.

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

Labels

AI Artificial Intelligence and Machine Learning bug Something isn't working documentation Improvements or additions to documentation ECSoC26-L2 Level 2 contribution for the ECSoC26 event. ECSoC26 Official label for ECSoC26 event contributions. enhancement New feature or request frontend Frontend development size/XL Very large or complex contribution. type:bug Fixes an existing bug or unexpected behavior. type:documentation Improves project documentation. type:feature Introduces a new feature or enhancement. type:frontend Changes frontend or client-side code.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create an "About Kepler" Page

2 participants