1- 'use client'
2-
3- import AppStoreButton from '@/components/AppStoreButton'
4- import GooglePlayButton from '@/components/GooglePlayButton'
5- import { useState , useEffect } from 'react'
6- import { TextBasedHowItWorks , YoutubeDemoSection } from '@/components/marketing'
7- import TextBasedFeatures from '@/components/marketing/TextBasedFeatures'
8- import AdaptiveTerminal from '@/components/AdaptiveTerminal'
9- import LaunchWebAppButton from '@/components/WebAppButton'
10- import StarOnGithubButton from '@/components/GithubButton'
11- import VideoComposite from '@/components/VideoComposite'
12- import Testimonials from '@/components/Testimonials'
13-
14- const GOOGLE_PLAY_LINK = 'https://play.google.com/store/apps/details?id=com.ex3ndr.happy'
15- const APP_STORE_LINK = 'https://apps.apple.com/us/app/happy-claude-code-client/id6748571505'
16-
17-
18- function DesktopHeroSection ( ) {
19- // Device detection state
20- const [ deviceType , setDeviceType ] = useState < 'ios' | 'android' | 'desktop' > ( 'desktop' )
21-
22- useEffect ( ( ) => {
23- // Client-side device detection
24- const userAgent = navigator . userAgent . toLowerCase ( )
25-
26- if ( / i p h o n e | i p a d | i p o d / . test ( userAgent ) ) {
27- setDeviceType ( 'ios' )
28- } else if ( / a n d r o i d / . test ( userAgent ) ) {
29- setDeviceType ( 'android' )
30- } else {
31- setDeviceType ( 'desktop' )
32- }
33- } , [ ] )
34-
35- // Render store buttons based on device type
36- const renderStoreButtons = ( ) => {
37- switch ( deviceType ) {
38- case 'ios' :
39- return (
40- < >
41- < AppStoreButton href = { APP_STORE_LINK } />
42- </ >
43- )
44- case 'android' :
45- return (
46- < >
47- < GooglePlayButton href = { GOOGLE_PLAY_LINK } />
48- </ >
49- )
50- case 'desktop' :
51- default :
52- return (
53- < >
54- < GooglePlayButton href = { GOOGLE_PLAY_LINK } />
55- < AppStoreButton href = { APP_STORE_LINK } />
56- </ >
57- )
58- }
59- }
60-
61- return (
62- < section className = "py-8 pb-24 md:py-24 xl:py-32 hidden sm:block font-mono" >
63- < div className = "max-w-[72ch] mx-auto px-5" >
64- < div className = "" >
65- < div >
66- < h1 className = "text-3xl sm:text-3xl font-bold mb-5 leading-tight" >
67- Claude Code Anywhere
68- </ h1 >
69-
70- < YoutubeDemoSection
71- youtubeId = "GCS0OG9QMSE"
72- posterImage = "https://img.youtube.com/vi/GCS0OG9QMSE/maxresdefault.jpg"
73- />
74-
75- < div className = "mb-6 text-base text-gray-700 dark:text-gray-300" >
76- < div className = "flex items-start mb-4 " >
77- < span > Works seamlessly with your existing tools and workflow</ span >
78- </ div >
79- < div className = "flex items-start mb-4" >
80- < span > Open source (MIT licensed)</ span >
81- </ div >
82- < div className = "flex items-start mb-4" >
83- < span > Secure with end-to-end encryption</ span >
84- </ div >
85- < div className = "flex items-start mb-4" >
86- < span > Multiple active sessions across multiple machines</ span >
87- </ div >
88- < AdaptiveTerminal command = "npm i -g happy-coder && happy" />
89- </ div >
90-
91- < div className = "grid grid-cols-2 gap-4 sm:flex sm:gap-4 sm:flex-wrap" >
92- < GooglePlayButton href = { GOOGLE_PLAY_LINK } />
93- < AppStoreButton href = { APP_STORE_LINK } />
94- < LaunchWebAppButton href = "https://app.happy.engineering" />
95- < StarOnGithubButton href = "https://github.com/slopus/happy" />
96- </ div >
97-
98- </ div >
99- </ div >
100- </ div >
101- </ section >
102- )
1+ import type { Metadata } from 'next'
2+ import HomePage from '@/components/marketing/HomePage'
3+
4+ export const metadata : Metadata = {
5+ alternates : {
6+ canonical : '/' ,
7+ } ,
8+ openGraph : {
9+ url : '/' ,
10+ } ,
10311}
10412
10513export default function Home ( ) {
106-
107-
108- return (
109- < >
110- < div className = "max-w-[74ch] mx-auto px-2.5 sm:px-[2ch] pt-8" >
111- < h1 className = "text-3xl sm:text-3xl font-bold leading-tight mb-2" >
112- Claude Code Anywhere
113- </ h1 >
114- < p className = "text-base text-gray-700 dark:text-gray-300 mb-2" >
115- Spawn and control multiple Claude Codes in parallel. Happy Coder runs on
116- your hardware, works from your phone and desktop, and costs nothing.
117- Open source.
118- </ p >
119- </ div >
120-
121- < VideoComposite />
122-
123- < section className = "max-w-[72ch] mx-auto px-2.5 md:px-0" >
124- < div className = "mb-6" >
125- < AdaptiveTerminal command = "npm i -g happy-coder && happy" />
126- </ div >
127-
128- < div className = "grid grid-cols-2 gap-4 sm:flex sm:gap-4 sm:flex-wrap" >
129- < GooglePlayButton href = { GOOGLE_PLAY_LINK } />
130- < AppStoreButton href = { APP_STORE_LINK } />
131- < LaunchWebAppButton href = "https://app.happy.engineering" />
132- < StarOnGithubButton href = "https://github.com/slopus/happy" />
133- </ div >
134- < div className = "mt-6 text-base text-gray-700 dark:text-gray-300 font-mono" >
135- < div className = "flex items-start mb-4 " >
136- < span > Hands-free control with voice agent—not just dictation</ span >
137- </ div >
138- < div className = "flex items-start mb-4" >
139- < span > Multiple active sessions across multiple machines</ span >
140- </ div >
141- < div className = "flex items-start mb-4" >
142- < span > Works seamlessly with your existing tools and workflow</ span >
143- </ div >
144- < div className = "flex items-start mb-4" >
145- < span > Secure with end-to-end encryption</ span >
146- </ div >
147- < div className = "flex items-start mb-10" >
148- < span > Open source (MIT licensed)</ span >
149- </ div >
150- </ div >
151- </ section >
152-
153-
154- < section className = "max-w-[72ch] mx-auto py-12 px-2.5 md:px-0" >
155- < TextBasedFeatures />
156- </ section >
157- < section className = "max-w-5xl mx-auto" >
158- < Testimonials layout = "masonry" />
159- </ section >
160- < section className = "max-w-[72ch] mx-auto py-12 px-2.5 md:px-0" >
161- < TextBasedHowItWorks />
162- </ section >
163- { /*
164- <YoutubeDemoSection
165- youtubeId="GCS0OG9QMSE"
166- posterImage="https://img.youtube.com/vi/GCS0OG9QMSE/maxresdefault.jpg"
167- />
168- */ }
169- </ >
170- )
171- }
14+ return < HomePage />
15+ }
0 commit comments