Skip to content

Commit 5a400b7

Browse files
authored
Merge pull request #83 from TryCli-Studio/blogs
Blogs
2 parents 95284a2 + e42aea2 commit 5a400b7

5 files changed

Lines changed: 94 additions & 37 deletions

File tree

client/src/app.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use leptos::*;
22
use leptos_router::*;
33
use crate::components::protected::ProtectedRoute;
4-
use crate::pages::{home::LandingPage, dashboard::DashboardPage, create::CreatePage, view::ViewPage, embed::EmbedPage, docs::DocsPage};
4+
use crate::pages::{home::LandingPage, dashboard::DashboardPage, create::CreatePage, view::ViewPage, embed::EmbedPage, docs::DocsPage, blogs::BlogsPage};
55

66
#[component]
77
pub fn App() -> impl IntoView {
@@ -10,12 +10,14 @@ pub fn App() -> impl IntoView {
1010
<Routes>
1111
<Route path="/" view=LandingPage />
1212
<Route path="/docs" view=DocsPage />
13+
<Route path="/blogs" view=BlogsPage />
1314
<Route path="/dashboard" view=move || view! {
1415
<ProtectedRoute>
1516
<DashboardPage />
1617
</ProtectedRoute>
1718
} />
1819

20+
1921
<Route path="/new" view=move || view! {
2022
<ProtectedRoute>
2123
<CreatePage />

client/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod pages {
1616
pub mod view;
1717
pub mod embed;
1818
pub mod docs;
19+
pub mod blogs;
1920
}
2021

2122
pub use app::App;

client/src/pages/blogs.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use leptos::*;
2+
use leptos_router::A;
3+
use crate::components::navbar::Navbar;
4+
5+
#[component]
6+
pub fn BlogsPage() -> impl IntoView {
7+
view! {
8+
<div style="min-height: 100vh; background: var(--bg-dark); display: flex; flex-direction: column;">
9+
<Navbar>
10+
<div style="display: flex; gap: 1rem; align-items: center;">
11+
<A href="/" class="btn-nav">"Home"</A>
12+
<A href="/dashboard" class="btn-primary">"Dashboard"</A>
13+
</div>
14+
</Navbar>
15+
16+
<main style="flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 2rem; text-align: center;">
17+
<div class="badge">"Under Construction"</div>
18+
19+
<h1 class="hero-title" style="font-size: 3.5rem; margin-bottom: 1.5rem; line-height: 1.1;">
20+
"Engineering" <br />
21+
<span class="text-gradient">"Insights"</span>
22+
</h1>
23+
24+
<p class="hero-subtitle" style="max-width: 500px; margin: 0 auto 2.5rem auto;">
25+
"We are currently writing deep dives on how we built TryCLI using Rust, WebAssembly, and Docker. Stay tuned."
26+
</p>
27+
28+
<div style="display: flex; gap: 1rem; justify-content: center;">
29+
<A href="/" class="btn-secondary">"← Back Home"</A>
30+
</div>
31+
</main>
32+
</div>
33+
}
34+
}

client/src/pages/dashboard.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ pub fn DashboardPage() -> impl IntoView {
6767
}
6868
});
6969

70-
7170
// Search state and debounce logic
7271
let (search_input, set_search_input) = create_signal(String::new());
7372
let (search_results, set_search_results) = create_signal(Vec::<ProjectSummary>::new());

client/src/pages/home.rs

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)