feat(web): grounded UVAI one-page homepage - #172
Conversation
Rewrite `/` to mirror the static one-page positioning site at /home/user/workspace/eventrelay-onepage. The new homepage describes only proven, currently shipping capabilities and drops marketing claims that the repository does not back up. What changed - New hero, capabilities, workflow, developers, templates, and contact sections that map 1:1 to the grounded reference page. - Removed unfounded stats (10K+ videos, 500ms response, 98% accuracy) and the "deploy in one click" claims; templates are described as starting points, not auto-deploy promises. - Removed pricing/Slack/Notion/SSO/SAML/enterprise SKU references on the homepage. Existing /pricing, /features, /playground, /prototype routes are left untouched for the parent app. - Inbound form is honest: client-side validation only, opens a mailto to viralnowsales@gmail.com. No fake backend submission. - External links use rel="noopener noreferrer" and target="_blank" consistently. - Brand: public site is UVAI; EventRelay is referenced only as the open-source repo/project name in the developer section and footer. - Layout: dropped the third-party Google Fonts <link> in favor of the existing system-ui Tailwind font stack to avoid third-party font cookies. Updated metadata title/description to match the grounded positioning. Preserved - /dashboard and all /api/* routes are untouched and still build. - Existing components, workflow templates module, and design system variables (#0e0e13, #6af2de, etc.) reused so the page fits the surrounding app. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
🔍 PR Validation |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (1)**/*.tsx⚙️ CodeRabbit configuration file
Files:
🔇 Additional comments (4)
📝 WalkthroughSummary by CodeRabbit
WalkthroughRebrands site metadata to “Video to Structured Intelligence”, replaces the interactive template gallery with a static marketing landing page, adds a client-side ContactForm that opens a mailto: link, introduces a CONTACT_EMAIL constant, and removes inline Google Fonts injection from the layout. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Review rate limit: 4/5 reviews remaining, refill in 12 minutes. Comment |
✅ E2E Test Results: ALL TESTS PASSED
Test Output |
There was a problem hiding this comment.
Pull request overview
Updates the public / route of the Next.js web app to a grounded, single-page UVAI positioning site that removes unsupported marketing claims and aligns the copy with capabilities that exist in the repo.
Changes:
- Replaced
apps/web/src/app/page.tsxwith a new one-page marketing layout (hero, pipeline preview, capabilities, workflow steps, developer section, template highlights, and a mailto-based contact form). - Updated
apps/web/src/app/layout.tsxmetadata (title/description/keywords) to match the new grounded homepage messaging. - Removed the Google Fonts
<head>links fromlayout.tsxto avoid third-party font requests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| apps/web/src/app/page.tsx | Rewrites the homepage to a grounded one-pager and introduces a mailto-based inbound form. |
| apps/web/src/app/layout.tsx | Updates SEO metadata and removes Google Fonts <head> links. |
| <html lang="en"> | ||
| <head> | ||
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
| <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" /> | ||
| <link | ||
| href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=JetBrains+Mono:wght@100..800&family=Space+Grotesk:wght@300..700&display=swap" | ||
| rel="stylesheet" | ||
| /> | ||
| </head> | ||
| <body className="min-h-screen bg-surface-950 font-sans antialiased"> | ||
| {/* Global background effects */} |
There was a problem hiding this comment.
RootLayout still has a comment claiming font CSS variables are defined via Google Fonts <link> tags in <head>, but this PR removes that <head> block. Please update/remove that comment (and any related assumptions) so it matches the new approach (system-ui / locally available fonts).
| > | ||
| {template.description} | ||
| </p> | ||
| const CONTACT_EMAIL = 'viralnowsales@gmail.com'; |
There was a problem hiding this comment.
CONTACT_EMAIL is hardcoded to a personal address in the client bundle. Consider reading this from a public env var (e.g., NEXT_PUBLIC_CONTACT_EMAIL) with a safe default, so forks/deploys can configure it without code changes and to avoid baking personal contact info into OSS builds.
| const CONTACT_EMAIL = 'viralnowsales@gmail.com'; | |
| const CONTACT_EMAIL = | |
| process.env.NEXT_PUBLIC_CONTACT_EMAIL || 'contact@example.com'; |
| if (n.length > 100 || msg.length > 2000) { | ||
| setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 2,000 characters.' }); | ||
| return; |
There was a problem hiding this comment.
The mailto body allows up to 2,000 characters, but mailto: URIs have fairly low and client-dependent length limits (and URL-encoding expands the payload). This can lead to truncated bodies or failures in some email clients. Consider lowering the limit substantially or switching to a real POST endpoint (even if it just relays to email) for longer requests.
There was a problem hiding this comment.
Code Review
This pull request updates the application metadata and completely redesigns the landing page to focus on core video intelligence capabilities. Key changes include the removal of manual font loading in the layout and the introduction of a new contact form that utilizes mailto: for workflow requests. Feedback is provided to improve the YouTube URL validation by handling missing protocols and to reduce the message character limit to ensure compatibility with email client URL length restrictions.
| function isYouTube(value: string) { | ||
| if (!value) return true; | ||
| try { | ||
| const u = new URL(value); | ||
| return ['youtube.com', 'www.youtube.com', 'youtu.be', 'm.youtube.com'].includes(u.hostname); | ||
| } catch { | ||
| return false; | ||
| } | ||
| } |
There was a problem hiding this comment.
The new URL() constructor throws an error if the string does not include a protocol (e.g., youtube.com/...). Users often omit https:// when typing URLs, which will cause this validation to fail and show an error message even for valid YouTube domains. Prepending a default protocol before validation improves the user experience.
| function isYouTube(value: string) { | |
| if (!value) return true; | |
| try { | |
| const u = new URL(value); | |
| return ['youtube.com', 'www.youtube.com', 'youtu.be', 'm.youtube.com'].includes(u.hostname); | |
| } catch { | |
| return false; | |
| } | |
| } | |
| function isYouTube(value: string) { | |
| if (!value) return true; | |
| try { | |
| const urlToTest = /^https?:\/\//.test(value) ? value : `https://${value}`; | |
| const u = new URL(urlToTest); | |
| return ['youtube.com', 'www.youtube.com', 'youtu.be', 'm.youtube.com'].includes(u.hostname); | |
| } catch { | |
| return false; | |
| } | |
| } |
| if (n.length > 100 || msg.length > 2000) { | ||
| setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 2,000 characters.' }); | ||
| return; | ||
| } |
There was a problem hiding this comment.
The current validation allows a message length of up to 2,000 characters. When combined with other fields and URL encoding, the resulting mailto: link will likely exceed the character limit for many email clients and browsers (often around 2,000 characters total). This can cause the "Send request" button to fail silently or open a broken link in the user's mail client. Reducing the limit to 1,000 characters is safer for a mailto-based implementation.
| if (n.length > 100 || msg.length > 2000) { | |
| setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 2,000 characters.' }); | |
| return; | |
| } | |
| if (n.length > 100 || msg.length > 1000) { | |
| setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 1,000 characters.' }); | |
| return; | |
| } |
| id="message" | ||
| name="message" | ||
| placeholder="Example: turn product demo videos into API docs and tickets." | ||
| maxLength={2000} |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/app/page.tsx`:
- Around line 186-200: The privacy claim is inaccurate because the form data is
serialized into a mailto URI (subject/body) and handed to the OS mail handler,
and setStatus is set to 'success' before any handoff confirmation; update either
by implementing a real POST-backed submission (create an API endpoint and send
the payload via fetch/POST from the form handler, await the response, then call
setStatus({ kind: 'success', ... }) on success) or, if you keep the mailto flow
(subject/body and window.location.href =
`mailto:${CONTACT_EMAIL}?subject=${subject}&body=${body}`), change the UI text
to a softer privacy/safety message and only set a non-final status (e.g.,
'action started' or remove premature success) instead of declaring success;
update all occurrences that use CONTACT_EMAIL, subject, body,
window.location.href and setStatus (also the similar block at the other
location) accordingly.
- Around line 1-4: page.tsx is currently a Client Component solely to host the
contact form, which forces the whole homepage to hydrate; extract the form into
a new small Client Component named ContactForm (e.g.,
apps/web/src/app/ContactForm.tsx) and keep page.tsx as a Server Component. Move
the form JSX and all related client state/hooks (useState, useCallback, status
state and the existing handleSubmit logic) into ContactForm, export it as
default, and replace the inline form in page.tsx with <ContactForm /> (server
component imports a client component). Ensure all event handlers and local state
live only in ContactForm and update any imports (useState/useCallback)
accordingly so page.tsx no longer contains 'use client'.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ebebfb6e-e0e8-4484-878a-25b751df84ff
📒 Files selected for processing (2)
apps/web/src/app/layout.tsxapps/web/src/app/page.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Agent
- GitHub Check: Generate and Upload Coverage
- GitHub Check: trivy
- GitHub Check: Analyze (javascript)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.tsx
⚙️ CodeRabbit configuration file
React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.
Files:
apps/web/src/app/layout.tsxapps/web/src/app/page.tsx
🧠 Learnings (1)
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Ensure all features support the single workflow: YouTube link → context extraction → agent dispatch
Applied to files:
apps/web/src/app/page.tsx
…dback - Move mailto form into apps/web/src/app/ContactForm.tsx so page.tsx is a Server Component (no 'use client', useState, or useCallback) - Soften privacy and status copy: replace 'success' with non-final 'Trying to open your email app...' and clarify that drafts are handled by the browser or local mail app, not stored on our backend - Accept YouTube URLs without protocol by prepending https:// before validation - Reduce message maxLength from 2000 to 1000 to keep mailto URLs safe - Update stale layout comment that referenced a Google Fonts <head> link; fonts come from the system stack via tailwind.config - Read CONTACT_EMAIL from NEXT_PUBLIC_CONTACT_EMAIL with fallback to the live default
🔍 PR Validation |
|
Addressed review feedback in 6203203:
Verification:
CodeRabbit should re-review automatically on the new push. To force a fresh review, comment |
|
Tip For best results, initiate chat on the files or code changes.
Triggering a full re-review now. [full_review] |
✅ E2E Test Results: ALL TESTS PASSED
Test Output |
There was a problem hiding this comment.
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 `@apps/web/src/app/ContactForm.tsx`:
- Around line 20-24: Duplicate CONTACT_EMAIL and DEFAULT_CONTACT_EMAIL logic in
ContactForm.tsx and page.tsx should be extracted to a single shared constant;
create a module (e.g., lib/constants.ts) that exports CONTACT_EMAIL (computed
from DEFAULT_CONTACT_EMAIL and process.env.NEXT_PUBLIC_CONTACT_EMAIL) and then
replace the local definitions in both ContactForm.tsx and page.tsx by importing
CONTACT_EMAIL from that module, removing the duplicated constants so both
components use the same exported symbol.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 362b5bae-88e2-4800-844e-ffbc6379a733
📒 Files selected for processing (3)
apps/web/src/app/ContactForm.tsxapps/web/src/app/layout.tsxapps/web/src/app/page.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: test
- GitHub Check: Generate and Upload Coverage
- GitHub Check: trivy
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript)
- GitHub Check: E2E Pipeline Tests
🧰 Additional context used
📓 Path-based instructions (1)
**/*.tsx
⚙️ CodeRabbit configuration file
React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.
Files:
apps/web/src/app/layout.tsxapps/web/src/app/page.tsxapps/web/src/app/ContactForm.tsx
🧠 Learnings (4)
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Frontend uses React 18+ with TypeScript; prefer React hooks and functional components
Applied to files:
apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Extract reusable logic into custom hooks
Applied to files:
apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{tsx,jsx} : Prefer functional components with hooks in React
Applied to files:
apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/services/**/*.{ts,tsx} : Add frontend API client integrations under frontend/src/services/
Applied to files:
apps/web/src/app/page.tsx
🔇 Additional comments (8)
apps/web/src/app/page.tsx (4)
575-583: Privacy copy is accurate now.The updated text correctly states the page doesn't submit to the backend and that the draft is handled by the browser/mail app. This addresses the earlier concern about overstating guarantees.
1-2: Good extraction of ContactForm.The page is now a proper Server Component with the interactive form extracted to a Client Component. This addresses the earlier feedback about unnecessary client-side hydration.
176-184: External links properly secured.All
target="_blank"links includerel="noopener noreferrer"which prevents reverse tabnabbing attacks.
99-121: Remove unusedworkflow-templates.ts—it's dead code.
TEMPLATE_CARDSdefined locally here replaces the entireWORKFLOW_TEMPLATESandCATEGORIESexports fromapps/web/src/lib/workflow-templates.ts. The file is not imported anywhere in the codebase and serves no purpose. Delete it to eliminate dead code.apps/web/src/app/ContactForm.tsx (2)
54-100: LGTM on the submit handler.The dependency array is complete, validation is thorough, and the status correctly shows "pending" rather than claiming success before the mail client actually opens. This addresses the earlier feedback about overstating guarantees.
102-201: Good accessibility on the form.
role="status"witharia-live="polite"ensures screen readers announce validation errors without interrupting. All inputs have proper labels and autocomplete hints. No concerns here.apps/web/src/app/layout.tsx (2)
6-9: Good documentation on font strategy.The comment clearly explains why
next/font/googleis avoided (build failures when Google Fonts API is unreachable). This prevents future contributors from "fixing" it and breaking CI.
11-64: Metadata updates align with the rebrand.Title, description, keywords, and OG/Twitter cards are consistent with the new "Video to Structured Intelligence" positioning. No issues.
…s values Browser native URL validation on type='url' was blocking submission of protocol-less values like "youtube.com/watch?v=..." before our onSubmit handler could prepend https:// in isYouTube(). Switch to type='text' with inputMode='url' and autoComplete='url' for accessibility and mobile UX, and add a visible hint that https:// is optional. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
🔍 PR Validation |
✅ E2E Test Results: ALL TESTS PASSED
Test Output |
There was a problem hiding this comment.
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 `@apps/web/src/app/ContactForm.tsx`:
- Around line 21-24: CONTACT_EMAIL is chosen using
NEXT_PUBLIC_CONTACT_EMAIL.trim() to validate but then uses the untrimmed env
value, which can leave leading/trailing spaces in the mailto: link; change the
assignment to use the trimmed value (e.g., compute a trimmedEmail from
process.env.NEXT_PUBLIC_CONTACT_EMAIL?.trim(), check trimmedEmail.length > 0 and
set CONTACT_EMAIL = trimmedEmail, otherwise fallback to DEFAULT_CONTACT_EMAIL)
so the final CONTACT_EMAIL contains no surrounding whitespace.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 86c6adcc-470c-458d-8271-8d329777cb86
📒 Files selected for processing (1)
apps/web/src/app/ContactForm.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: Generate and Upload Coverage
- GitHub Check: build
- GitHub Check: npm-audit
- GitHub Check: test
- GitHub Check: python-safety
- GitHub Check: Analyze (javascript)
- GitHub Check: trivy
- GitHub Check: Analyze (python)
- GitHub Check: E2E Pipeline Tests
🧰 Additional context used
📓 Path-based instructions (1)
**/*.tsx
⚙️ CodeRabbit configuration file
React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.
Files:
apps/web/src/app/ContactForm.tsx
🔇 Additional comments (2)
apps/web/src/app/ContactForm.tsx (2)
33-42: YouTube normalization logic is solid.Accepting protocol-less input and normalizing before URL parsing avoids false negatives while keeping host allowlisting strict.
186-200: Status announcement pattern is accessibility-friendly.Using a live region for async/error feedback here is a good implementation choice.
Move the duplicated CONTACT_EMAIL / DEFAULT_CONTACT_EMAIL logic into apps/web/src/lib/constants.ts and import it from both ContactForm.tsx and page.tsx. Addresses CodeRabbit feedback on PR #172.
🔍 PR Validation |
✅ E2E Test Results: ALL TESTS PASSED
Test Output |
🔍 PR Validation |
✅ E2E Test Results: ALL TESTS PASSED
Test Output |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
apps/web/src/lib/constants.ts (1)
3-6:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse the trimmed env value in
CONTACT_EMAIL.
NEXT_PUBLIC_CONTACT_EMAILis validated with.trim(), but the exported value is still the raw env string. If the env var has leading/trailing spaces, every homepagemailto:link can break.🔧 Minimal fix
const DEFAULT_CONTACT_EMAIL = 'viralnowsales@gmail.com'; +const trimmedContactEmail = (process.env.NEXT_PUBLIC_CONTACT_EMAIL ?? '').trim(); export const CONTACT_EMAIL = - process.env.NEXT_PUBLIC_CONTACT_EMAIL && process.env.NEXT_PUBLIC_CONTACT_EMAIL.trim().length > 0 - ? process.env.NEXT_PUBLIC_CONTACT_EMAIL - : DEFAULT_CONTACT_EMAIL; + trimmedContactEmail || DEFAULT_CONTACT_EMAIL;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/lib/constants.ts` around lines 3 - 6, The exported CONTACT_EMAIL uses the raw NEXT_PUBLIC_CONTACT_EMAIL despite validating with .trim(), which allows leading/trailing spaces to persist; update the logic for CONTACT_EMAIL to compute a local env string (e.g., read process.env.NEXT_PUBLIC_CONTACT_EMAIL into a variable), call .trim() safely only when the var is defined, and use the trimmed value in the ternary so CONTACT_EMAIL becomes either the trimmed NEXT_PUBLIC_CONTACT_EMAIL or DEFAULT_CONTACT_EMAIL; reference CONTACT_EMAIL, NEXT_PUBLIC_CONTACT_EMAIL, and DEFAULT_CONTACT_EMAIL when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/app/ContactForm.tsx`:
- Around line 31-34: Validation currently normalizes protocol-less YouTube
inputs into the local variable candidate (and URL u) but the draft email still
uses the original raw videoUrl, producing non-clickable links; modify the flow
to normalize once and reuse that normalized value when building the outgoing
draft body and anywhere the URL is used (replace uses of the raw videoUrl with a
single normalized variable like normalizedVideoUrl / candidate), and apply the
same change to the other validation/usage sites referenced (the blocks around
lines 53-57 and 74-90) so validation and outgoing content use the exact same
normalized URL.
In `@apps/web/src/app/page.tsx`:
- Around line 154-168: The nav links point to hash IDs (e.g., '#capabilities',
'#workflow', '#developers', '#contact') but the fixed header covers the anchored
headings; add scroll offset by applying CSS scroll-margin-top to each target
element (the section or heading elements that have id="capabilities" etc.).
Update the page.tsx targets (the elements that render those IDs) to include a
class like "scroll-mt-20" or inline style {scrollMarginTop:
'var(--header-height)'} (or a pixel value) so clicking the <a> tags in the
mapped links scrolls the section below the fixed navbar; apply the same change
to the other listed IDs (lines referenced) to fix all anchors.
---
Duplicate comments:
In `@apps/web/src/lib/constants.ts`:
- Around line 3-6: The exported CONTACT_EMAIL uses the raw
NEXT_PUBLIC_CONTACT_EMAIL despite validating with .trim(), which allows
leading/trailing spaces to persist; update the logic for CONTACT_EMAIL to
compute a local env string (e.g., read process.env.NEXT_PUBLIC_CONTACT_EMAIL
into a variable), call .trim() safely only when the var is defined, and use the
trimmed value in the ternary so CONTACT_EMAIL becomes either the trimmed
NEXT_PUBLIC_CONTACT_EMAIL or DEFAULT_CONTACT_EMAIL; reference CONTACT_EMAIL,
NEXT_PUBLIC_CONTACT_EMAIL, and DEFAULT_CONTACT_EMAIL when making the change.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: f2ce6f31-92ee-4b96-9303-51d4699bb2f0
📒 Files selected for processing (3)
apps/web/src/app/ContactForm.tsxapps/web/src/app/page.tsxapps/web/src/lib/constants.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Generate and Upload Coverage
- GitHub Check: Analyze (javascript)
- GitHub Check: Analyze (python)
- GitHub Check: trivy
🧰 Additional context used
📓 Path-based instructions (2)
**/*.tsx
⚙️ CodeRabbit configuration file
React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.
Files:
apps/web/src/app/ContactForm.tsxapps/web/src/app/page.tsx
**/*.ts
⚙️ CodeRabbit configuration file
This is a TypeScript/Next.js project. Focus on type safety, null checks, async/await error handling, and SSE stream lifecycle management. Flag any fetch() calls without AbortSignal.timeout. Check for proper error boundaries. Flag any TODO, placeholder, or stub implementations that are not production-ready. Enforce TypeScript strict mode compliance — flag implicit any, missing return types, and unsafe type assertions.
Files:
apps/web/src/lib/constants.ts
🧠 Learnings (4)
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Frontend uses React 18+ with TypeScript; prefer React hooks and functional components
Applied to files:
apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Extract reusable logic into custom hooks
Applied to files:
apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/services/**/*.{ts,tsx} : Add frontend API client integrations under frontend/src/services/
Applied to files:
apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{tsx,jsx} : Prefer functional components with hooks in React
Applied to files:
apps/web/src/app/page.tsx
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
- ContactForm: extract normalizeVideoUrl helper; apply normalization to the trimmed video URL once and use that value for both validation and the outgoing mailto body. - page.tsx: add scroll-mt-24 to #capabilities, #workflow, #developers, and #contact so the sticky header does not cover hash-link targets.
🔍 PR Validation |
✅ E2E Test Results: ALL TESTS PASSED
Test Output |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary
Rewrites
/to be the grounded UVAI one-page positioning site, matching the static reference at/home/user/workspace/eventrelay-onepage. The page now reflects only proven repo capabilities (YouTube transcript, typed event extraction, Gemini/OpenAI analysis, SSE pipeline, OpenAPI, Docker/Cloud Run/Railway/Vercel, MIT) and drops unsupported homepage claims.What changed
apps/web/src/app/page.tsxwith the grounded one-pager: hero, pipeline preview, capabilities, workflow steps, developers panel, four template highlights (with a pointer to the dashboard for the rest), and an honest mailto-based inbound form.apps/web/src/app/layout.tsx: removed third-party Google Fonts<link>(uses existingsystem-uiTailwind stack — avoids third-party font cookies). Updated metadata title/description to match grounded copy.rel="noopener noreferrer"withtarget="_blank".Preserved
/dashboardand all/api/*routes are untouched and still build (build output confirms 20 routes including/dashboard,/dashboard/agents, and every existing API route)./features,/pricing,/playground,/prototype) untouched.Test plan
npm run build(Next.js 16 / Turbopack) — succeeded; static pages generated; both/and/dashboardrouted.npx eslint src/app/page.tsx src/app/layout.tsx --max-warnings=0— clean.Notes / risks
npm run lintscript uses Next 15'snext lint --dir srcwhich Next 16 removed — pre-existing repo issue, unrelated to this PR. Directeslintinvocation passes.--legacy-peer-depsdue to a pre-existing vitest/@opentelemetry peer conflict in the monorepo./pricing) is still in the app from earlier work; only homepage messaging is updated as scoped.🤖 Generated with Claude Code