@@ -30,9 +30,7 @@ pub fn LandingPage() -> impl IntoView {
3030
3131 let auth_github_url = move || format ! ( "{}/auth/github" , api_base( ) ) ;
3232
33- // 2. STRUCTURED DATA (JSON-LD)
34- // Defines the site as a 'SoftwareApplication' for search engines[cite: 52].
35- // This allows Google to display "Free", "Web/WASM", and feature lists in snippets[cite: 53].
33+ // 2. STRUCTURED DATA (JSON-LD)
3634 let schema_json = r#"{
3735 "@context": "https://schema.org",
3836 "@type": "SoftwareApplication",
@@ -47,24 +45,18 @@ pub fn LandingPage() -> impl IntoView {
4745 "featureList": "Docker Integration, In-Browser Terminal, Markdown Guides"
4846 }"# ;
4947
50-
51-
5248 view ! {
5349 <>
54- // 4. SEO METADATA
55- // Explicit Title and Description for correct indexing[cite: 22].
50+ // 4. SEO METADATA
5651 <Title text="TryCLI - Interactive CLI Demos & Embeds" />
5752 <Meta name="description" content="Host, share, and embed fully interactive CLI demos directly in the browser. Think Replit, but purpose-built for command-line applications." />
5853
59- // Canonical Link (Essential for preventing duplicate content penalties)[cite: 33].
6054 <Link rel="canonical" href="https://trycli.com" />
6155
62- // JSON-LD Script Injection via leptos_meta[cite: 54].
6356 <Script type_="application/ld+json" >
6457 { schema_json}
6558 </Script >
6659
67- // Open Graph & Twitter Cards (Social Sharing)[cite: 45].
6860 <Meta property="og:type" content="website" />
6961 <Meta property="og:title" content="TryCLI - Interactive CLI Demos & Embeds" />
7062 <Meta property="og:description" content="Instantly spin up isolated Docker containers and share your CLI projects with a single link." />
@@ -74,33 +66,54 @@ pub fn LandingPage() -> impl IntoView {
7466 <Meta name="twitter:title" content="TryCLI - Interactive CLI Demos" />
7567 <Meta name="twitter:description" content="Host, share, and embed fully interactive CLI demos directly in the browser." />
7668
77- // MAIN CONTENT
69+ // MAIN CONTENT
7870 <div class="landing-container" >
7971
8072 <Navbar >
8173 <div class="nav-actions" >
8274 { move || {
83- if auth_checked. get( ) && user. get( ) . is_some( ) {
84- view! {
85- <A href="/dashboard" class="btn-primary btn-lg" >"Launch Dashboard" </A >
86- } . into_view( )
75+ if auth_checked. get( ) {
76+ if let Some ( u) = user. get( ) {
77+ // LOGGED IN: Show Profile + Dashboard Button
78+ view! {
79+ <div style="display: flex; align-items: center; gap: 20px;" >
80+ <div style="display: flex; align-items: center; gap: 12px;" >
81+ <img src=u. avatar_url
82+ style="width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--border);"
83+ alt="User Avatar" />
84+ <span style="color: var(--text-main); font-weight: 500; font-size: 0.95rem;" >
85+ { u. login}
86+ </span>
87+ </div>
88+ <A href="/dashboard" class="btn-primary" >"Dashboard" </A >
89+ </div>
90+ } . into_view( )
91+ } else {
92+ // LOGGED OUT: Single "Login with GitHub" Button
93+ let url = auth_github_url( ) ;
94+ view! {
95+ <a href=url class="btn-primary" rel="external" style="display: flex; align-items: center; gap: 8px;" >
96+ // GitHub Logo SVG
97+ <svg height="20" width="20" viewBox="0 0 16 16" fill="currentColor" >
98+ <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" ></path>
99+ </svg>
100+ "Login with GitHub"
101+ </a>
102+ } . into_view( )
103+ }
87104 } else {
88- let url = auth_github_url( ) ;
89- view! {
90- <a href=url. clone( ) class="btn-nav" rel="external" >"Login" </a>
91- <a href=url class="btn-primary btn-lg" rel="external" >"Launch Dashboard" </a>
92- } . into_view( )
105+ // Loading Spinner
106+ view! { <div class="spinner" style="width: 20px; height: 20px; border-width: 2px;" ></div> } . into_view( )
93107 }
94108 } }
95109 </div>
96110 </Navbar >
97111
98- // Hero Section: Uses semantic <main>[cite: 73].
112+ // Hero Section
99113 <main class="hero-main" >
100114 <div class="hero-content" >
101115 <div class="badge" >"Run Anywhere • Embed Everywhere" </div>
102116
103- // H1 contains primary keywords[cite: 75].
104117 <h1 class="hero-title" >
105118 "Interactive CLI Demos" <br />
106119 <span class="text-gradient" >"for the Modern Web." </span>
@@ -117,15 +130,17 @@ pub fn LandingPage() -> impl IntoView {
117130 if auth_checked. get( ) && user. get( ) . is_some( ) {
118131 view! {
119132 <A href="/dashboard" class="btn-primary btn-hero" >
120- "Start Building "
133+ "Go to Dashboard "
121134 <span class="arrow" >"→" </span>
122135 </A >
123136 } . into_view( )
124137 } else {
125138 view! {
126- <a href=url class="btn-primary btn-hero" rel="external" >
127- "Start Building"
128- <span class="arrow" >"→" </span>
139+ <a href=url class="btn-primary btn-hero" rel="external" style="display: flex; align-items: center; gap: 10px;" >
140+ <svg height="24" width="24" viewBox="0 0 16 16" fill="currentColor" style="color: black;" >
141+ <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" ></path>
142+ </svg>
143+ "Login with GitHub"
129144 </a>
130145 } . into_view( )
131146 }
@@ -135,10 +150,8 @@ pub fn LandingPage() -> impl IntoView {
135150 </A >
136151 </div>
137152
138- // 5. TERMINAL PREVIEW
139- // Added role="log" so search engines treat this as code output.
153+ // TERMINAL PREVIEW
140154 <div class="terminal-preview" role="log" aria-label="Terminal Preview Demo" >
141- // Hidden decorative elements to reduce screen reader noise[cite: 70].
142155 <div class="terminal-header-preview" aria-hidden="true" >
143156 <div class="dot red" ></div>
144157 <div class="dot yellow" ></div>
@@ -159,7 +172,7 @@ pub fn LandingPage() -> impl IntoView {
159172 </div>
160173 </main>
161174
162- // FEATURES
175+ // FEATURES
163176 <section class="section-features" style="background: rgba(255,255,255,0.01);" >
164177 <div class="container-narrow" >
165178 <h2 class="section-title" >"What Is TryCLI?" </h2>
@@ -202,7 +215,7 @@ pub fn LandingPage() -> impl IntoView {
202215 </div>
203216 </section>
204217
205- // USE CASES
218+ // USE CASES
206219 <section class="section-usage" >
207220 <div class="container-narrow" >
208221 <h2 class="section-title" >"Use Cases" </h2>
@@ -224,7 +237,7 @@ pub fn LandingPage() -> impl IntoView {
224237 </div>
225238 </section>
226239
227- // FINAL CTA
240+ // FINAL CTA
228241 <section class="section-usage" style="border-bottom: none;" >
229242 <div class="container-narrow" >
230243 <div class="final-cta" >
@@ -241,15 +254,22 @@ pub fn LandingPage() -> impl IntoView {
241254 if auth_checked. get( ) && user. get( ) . is_some( ) {
242255 view! { <A href="/dashboard" class="btn-primary btn-lg" >"Start Building Now" </A > } . into_view( )
243256 } else {
244- view! { <a href=url class="btn-primary btn-lg" rel="external" >"Start Building Now" </a> } . into_view( )
257+ view! {
258+ <a href=url class="btn-primary btn-lg" rel="external" style="display: flex; align-items: center; gap: 10px;" >
259+ <svg height="24" width="24" viewBox="0 0 16 16" fill="currentColor" style="color: black;" >
260+ <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" ></path>
261+ </svg>
262+ "Login with GitHub"
263+ </a>
264+ } . into_view( )
245265 }
246266 } }
247267 </div>
248268 </div>
249269 </div>
250270 </section>
251271
252- // FOOTER
272+ // FOOTER
253273 <footer class="landing-footer" >
254274 <div class="footer-container" >
255275 <div class="footer-top" >
@@ -258,7 +278,8 @@ pub fn LandingPage() -> impl IntoView {
258278 <span class="brand-name" >"TryCLI" </span>
259279 </div>
260280 <div class="footer-links" >
261- <a href="https://github.com/TryCli-Studio" target="_blank" rel="noopener noreferrer" >"GitHub" </a>
281+ <a href="https://ko-fi.com/V7V21TRPL5" target="_blank" rel="noopener noreferrer" >"Support us" </a>
282+ <a href="/blogs" rel="noopener noreferrer" >"Blogs" </a>
262283 <a href="/docs" rel="noopener noreferrer" >"Documentation" </a>
263284 <a href="https://x.com/TryCliStudio" rel="noopener noreferrer" >"Twitter" </a>
264285 </div>
0 commit comments