Restore marketing landing page at /. - #46
Conversation
Stop auto-redirecting the root URL to /login so querycraft.xyz shows the homepage; Launch App still routes to login or dashboard. Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
🟡 Changes recommended
The new client-side effects include a timer-driven state update that can fire after unmount, and the new popover lacks key accessibility behaviors/attributes that should be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Restores the root (/) route as a marketing landing page instead of immediately redirecting users to /login, while still offering a “Launch App” path into the authenticated experience.
Changes:
- Replaced the root redirect-only page with a full marketing homepage layout (hero, workspace tiles, CTA, footer).
- Added theme switching UI and an optional animated background / pointer effects that respect reduced-motion and data-saver hints.
- Updated “Launch App” and workspace links to route to
/login(withnext=) for unauthenticated users.
File summaries
| File | Description |
|---|---|
| src/app/page.tsx | Replaces root redirect logic with a full marketing homepage, including theme controls and animated visuals. |
Review details
Suppressed comments (2)
src/app/page.tsx:285
- Click-bursts are removed via setTimeout in the pointer handler; switching to onAnimationComplete avoids timers and prevents state updates after unmount.
<motion.div
key={burst.id}
aria-hidden
className="pointer-events-none fixed z-30 h-3 w-3 border border-primary"
initial={{ x: burst.x, y: burst.y, scale: 0.2, opacity: 0.95, rotate: 20 }}
src/app/page.tsx:27
- After switching TileWaveCanvas to a dynamic import, define the dynamic component once (before render) similarly to src/app/our-team/page.tsx.
import { useEffect, useRef, useState, useSyncExternalStore, type ReactNode } from 'react';
const tools: { title: string; description: string; href: string; icon: ReactNode }[] = [
- Files reviewed: 1/1 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| setClickBursts((previous) => [...previous.slice(-4), { id: burstId, x: event.clientX, y: event.clientY }]); | ||
|
|
||
| window.setTimeout(() => { | ||
| setClickBursts((previous) => previous.filter((burst) => burst.id !== burstId)); | ||
| }, 420); |
| import Link from 'next/link'; | ||
| import { motion } from 'framer-motion'; | ||
| import TileWaveCanvas from '@/shared/ui/marketing/TileWaveCanvas'; | ||
| import { useTestAuth } from '@/features/test-module/hooks/use-test-auth'; | ||
| import { useThemeStore } from '@/shared/ui/theme/store'; |
| <button | ||
| onClick={() => setThemeMenuOpen(!themeMenuOpen)} | ||
| className="rounded-lg p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground" | ||
| aria-label="Switch theme" | ||
| > | ||
| <Palette size={16} suppressHydrationWarning /> | ||
| </button> | ||
|
|
||
| {themeMenuOpen && ( | ||
| <div className="qc-popover absolute right-0 top-full z-[500] mt-2 w-[340px] overflow-hidden rounded-2xl"> | ||
| <div className="p-3"> |
| useEffect(() => { | ||
| if (!hydrated) return; | ||
| if (!isAuthenticated || !user) { | ||
| router.replace('/login'); | ||
| return; | ||
| } | ||
| router.replace(user.role === 'admin' ? '/admin' : '/dashboard'); | ||
| }, [hydrated, isAuthenticated, router, user]); | ||
|
|
||
| return null; | ||
| if (!themeMenuOpen) return; | ||
| const handleOutsideClick = (e: MouseEvent) => { | ||
| if (themeMenuRef.current && !themeMenuRef.current.contains(e.target as Node)) { | ||
| setThemeMenuOpen(false); |
Stop auto-redirecting the root URL to /login so querycraft.xyz shows the homepage; Launch App still routes to login or dashboard.