|
@@ -0,0 +1,190 @@
|
|
|
|
|
+using Astralis;
|
|
|
|
|
+using Invercargill;
|
|
|
|
|
+using Invercargill.DataStructures;
|
|
|
|
|
+using Inversion;
|
|
|
|
|
+using Spry;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * HomePage - The main landing page
|
|
|
|
|
+ *
|
|
|
|
|
+ * Eye-catching hero section with gradient text,
|
|
|
|
|
+ * feature highlights, and call-to-action buttons
|
|
|
|
|
+ */
|
|
|
|
|
+public class HomePage : PageComponent {
|
|
|
|
|
+
|
|
|
|
|
+ public const string ROUTE = "/";
|
|
|
|
|
+
|
|
|
|
|
+ private ComponentFactory factory = inject<ComponentFactory>();
|
|
|
|
|
+
|
|
|
|
|
+ public override string markup { get {
|
|
|
|
|
+ return """
|
|
|
|
|
+ <div sid="home">
|
|
|
|
|
+ <!-- Hero Section -->
|
|
|
|
|
+ <section class="hero">
|
|
|
|
|
+ <div class="container">
|
|
|
|
|
+ <span class="hero-badge">
|
|
|
|
|
+ ⚡ Free & Open Source
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <h1>Build Modern Web Apps in Vala</h1>
|
|
|
|
|
+ <p class="hero-subtitle">
|
|
|
|
|
+ Spry is a component-based web framework featuring HTMX integration,
|
|
|
|
|
+ reactive templates, and dependency injection. Fast, type-safe, and elegant.
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <div class="hero-actions">
|
|
|
|
|
+ <a href="/demo" class="btn btn-primary">
|
|
|
|
|
+ ✨ Try Live Demo
|
|
|
|
|
+ </a>
|
|
|
|
|
+ <a href="/features" class="btn btn-secondary">
|
|
|
|
|
+ Explore Features
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Quick Stats -->
|
|
|
|
|
+ <section class="section">
|
|
|
|
|
+ <div class="container">
|
|
|
|
|
+ <div class="stats-grid">
|
|
|
|
|
+ <div class="stat-card">
|
|
|
|
|
+ <div class="stat-value">100%</div>
|
|
|
|
|
+ <div class="stat-label">Type-Safe Vala</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-card">
|
|
|
|
|
+ <div class="stat-value">0</div>
|
|
|
|
|
+ <div class="stat-label">JavaScript Required</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-card">
|
|
|
|
|
+ <div class="stat-value">∞</div>
|
|
|
|
|
+ <div class="stat-label">Possibilities</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-card">
|
|
|
|
|
+ <div class="stat-value">FREE</div>
|
|
|
|
|
+ <div class="stat-label">Forever</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Feature Highlights -->
|
|
|
|
|
+ <section class="section">
|
|
|
|
|
+ <div class="container">
|
|
|
|
|
+ <div class="section-header">
|
|
|
|
|
+ <h2>Why Choose Spry?</h2>
|
|
|
|
|
+ <p>Build powerful web applications with a framework designed for developer happiness</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="features-grid">
|
|
|
|
|
+ <spry-outlet sid="features"/>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Code Example -->
|
|
|
|
|
+ <section class="section">
|
|
|
|
|
+ <div class="container">
|
|
|
|
|
+ <div class="section-header">
|
|
|
|
|
+ <h2>Clean, Intuitive Code</h2>
|
|
|
|
|
+ <p>Write components that are easy to understand and maintain</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="code-block">
|
|
|
|
|
+ <div class="code-header">
|
|
|
|
|
+ <div class="code-dots">
|
|
|
|
|
+ <div class="code-dot red"></div>
|
|
|
|
|
+ <div class="code-dot yellow"></div>
|
|
|
|
|
+ <div class="code-dot green"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span class="code-lang">Vala</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <pre><code>class CounterComponent : Component {
|
|
|
|
|
+ private int count = 0;
|
|
|
|
|
+
|
|
|
|
|
+ public override string markup {
|
|
|
|
|
+ owned get {
|
|
|
|
|
+ // Use spry-action for interactivity
|
|
|
|
|
+ return @"Counter: $(count)
|
|
|
|
|
+ [Button: spry-action=':Increment' +]
|
|
|
|
|
+ [Button: spry-action=':Decrement' -]";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public async override void handle_action(string action) {
|
|
|
|
|
+ if (action == "Increment") count++;
|
|
|
|
|
+ else if (action == "Decrement") count--;
|
|
|
|
|
+ }
|
|
|
|
|
+}</code></pre>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- CTA Section -->
|
|
|
|
|
+ <section class="section">
|
|
|
|
|
+ <div class="container">
|
|
|
|
|
+ <div class="freedom-section">
|
|
|
|
|
+ <div class="freedom-icon">🕊</div>
|
|
|
|
|
+ <h2>Free as in Freedom</h2>
|
|
|
|
|
+ <p>
|
|
|
|
|
+ Spry is Free/Libre Open Source Software. Use it, study it, modify it,
|
|
|
|
|
+ and share it freely. Built by the community, for the community.
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <div class="hero-actions">
|
|
|
|
|
+ <a href="/freedom" class="btn btn-accent">
|
|
|
|
|
+ Learn About Freedom
|
|
|
|
|
+ </a>
|
|
|
|
|
+ <a href="/ecosystem" class="btn btn-secondary">
|
|
|
|
|
+ Explore Ecosystem
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ """;
|
|
|
|
|
+ }}
|
|
|
|
|
+
|
|
|
|
|
+ public override async void prepare() throws Error {
|
|
|
|
|
+ var features = new Series<Renderable>();
|
|
|
|
|
+
|
|
|
|
|
+ var feature1 = factory.create<FeatureCardComponent>();
|
|
|
|
|
+ feature1.icon = "purple";
|
|
|
|
|
+ feature1.icon_emoji = "⚡";
|
|
|
|
|
+ feature1.title = "HTMX Integration";
|
|
|
|
|
+ feature1.description = "Build dynamic UIs without writing JavaScript. HTMX handles the complexity, you handle the logic.";
|
|
|
|
|
+ features.add(feature1);
|
|
|
|
|
+
|
|
|
|
|
+ var feature2 = factory.create<FeatureCardComponent>();
|
|
|
|
|
+ feature2.icon = "blue";
|
|
|
|
|
+ feature2.icon_emoji = "🔧";
|
|
|
|
|
+ feature2.title = "Dependency Injection";
|
|
|
|
|
+ feature2.description = "Clean architecture with Inversion of Control. Inject services, stores, and components effortlessly.";
|
|
|
|
|
+ features.add(feature2);
|
|
|
|
|
+
|
|
|
|
|
+ var feature3 = factory.create<FeatureCardComponent>();
|
|
|
|
|
+ feature3.icon = "green";
|
|
|
|
|
+ feature3.icon_emoji = "🎨";
|
|
|
|
|
+ feature3.title = "Reactive Templates";
|
|
|
|
|
+ feature3.description = "Declarative templates with outlets and automatic updates. Your UI stays in sync with your data.";
|
|
|
|
|
+ features.add(feature3);
|
|
|
|
|
+
|
|
|
|
|
+ var feature4 = factory.create<FeatureCardComponent>();
|
|
|
|
|
+ feature4.icon = "purple";
|
|
|
|
|
+ feature4.icon_emoji = "🔒";
|
|
|
|
|
+ feature4.title = "Type-Safe";
|
|
|
|
|
+ feature4.description = "Full Vala type safety means fewer runtime errors. The compiler catches bugs before you do.";
|
|
|
|
|
+ features.add(feature4);
|
|
|
|
|
+
|
|
|
|
|
+ var feature5 = factory.create<FeatureCardComponent>();
|
|
|
|
|
+ feature5.icon = "blue";
|
|
|
|
|
+ feature5.icon_emoji = "🚀";
|
|
|
|
|
+ feature5.title = "High Performance";
|
|
|
|
|
+ feature5.description = "Built on Astralis for maximum throughput. Native code performance with web framework convenience.";
|
|
|
|
|
+ features.add(feature5);
|
|
|
|
|
+
|
|
|
|
|
+ var feature6 = factory.create<FeatureCardComponent>();
|
|
|
|
|
+ feature6.icon = "green";
|
|
|
|
|
+ feature6.icon_emoji = "📦";
|
|
|
|
|
+ feature6.title = "Modular Design";
|
|
|
|
|
+ feature6.description = "Use what you need, extend what you want. Clean separation of concerns at every level.";
|
|
|
|
|
+ features.add(feature6);
|
|
|
|
|
+
|
|
|
|
|
+ set_outlet_children("features", features);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|