style: refine design system aesthetics to flat solid dark-mode theme
This commit is contained in:
+40
-82
@@ -1,6 +1,6 @@
|
||||
# Detailed Project Architecture & Design System Reference Manual
|
||||
|
||||
This document provides a comprehensive technical overview of the **Stick** template, detailing its vertical structure, core dependencies, event delegation contracts, component reuse solutions, and our current implementation plan.
|
||||
This document provides a comprehensive technical overview of the **Stick** template, detailing its vertical structure, core dependencies, event delegation contracts, component reuse solutions, and our completed implementation history.
|
||||
|
||||
---
|
||||
|
||||
@@ -15,116 +15,74 @@ stick/
|
||||
├── package.json # Node assets configuration (optional tooling)
|
||||
├── src/
|
||||
│ ├── main.rs # Core composition, shared state, and route merging
|
||||
│ ├── common/ # Shared utilities & configurations
|
||||
│ │ ├── config.rs # Configuration parsed from environment variables (.env)
|
||||
│ │ ├── database.rs # MongoDB initialization and connections
|
||||
│ │ └── errors.rs # AppError implementation wrapping custom responses
|
||||
│ ├── common/ # Shared features (errors, database, settings)
|
||||
│ ├── auth/ # AUTH USE-CASE (Users, Passwords, Session cookies)
|
||||
│ │ ├── extractors.rs # Native Axum extractors for authentication state
|
||||
│ │ ├── handlers.rs # Login and registration endpoint handlers
|
||||
│ │ ├── models.rs # User database schemas
|
||||
│ │ └── repository.rs # MongoDB operations for authentication
|
||||
│ ├── tasks/ # TASKS USE-CASE (CRUD tasks, dashboard view)
|
||||
│ │ ├── handlers.rs
|
||||
│ │ ├── models.rs
|
||||
│ │ └── repository.rs
|
||||
│ ├── developers/ # DEVELOPERS USE-CASE (HTMX-based assignee autocomplete query)
|
||||
│ │ ├── handlers.rs
|
||||
│ │ ├── models.rs
|
||||
│ │ └── repository.rs
|
||||
│ ├── developers/ # DEVELOPERS USE-CASE (Assignee autocomplete query)
|
||||
│ ├── main_view/ # STATIC VIEWS & GLOBAL ASSET ENDPOINTS
|
||||
│ │ └── mod.rs # Serves index.html, static css, and static javascript files
|
||||
│ ├── components/ # WIKI & INTERACTIVE DESIGN SYSTEM
|
||||
│ │ ├── mod.rs # Wiki routing table
|
||||
│ │ └── handlers.rs # Handlers serving reference pages
|
||||
│ └── input.css # Tailwind CSS v4 custom theme mappings and custom scrollbars
|
||||
├── static/ # Raw assets compiled/included in compilation
|
||||
│ ├── tailwind.css # Output/input css rules
|
||||
│ └── js/
|
||||
│ ├── components.js # Main component event delegation system
|
||||
│ └── combobox.js # HTMX-friendly autocomplete combobox scripts
|
||||
└── templates/ # Raw HTML template layout files (Askama templates)
|
||||
├── base.html # Global HTML layout wrapper (injects headers, navigation)
|
||||
├── auth/ # Login / registration markup
|
||||
├── tasks/ # Task management layouts
|
||||
├── base.html # Global HTML layout wrapper
|
||||
├── auth/ # Login / registration markup (refactored to macros)
|
||||
├── tasks/ # Task management layouts (refactored to macros)
|
||||
├── main_view/ # Landing page layout
|
||||
└── components/ # Component Wiki pages (Buttons, Modals, Comboboxes, etc.)
|
||||
```
|
||||
|
||||
### Route Composition
|
||||
In [src/main.rs](file:///home/enciphered/Desktop/Code/stick/src/main.rs), routers from each vertical module are instantiated and merged using Axum's `.merge()` method:
|
||||
```rust
|
||||
let app = Router::new()
|
||||
.merge(main_view::router())
|
||||
.merge(components::router())
|
||||
.merge(auth::router())
|
||||
.merge(tasks::router())
|
||||
.merge(developers::router())
|
||||
.with_state(state);
|
||||
└── components/ # Component Wiki pages (refactored to macros)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 2. Core Technical Dependencies
|
||||
|
||||
* **Web Server**: `axum = "0.8.9"` — Native asynchronous routing with type-safe extractor traits.
|
||||
* **Database**: `mongodb = "3.7.0"` — Offical Rust driver, using `bson = "3.1.0"` with serde serialization.
|
||||
* **Template Rendering**: `askama = "0.16.0"` — Compile-time type safety; views are compiled directly into the binary.
|
||||
* **Styling Engine**: Tailwind CSS (v4) — Uses native CSS variables and `@import "tailwindcss"` rather than complex configuration JSONs.
|
||||
* **Security & JWT**: `jsonwebtoken = "10.4.0"` (via `rust_crypto` backend) + `bcrypt = "0.19.1"` for password hashing. JWTs are stored in secure `HttpOnly` cookie wrappers.
|
||||
* **Web Server**: `axum = "0.8.9"`
|
||||
* **Database**: `mongodb = "3.7.0"` (using `bson = "3.1.0"`)
|
||||
* **Template Rendering**: `askama = "0.16.0"`
|
||||
* **Styling Engine**: Tailwind CSS (v4)
|
||||
* **Security & JWT**: `jsonwebtoken = "10.4.0"` + `bcrypt = "0.19.1"`
|
||||
|
||||
---
|
||||
|
||||
## 🎨 3. JavaScript & HTML Event Delegation Contract
|
||||
|
||||
Rather than attaching individual event listeners to elements upon page load (which degrades performance and fails when elements are swapped dynamically via HTMX), Stick uses **document-level event delegation** via [static/js/components.js](file:///home/enciphered/Desktop/Code/stick/static/js/components.js) and [static/js/combobox.js](file:///home/enciphered/Desktop/Code/stick/static/js/combobox.js).
|
||||
|
||||
### Active Binding Attributes & Hooks
|
||||
To make components function, developers must preserve specific HTML attributes and class structures that JavaScript expects:
|
||||
Stick uses **document-level event delegation** via `components.js` and `combobox.js`.
|
||||
|
||||
| Component Type | JavaScript Trigger / Hook | Expected Target / Functional Structure |
|
||||
| :--- | :--- | :--- |
|
||||
| **Modal / Dialog** | `[data-modal-target="id"]` | `.modal-dialog` (wrapper), `.modal-backdrop`, `.modal-close` |
|
||||
| **Sheets / Drawers** | `[data-sheet-target="id"]` | `.sheet-dialog` (wrapper), `.sheet-backdrop`, `.sheet-close` |
|
||||
| **Custom Dropdowns** | `.dropdown-trigger` | `.dropdown-menu` (container), `.dropdown-content` |
|
||||
| **Modal / Dialog** | `[data-modal-target="id"]` | `.modal-dialog`, `.modal-backdrop`, `.modal-close` |
|
||||
| **Sheets / Drawers** | `[data-sheet-target="id"]` | `.sheet-dialog`, `.sheet-backdrop`, `.sheet-close` |
|
||||
| **Custom Dropdowns** | `.dropdown-trigger` | `.dropdown-menu`, `.dropdown-content` |
|
||||
| **Interactive Tabs**| `[data-tab-target="pane-id"]` | `[data-tab-group="group-name"]` on buttons & content wrappers |
|
||||
| **Accordions** | `.accordion-trigger` | `.accordion-item` (container), `.accordion-content`, `.accordion-chevron` |
|
||||
| **Custom Select** | `.select-trigger` | `.custom-select` (container), `.select-popover`, `.select-item`, `.select-value` |
|
||||
| **Autocomplete Combobox**| `.combobox-input` | `.autocomplete-combobox` (container), `.combobox-results`, `.combobox-value` |
|
||||
|
||||
*Any customized styling classes (colors, borders, rounded corners) can be freely added or changed. However, the core class naming hierarchy listed above must remain intact to preserve interaction animations and keyboard controls.*
|
||||
| **Accordions** | `.accordion-trigger` | `.accordion-item`, `.accordion-content`, `.accordion-chevron` |
|
||||
| **Custom Select** | `.select-trigger` | `.custom-select`, `.select-popover`, `.select-item`, `.select-value` |
|
||||
| **Autocomplete Combobox**| `.combobox-input` | `.autocomplete-combobox`, `.combobox-results`, `.combobox-value` |
|
||||
|
||||
---
|
||||
|
||||
## 🧩 4. Proposed Scalability & Code Reuse Solutions
|
||||
## 🚀 4. Completed Askama Macros Refactoring (Completed Tasks)
|
||||
We successfully migrated all UI components to type-safe templates on the branch `demo/askama-macros`.
|
||||
|
||||
### Solution 1: Askama Macros (Selected Demo)
|
||||
Consolidate UI components into a global macros registry template.
|
||||
* *Pros*: Safe compilation (missing variables or typos are checked at build time), zero performance cost.
|
||||
* *Cons*: Complex child structures (e.g. slots or dynamic SVG parameters) require passing strings/blocks, which can look verbose.
|
||||
### A. Phase 1: Form Inputs & Basic Controls
|
||||
Consolidated basic form controls into [templates/components/macros.html](file:///home/enciphered/Desktop/Code/stick/templates/components/macros.html):
|
||||
* `button`: Unified visual styles with custom icon inclusion (`label|safe`).
|
||||
* `text_input` & `textarea`: Standardized label, placeholder, name, and value variables.
|
||||
* `select_open`, `select_item`, `select_close`: Structural paired macros bypassing Askama's lack of template slots.
|
||||
* `toggle_switch` & `checkbox`: Standardized custom check styles.
|
||||
* `range_slider` & `datepicker` & `timepicker`: Popover-based pickers integration.
|
||||
|
||||
### Solution 2: CSS Component Classes
|
||||
Define custom components in [src/input.css](file:///home/enciphered/Desktop/Code/stick/src/input.css) using Tailwind CSS v4's components layer (e.g. `@apply btn btn-primary`).
|
||||
* *Pros*: Clear, descriptive markup syntax; easily consumable by pure front-end web developers.
|
||||
* *Cons*: Partially moves styling definitions out of HTML files and back into stylesheet files.
|
||||
### B. Phase 2: Layout & Overlays (Paired Macro Pattern)
|
||||
* `modal_open` & `modal_close`: Paired overlay layout block wrapping.
|
||||
* `sheet_open` & `sheet_close`: Paired slide-out detail drawers.
|
||||
* `tabs_header_open`, `tab_trigger`, `tabs_header_close`, `tabs_content_open`, `tab_pane_open`, `tab_pane_close`, `tabs_content_close`: Flexible dynamic tabs.
|
||||
* `accordion_open` & `accordion_close`: Paired collapsible vertical containers.
|
||||
|
||||
### Solution 3: Rust Struct Components
|
||||
Represent reusable buttons, grids, or select widgets as Rust structs that implement Askama's `Template` trait.
|
||||
* *Pros*: Advanced data-driven structures and type constraints managed entirely in Rust code.
|
||||
* *Cons*: Visual updates require recompiling Rust binaries, which limits swift CSS experimentation.
|
||||
### C. Phase 3: Global Cleanup & Integration
|
||||
* Refactored the Component Wiki demo views to use all new macros (`buttons.html`, `inputs.html`, `toggles.html`, `date_time.html`, `modals.html`, `sheets.html`, `tabs_accordion.html`).
|
||||
* Refactored the authentication views (`login.html` and `register.html`) to use unified `text_input` and `button` macros.
|
||||
* Refactored the rest of the Task Dashboard (`dashboard.html`) to use macro inputs for the task name and task description fields.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 5. Action Plan: Askama Macros Implementation
|
||||
We are implementing a demo showcasing Askama Macros in a new git branch:
|
||||
|
||||
1. **Branch Setup**: Create `demo/askama-macros`.
|
||||
2. **Define Macros**: Create `templates/components/macros.html` to define reusable snippets for:
|
||||
* **Button**: Primary, secondary, outline, destructive, status indicators.
|
||||
* **Modal**: Accessibility markup, background overlays, closing controls.
|
||||
* **Autocomplete Combobox**: Dynamic HTMX data queries and search hooks.
|
||||
3. **Refactor Views**: Replace manual HTML blocks in [dashboard.html](file:///home/enciphered/Desktop/Code/stick/templates/tasks/dashboard.html) with:
|
||||
```html
|
||||
{% import "components/macros.html" as ui %}
|
||||
{{ ui::button("Submit", "primary") }}
|
||||
```
|
||||
## 🧪 5. Testing & Verification Results
|
||||
* **Compile-time Check**: Successfully ran `cargo check` to ensure all macro scopes, imports, and variables are resolved at compilation time.
|
||||
* **Docker Container Status**: Image rebuilt successfully. Running on network port `3009`.
|
||||
|
||||
@@ -67,7 +67,7 @@ impl IntoResponse for AppError {
|
||||
</head>
|
||||
<body class="bg-[#0f172a] text-slate-100 min-h-screen flex items-center justify-center p-4">
|
||||
<div class="max-w-md w-full bg-[#1e293b] border border-slate-800 rounded-2xl p-8 text-center shadow-2xl relative overflow-hidden">
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-red-500 via-rose-500 to-pink-600"></div>
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-rose-500"></div>
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-rose-950/50 border border-rose-900/50 text-rose-500 mb-6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-8 h-8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" />
|
||||
@@ -79,7 +79,7 @@ impl IntoResponse for AppError {
|
||||
<a href="/" class="px-5 py-2.5 rounded-xl bg-slate-800 hover:bg-slate-750 transition font-medium text-sm text-slate-200 border border-slate-700">
|
||||
Go to Safety
|
||||
</a>
|
||||
<a href="/auth/login" class="px-5 py-2.5 rounded-xl bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-90 transition font-medium text-sm text-white">
|
||||
<a href="/auth/login" class="px-5 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 transition font-medium text-sm text-white">
|
||||
Log In
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{% block content %}
|
||||
<div class="grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-md w-full bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden">
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-sky-400 via-blue-500 to-indigo-600"></div>
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-sky-500"></div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Welcome Back</h2>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{% block content %}
|
||||
<div class="grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-md w-full bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden">
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-emerald-400 via-teal-500 to-cyan-600"></div>
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-emerald-500"></div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Create Account</h2>
|
||||
@@ -37,7 +37,7 @@
|
||||
{{ ui::text_input(id="password", name="password", label="Password", type="password", placeholder="••••••••", required=true) }}
|
||||
|
||||
<div>
|
||||
{{ ui::button(label="Sign Up", variant="primary", type="submit", extra_class="w-full py-3.5 bg-gradient-to-r from-emerald-500 to-teal-600 hover:opacity-95 text-white shadow-lg shadow-emerald-500/10 focus:ring-emerald-500") }}
|
||||
{{ ui::button(label="Sign Up", variant="primary", type="submit", extra_class="w-full py-3.5 bg-emerald-600 hover:bg-emerald-700 text-white shadow-lg shadow-emerald-500/10 focus:ring-emerald-500") }}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
+3
-3
@@ -36,12 +36,12 @@
|
||||
<!-- Logo -->
|
||||
<div class="flex items-center space-x-3">
|
||||
<a href="/" class="flex items-center space-x-2.5 group">
|
||||
<div class="w-9 h-9 rounded-xl bg-gradient-to-tr from-sky-400 to-indigo-600 flex items-center justify-center shadow-lg shadow-sky-500/20 group-hover:scale-105 transition-all duration-300">
|
||||
<div class="w-9 h-9 rounded-xl bg-indigo-600 flex items-center justify-center shadow-lg shadow-indigo-600/10 group-hover:scale-105 transition-all duration-300">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-5 h-5 text-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="text-xl font-bold tracking-tight bg-gradient-to-r from-slate-100 to-slate-300 bg-clip-text text-transparent group-hover:from-white group-hover:to-slate-200 transition duration-300">
|
||||
<span class="text-xl font-bold tracking-tight text-slate-100 group-hover:text-white transition duration-300">
|
||||
stick
|
||||
</span>
|
||||
</a>
|
||||
@@ -72,7 +72,7 @@
|
||||
<a href="/auth/login" class="text-sm font-medium text-muted-foreground hover:text-white transition py-2 px-3 rounded-lg hover:bg-secondary">
|
||||
Log In
|
||||
</a>
|
||||
<a href="/auth/register" class="text-sm font-medium text-white bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-90 transition px-4 py-2 rounded-xl shadow-md shadow-sky-500/10">
|
||||
<a href="/auth/register" class="text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-500 transition px-4 py-2 rounded-xl shadow-md shadow-indigo-600/10">
|
||||
Sign Up
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<!-- Architecture & Concept -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="border border-border bg-secondary/10 rounded-2xl p-6 space-y-3">
|
||||
<div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-sky-400/20 to-indigo-500/20 border border-sky-500/30 flex items-center justify-center">
|
||||
<div class="w-10 h-10 rounded-xl bg-sky-500/10 border border-sky-500/20 flex items-center justify-center">
|
||||
<svg class="h-5 w-5 text-sky-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/>
|
||||
</svg>
|
||||
@@ -37,7 +37,7 @@
|
||||
</div>
|
||||
|
||||
<div class="border border-border bg-secondary/10 rounded-2xl p-6 space-y-3">
|
||||
<div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-emerald-400/20 to-teal-500/20 border border-emerald-500/30 flex items-center justify-center">
|
||||
<div class="w-10 h-10 rounded-xl bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center">
|
||||
<svg class="h-5 w-5 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{% block content %}
|
||||
<div class="grow py-12 px-4 sm:px-6 lg:px-8 max-w-lg mx-auto w-full">
|
||||
<div class="bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden">
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-sky-400 via-blue-500 to-indigo-600"></div>
|
||||
<div class="absolute top-0 left-0 w-full h-1 bg-sky-500"></div>
|
||||
|
||||
<div class="text-center mb-8">
|
||||
<h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Edit Developer</h2>
|
||||
@@ -24,7 +24,7 @@
|
||||
<a href="/developers" class="flex-1 py-3 px-4 text-center text-sm font-semibold rounded-xl text-slate-300 bg-slate-900 border border-slate-800 hover:border-slate-700 transition">
|
||||
Cancel
|
||||
</a>
|
||||
{{ ui::button(label="Save Changes", variant="indigo", type="submit", extra_class="flex-1 py-3 bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-95 transition shadow-lg shadow-sky-500/10") }}
|
||||
{{ ui::button(label="Save Changes", variant="indigo", type="submit", extra_class="flex-1 py-3 transition shadow-lg shadow-indigo-500/10") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
{{ ui::text_input(id="skills", name="skills", label="Skills (Comma-separated)", type="text", placeholder="e.g. Rust, Axum, MongoDB") }}
|
||||
|
||||
{{ ui::button(label="Create Developer", variant="indigo", type="submit", extra_class="w-full py-3 bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-95 transition shadow-md shadow-sky-500/10") }}
|
||||
{{ ui::button(label="Create Developer", variant="indigo", type="submit", extra_class="w-full py-3 transition shadow-md shadow-indigo-500/10") }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
</span>
|
||||
|
||||
<!-- Hero Title -->
|
||||
<h1 class="text-4xl sm:text-6xl font-extrabold tracking-tight mb-6 bg-linear-to-r from-slate-100 via-slate-200 to-slate-400 bg-clip-text text-transparent leading-none">
|
||||
<h1 class="text-4xl sm:text-6xl font-extrabold tracking-tight mb-6 text-slate-100 leading-none">
|
||||
Clean, Use-Case Centric <br class="hidden sm:inline">
|
||||
<span class="bg-linear-to-r from-sky-400 via-blue-500 to-indigo-500 bg-clip-text">Rust Web Development</span>
|
||||
<span class="text-indigo-500">Rust Web Development</span>
|
||||
</h1>
|
||||
|
||||
<!-- Subtitle -->
|
||||
@@ -25,11 +25,11 @@
|
||||
<!-- CTA Buttons -->
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
|
||||
{% if authenticated %}
|
||||
<a href="/tasks" class="px-8 py-4 rounded-2xl bg-linear-to-r from-sky-500 via-blue-600 to-indigo-600 hover:opacity-95 transition font-semibold text-white shadow-xl shadow-sky-500/10 hover:shadow-sky-500/20 scale-100 hover:scale-[1.02] transform duration-200">
|
||||
<a href="/tasks" class="px-8 py-4 rounded-2xl bg-indigo-600 hover:bg-indigo-500 transition font-semibold text-white shadow-xl shadow-indigo-600/10 hover:shadow-indigo-600/20 scale-100 hover:scale-[1.02] transform duration-200">
|
||||
Go to Tasks Dashboard
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="/auth/register" class="px-8 py-4 rounded-2xl bg-linear-to-r from-sky-500 via-blue-600 to-indigo-600 hover:opacity-95 transition font-semibold text-white shadow-xl shadow-sky-500/10 hover:shadow-sky-500/20 scale-100 hover:scale-[1.02] transform duration-200">
|
||||
<a href="/auth/register" class="px-8 py-4 rounded-2xl bg-indigo-600 hover:bg-indigo-500 transition font-semibold text-white shadow-xl shadow-indigo-600/10 hover:shadow-indigo-600/20 scale-100 hover:scale-[1.02] transform duration-200">
|
||||
Get Started Free
|
||||
</a>
|
||||
<a href="/auth/login" class="px-8 py-4 rounded-2xl bg-slate-900/60 hover:bg-slate-900 border border-slate-800 hover:border-slate-700 transition font-semibold text-slate-200 scale-100 hover:scale-[1.02] transform duration-200">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
Total Tasks: {{ tasks.len() }}
|
||||
</span>
|
||||
<!-- Info trigger button -->
|
||||
{{ ui::modal_trigger(target_id="task-info-modal", label="<svg class='w-4 h-4' fill='none' stroke='currentColor' viewBox='0 0 24 24'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z'/></svg>", variant="outline", extra_class="px-2.5 py-2.5") }}
|
||||
{{ ui::modal_trigger(target_id="task-info-modal", label="<svg class='w-4 h-4' fill='none' stroke='currentColor' viewBox='0 0 24 24'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z'/></svg>", variant="outline", extra_class="w-9 h-9 !p-0 flex items-center justify-center") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
{{ ui::search_combobox(name="assignee_id", label="Assignee (Optional)", placeholder="Search developer...", search_url="/developers/search", input_id="assignee-search", value_id="assignee-id") }}
|
||||
|
||||
<!-- Create Task submit button using macro -->
|
||||
{{ ui::button(label="Create Task", variant="indigo", type="submit", extra_class="w-full py-3 bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-95 transition shadow-md shadow-sky-500/10") }}
|
||||
{{ ui::button(label="Create Task", variant="indigo", type="submit", extra_class="w-full py-3 transition shadow-md shadow-indigo-500/10") }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user