Skip to content

Commit aa1c366

Browse files
mariuspruvotclaude
andauthored
refactor(web): replace marketing landing with minimal login page (#48)
The self-hosted, OSS nature of the app makes a full marketing landing redundant — the README already covers discovery, and instance visitors just need a way to sign in. Drops ~460 lines of SaaS-style content in favor of a terse mono/accent login screen. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c27e6a2 commit aa1c366

9 files changed

Lines changed: 68 additions & 465 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ apps/api/ — FastAPI backend (Python 3.12, uv)
2121
tests/ — mirrors modules/ structure
2222
alembic/ — DB migrations
2323
apps/web/ — React frontend (Vite, TypeScript)
24-
src/features/ — feature modules: auth, dashboard, landing, installation, session
24+
src/features/ — feature modules: auth, dashboard, installation, session
2525
src/shared/ — API client (shared/api/client.ts)
2626
skills/ — Claude Code skill definitions (mounted into ephemeral containers)
2727
infra/

apps/web/src/app.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import SessionReplay from './features/dashboard/SessionReplay'
99
import SetupView from './features/installation/SetupView'
1010
import SettingsView from './features/installation/SettingsView'
1111
import SessionView from './features/session/SessionView'
12-
import LandingPage from './features/landing/LandingPage'
12+
import LoginPage from './features/auth/LoginPage'
1313

1414
function AuthRedirect() {
1515
const isAuthenticated = useAuthStore((s) => s.isAuthenticated)
1616
if (isAuthenticated) return <Navigate to="/installations" replace />
17-
return <LandingPage />
17+
return <LoginPage />
1818
}
1919

2020
export default function App() {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { cleanup, render, screen } from '@testing-library/react'
2+
import { afterEach, describe, expect, test } from 'vitest'
3+
import LoginPage from './LoginPage'
4+
5+
afterEach(() => cleanup())
6+
7+
describe('LoginPage', () => {
8+
test('renders helPRs wordmark', () => {
9+
render(<LoginPage />)
10+
expect(screen.getByText('helPRs')).toBeTruthy()
11+
})
12+
13+
test('renders sign-in link pointing to GitHub OAuth', () => {
14+
render(<LoginPage />)
15+
const link = screen.getByRole('link', { name: /sign in with github/i })
16+
expect(link.getAttribute('href')).toContain('/api/v1/auth/github')
17+
})
18+
19+
test('renders link to the GitHub repo', () => {
20+
render(<LoginPage />)
21+
const link = screen.getByRole('link', { name: /view on github/i })
22+
expect(link.getAttribute('href')).toContain('github.com/mariuspruvot/helprs')
23+
})
24+
25+
test('renders tagline', () => {
26+
const { container } = render(<LoginPage />)
27+
expect(container.textContent).toContain('Self-hosted')
28+
})
29+
})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Button, GrainOverlay } from '../../shared/components'
2+
3+
const API_BASE = import.meta.env.VITE_API_URL ?? 'http://localhost:8000'
4+
const GITHUB_URL = 'https://github.com/mariuspruvot/helprs'
5+
6+
export default function LoginPage() {
7+
return (
8+
<div className="relative min-h-screen bg-bg text-ink font-sans flex flex-col items-center justify-center px-6">
9+
<GrainOverlay />
10+
11+
<main className="relative flex flex-col items-center text-center max-w-md w-full">
12+
<span className="font-mono text-3xl font-bold text-accent tracking-tight">helPRs</span>
13+
<p className="mt-4 text-ink2 text-sm leading-relaxed font-mono">
14+
Claude Code on your PRs. Self-hosted.
15+
</p>
16+
17+
<a href={`${API_BASE}/api/v1/auth/github`} className="mt-10 w-full sm:w-auto">
18+
<Button className="w-full sm:w-auto px-6 py-3">Sign in with GitHub</Button>
19+
</a>
20+
21+
<a
22+
href={GITHUB_URL}
23+
target="_blank"
24+
rel="noopener noreferrer"
25+
className="mt-6 font-mono text-xs text-dim hover:text-ink2 transition-colors"
26+
>
27+
View on GitHub {'\u2192'}
28+
</a>
29+
</main>
30+
31+
<footer className="relative mt-16 font-mono text-xs text-dim">
32+
{'// MIT \u00B7 open source'}
33+
</footer>
34+
</div>
35+
)
36+
}

apps/web/src/features/landing/InstallCTA.test.tsx

Lines changed: 0 additions & 48 deletions
This file was deleted.

apps/web/src/features/landing/InstallCTA.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.

apps/web/src/features/landing/LandingPage.test.tsx

Lines changed: 0 additions & 95 deletions
This file was deleted.

0 commit comments

Comments
 (0)