Skip to content

feat(docs): randomize hero terminal demo across integrations#263

Open
rubenmarcus wants to merge 2 commits intomainfrom
feat/hero-randomization
Open

feat(docs): randomize hero terminal demo across integrations#263
rubenmarcus wants to merge 2 commits intomainfrom
feat/hero-randomization

Conversation

@rubenmarcus
Copy link
Copy Markdown
Member

Summary

  • Hero section now randomly shows one of 4 integration workflows (Figma, GitHub, Linear, Notion) on each page load
  • Each scenario has its own tagline, subtitle, terminal demo, and highlighted integration logo
  • Figma remains the SSR default (safe for crawlers/SEO)
  • Layout description updated to be integration-neutral

Test plan

  • Reload homepage multiple times — different terminal demos appear
  • Each scenario shows correct tagline, command, and output
  • Active integration logo is highlighted (not grayscale)
  • Mobile/tablet responsive layout preserved
  • pnpm build in docs/ passes

🤖 Generated with Claude Code

The hero section now randomly shows one of four integration workflows
(Figma, GitHub, Linear, Notion) on each page load, with matching
taglines and highlighted integration logos. Figma is the SSR default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 6, 2026

Issue Linking Reminder

This PR doesn't appear to have a linked issue. Consider linking to:

  • This repo: Closes #123
  • ralph-ideas: Closes multivmlabs/ralph-ideas#123

Using Closes, Fixes, or Resolves will auto-close the issue when this PR is merged.


If this PR doesn't need an issue, you can ignore this message.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR makes the hero section's terminal demo dynamic: on each client-side page load one of four integration scenarios (Figma, GitHub, Linear, Notion) is randomly selected, updating the tagline, subtitle, command output, and the highlighted integration logo. Figma remains the SSR default (index 0), keeping the crawlable HTML stable for SEO.

The approach is clean and low-risk for the HeroSection itself, but the index.tsx page file introduces three new component imports (FigmaShowcase, VisualValidation, AgentEcosystem) that do not exist in the repository, which will cause the pnpm build to fail.

Key observations:

  • Build-breaking: FigmaShowcase, VisualValidation, and AgentEcosystem are imported in docs/src/pages/index.tsx but have no corresponding component files — the documented test plan step pnpm build in docs/ passes will not pass.
  • Convention: DemoScenario is declared as an interface but the project convention prefers type for plain data structures without inheritance.
  • Effect cleanup: Math.random() selection and the visibility timer share a single useEffect; only the timer is cleaned up on unmount. Splitting into two effects would be safer.
  • CSS change: The .integrationLogoActive selector is correctly added alongside :hover to highlight the active logo — straightforward and correct.

Confidence Score: 2/5

  • Not safe to merge — three missing component files will cause a build failure.
  • The HeroSection changes themselves are solid and low-risk. However, docs/src/pages/index.tsx imports FigmaShowcase, VisualValidation, and AgentEcosystem which do not exist anywhere in the repository. This is a hard build error that will fail pnpm build in docs/, directly contradicting the PR's own test plan. The score is kept at 2 rather than 0 because the core hero randomisation logic is correct and the missing components may simply be omitted from the PR by mistake.
  • docs/src/pages/index.tsx — imports three components that do not exist; docs/src/components/HeroSection/index.tsx — minor style and effect-cleanup issues.

Important Files Changed

Filename Overview
docs/src/components/HeroSection/index.tsx Core change: adds 4 DemoScenario data objects and randomises the active scenario client-side via useEffect. Minor issues: interface should be type per project convention; Math.random() and the visibility timer share one effect (only the timer is cleaned up); array-index keys used for output lines.
docs/src/components/HeroSection/styles.module.css Minimal CSS change: adds .integrationLogoActive alongside the existing :hover rule so the active integration logo is shown in full colour. Clean and correct.
docs/src/pages/index.tsx Adds FigmaShowcase, VisualValidation, and AgentEcosystem components; removes ClientShowcase and LLMProviders; reorders the section sequence. The diff itself is safe, but several of the newly imported components are not in the PR changeset — their existence should be verified before merge.

Sequence Diagram

sequenceDiagram
    participant SSR as SSR / Crawler
    participant Browser as Browser (Client)
    participant HeroSection as HeroSection Component

    SSR->>HeroSection: Render (scenarioIndex = 0 → Figma)
    HeroSection-->>SSR: Static HTML with Figma tagline/terminal

    Browser->>HeroSection: Hydrate
    HeroSection->>HeroSection: useEffect fires
    HeroSection->>HeroSection: setScenarioIndex(Math.random() * 4)
    HeroSection->>HeroSection: setTimeout → setIsVisible(true)
    HeroSection-->>Browser: Re-render with random scenario (Figma/GitHub/Linear/Notion)
    HeroSection-->>Browser: Highlight active integration logo (integrationLogoActive)
Loading

Last reviewed commit: a24245d

Comment on lines +6 to +13
interface DemoScenario {
id: 'figma' | 'github' | 'linear' | 'notion';
tagline: [string, string];
subtitle: string;
command: string;
outputLines: string[];
successLine: string;
}
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.

interface instead of type for DemoScenario

DemoScenario is a plain data structure with no inheritance or extension — the project's conventions prefer type over interface for such shapes.

Suggested change
interface DemoScenario {
id: 'figma' | 'github' | 'linear' | 'notion';
tagline: [string, string];
subtitle: string;
command: string;
outputLines: string[];
successLine: string;
}
type DemoScenario = {
id: 'figma' | 'github' | 'linear' | 'notion';
tagline: [string, string];
subtitle: string;
command: string;
outputLines: string[];
successLine: string;
};

Context Used: Rule from dashboard - Use type by default in TypeScript unless you specifically need interface features like extension... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/src/components/HeroSection/index.tsx
Line: 6-13

Comment:
**`interface` instead of `type` for `DemoScenario`**

`DemoScenario` is a plain data structure with no inheritance or extension — the project's conventions prefer `type` over `interface` for such shapes.

```suggestion
type DemoScenario = {
  id: 'figma' | 'github' | 'linear' | 'notion';
  tagline: [string, string];
  subtitle: string;
  command: string;
  outputLines: string[];
  successLine: string;
};
```

**Context Used:** Rule from `dashboard` - Use `type` by default in TypeScript unless you specifically need `interface` features like extension... ([source](https://app.greptile.com/review/custom-context?memory=c862f053-5655-4b41-be69-c840e3c9f280))

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!

Comment on lines +85 to 91
const [scenarioIndex, setScenarioIndex] = useState(0);

useEffect(() => {
setScenarioIndex(Math.floor(Math.random() * DEMO_SCENARIOS.length));
const timer = setTimeout(() => setIsVisible(true), 100);
return () => clearTimeout(timer);
}, []);
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.

SSR hydration mismatch from Math.random() in useEffect

scenarioIndex is initialised to 0 (Figma) at render time, and then setScenarioIndex(Math.floor(Math.random() * …)) runs in useEffect after hydration. This is intentional for SSR/SEO (Figma is the safe default), but the two setScenarioIndex + setTimeout calls share one useEffect and only the timer is cleaned up. If the component were ever unmounted before the effect runs the setScenarioIndex call would still execute, causing a state-update-on-unmounted-component warning. Consider splitting them into two separate effects, or guarding with a ref:

Suggested change
const [scenarioIndex, setScenarioIndex] = useState(0);
useEffect(() => {
setScenarioIndex(Math.floor(Math.random() * DEMO_SCENARIOS.length));
const timer = setTimeout(() => setIsVisible(true), 100);
return () => clearTimeout(timer);
}, []);
useEffect(() => {
setScenarioIndex(Math.floor(Math.random() * DEMO_SCENARIOS.length));
}, []);
useEffect(() => {
const timer = setTimeout(() => setIsVisible(true), 100);
return () => clearTimeout(timer);
}, []);
Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/src/components/HeroSection/index.tsx
Line: 85-91

Comment:
**SSR hydration mismatch from `Math.random()` in `useEffect`**

`scenarioIndex` is initialised to `0` (Figma) at render time, and then `setScenarioIndex(Math.floor(Math.random() * …))` runs in `useEffect` after hydration. This is intentional for SSR/SEO (Figma is the safe default), but the two `setScenarioIndex` + `setTimeout` calls share one `useEffect` and only the timer is cleaned up. If the component were ever unmounted before the effect runs the `setScenarioIndex` call would still execute, causing a state-update-on-unmounted-component warning. Consider splitting them into two separate effects, or guarding with a ref:

```suggestion
  useEffect(() => {
    setScenarioIndex(Math.floor(Math.random() * DEMO_SCENARIOS.length));
  }, []);

  useEffect(() => {
    const timer = setTimeout(() => setIsVisible(true), 100);
    return () => clearTimeout(timer);
  }, []);
```

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

Comment on lines +138 to 143
{scenario.subtitle} Also works with {
['Figma', 'GitHub', 'Linear', 'Notion']
.filter(name => name.toLowerCase() !== scenario.id)
.join(', ')
} specs.
</p>
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.

Subtitle "Also works with" text not updated during SSR

On the server, scenarioIndex is 0 (Figma), so the subtitle correctly says "Also works with GitHub, Linear, Notion specs." After the client-side useEffect fires and picks a different scenario, the subtitle switches. This is fine for the crawlable SSR output.

However, the filter comparison uses name.toLowerCase() !== scenario.id. The IDs are already lowercase ('figma', 'github', etc.) and the display names are title-case ('Figma', 'GitHub', etc.). 'GitHub'.toLowerCase()'github' matches correctly, so the logic is sound. No bug here, just worth a note that this implicit casing convention should be kept consistent if new integrations are added.

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/src/components/HeroSection/index.tsx
Line: 138-143

Comment:
**Subtitle "Also works with" text not updated during SSR**

On the server, `scenarioIndex` is `0` (Figma), so the subtitle correctly says "Also works with GitHub, Linear, Notion specs." After the client-side `useEffect` fires and picks a different scenario, the subtitle switches. This is fine for the crawlable SSR output.

However, the filter comparison uses `name.toLowerCase() !== scenario.id`. The IDs are already lowercase (`'figma'`, `'github'`, etc.) and the display names are title-case (`'Figma'`, `'GitHub'`, etc.). `'GitHub'.toLowerCase()``'github'` matches correctly, so the logic is sound. No bug here, just worth a note that this implicit casing convention should be kept consistent if new integrations are added.

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

Comment on lines +5 to +7
import HeroSection from '@site/src/components/HeroSection';
import FigmaShowcase from '@site/src/components/FigmaShowcase';
import VisualValidation from '@site/src/components/VisualValidation';
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.

Missing component files — build will fail

FigmaShowcase, VisualValidation, and AgentEcosystem are imported here but none of these files exist anywhere under docs/src/components/. The directory currently contains only:

AIToggle, AutoMode, ClientShowcase, DownloadDocs, FeatureSections, HeroSection, HomepageFeatures, IntegrationShowcase, LLMProviders, PresetsShowcase, QuickStart, SkillsShowcase, UseCases.

Running pnpm build in docs/ will fail with a module-not-found error for each of these three imports. They need to be created (or the imports need to be removed) before this PR is mergeable.

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/src/pages/index.tsx
Line: 5-7

Comment:
**Missing component files — build will fail**

`FigmaShowcase`, `VisualValidation`, and `AgentEcosystem` are imported here but none of these files exist anywhere under `docs/src/components/`. The directory currently contains only:

`AIToggle`, `AutoMode`, `ClientShowcase`, `DownloadDocs`, `FeatureSections`, `HeroSection`, `HomepageFeatures`, `IntegrationShowcase`, `LLMProviders`, `PresetsShowcase`, `QuickStart`, `SkillsShowcase`, `UseCases`.

Running `pnpm build` in `docs/` will fail with a module-not-found error for each of these three imports. They need to be created (or the imports need to be removed) before this PR is mergeable.

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

Copy link
Copy Markdown

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

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: a24245d22c

ℹ️ 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".

import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import HeroSection from '@site/src/components/HeroSection';
import FigmaShowcase from '@site/src/components/FigmaShowcase';
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 existing homepage sections instead of missing modules

index.tsx now imports and renders FigmaShowcase, VisualValidation, and AgentEcosystem, but these modules are not present anywhere under docs/src/components in this commit, so the docs app cannot resolve these imports during build/bundle. This makes the homepage fail to compile until the imports are reverted to existing components or the missing component modules are added.

Useful? React with 👍 / 👎.

/>
</Link>
{[
{ id: 'figma' as const, to: '/docs/cli/figma', src: '/img/figma-logo.svg', alt: 'Figma' },
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 Point Figma integration logo at the sources route

The Figma logo link was changed to /docs/cli/figma, but this repo only defines the Figma docs page under the sources section (docs/docs/sources/figma.md, and other internal links use /docs/sources/figma). Clicking the hero Figma logo will therefore route users to a non-existent page instead of the Figma integration documentation.

Useful? React with 👍 / 👎.

The index.tsx referenced FigmaShowcase, VisualValidation, and
AgentEcosystem components that were never created. Restored the
original ClientShowcase and LLMProviders components that exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant