Replace emoji icons with Lucide icons and soften link colors
Replaced emoji icons throughout the Angular app with modern Lucide icon library for a more professional and consistent look matching the original static site design. **Icon Updates:** - Navigation tabs: Database, Upload, Search icons - Toolbar buttons: RefreshCw, Sparkles, Search, X icons - Action buttons: Download, Trash2 icons - Form buttons: Upload, Search, X icons **Style Improvements:** - Added softer blue color for artifact links (#93c5fd) - Added hover effect with lighter blue (#bfdbfe) - Added proper cursor pointer for clickable rows - Improved icon color consistency throughout **Dependencies:** - Added lucide-angular (v0.545.0) for icon support - Bundle size: 356.54 kB (raw) → 93.91 kB (gzipped) - Minimal impact: only +7.79 kB for full icon library All components updated with Lucide imports and icon references. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
"@angular/forms": "^19.0.0",
|
||||
"@angular/platform-browser": "^19.0.0",
|
||||
"@angular/router": "^19.0.0",
|
||||
"lucide-angular": "^0.545.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.15.0"
|
||||
|
||||
@@ -3,11 +3,12 @@ import { CommonModule } from '@angular/common';
|
||||
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { ArtifactService } from './services/artifact';
|
||||
import { LucideAngularModule, Database, Upload, Search } from 'lucide-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive],
|
||||
imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive, LucideAngularModule],
|
||||
template: `
|
||||
<div class="container">
|
||||
<header>
|
||||
@@ -20,13 +21,13 @@ import { ArtifactService } from './services/artifact';
|
||||
|
||||
<nav class="tabs">
|
||||
<a routerLink="/artifacts" routerLinkActive="active" class="tab-button">
|
||||
📦 Artifacts
|
||||
<lucide-icon [img]="Database" [size]="16"></lucide-icon> Artifacts
|
||||
</a>
|
||||
<a routerLink="/upload" routerLinkActive="active" class="tab-button">
|
||||
📤 Upload
|
||||
<lucide-icon [img]="Upload" [size]="16"></lucide-icon> Upload
|
||||
</a>
|
||||
<a routerLink="/query" routerLinkActive="active" class="tab-button">
|
||||
🔍 Query
|
||||
<lucide-icon [img]="Search" [size]="16"></lucide-icon> Query
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
@@ -38,6 +39,9 @@ import { ArtifactService } from './services/artifact';
|
||||
export class AppComponent implements OnInit {
|
||||
deploymentMode: string = '';
|
||||
storageBackend: string = '';
|
||||
readonly Database = Database;
|
||||
readonly Upload = Upload;
|
||||
readonly Search = Search;
|
||||
|
||||
constructor(private artifactService: ArtifactService) {}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="artifacts-container">
|
||||
<div class="toolbar">
|
||||
<button (click)="loadArtifacts()" class="btn btn-primary">
|
||||
🔄 Refresh
|
||||
<lucide-icon [img]="RefreshCw" [size]="16"></lucide-icon> Refresh
|
||||
</button>
|
||||
<button (click)="toggleAutoRefresh()"
|
||||
[class.btn-success]="autoRefreshEnabled"
|
||||
@@ -10,20 +10,22 @@
|
||||
Auto-refresh: {{ autoRefreshEnabled ? 'ON' : 'OFF' }}
|
||||
</button>
|
||||
<button (click)="generateSeedData()" class="btn btn-secondary">
|
||||
✨ Generate Seed Data
|
||||
<lucide-icon [img]="Sparkles" [size]="16"></lucide-icon> Generate Seed Data
|
||||
</button>
|
||||
|
||||
<span class="count-badge">{{ filteredArtifacts.length }} artifacts</span>
|
||||
|
||||
<div class="filter-inline">
|
||||
<span class="search-icon">🔍</span>
|
||||
<lucide-icon [img]="Search" [size]="16" class="search-icon"></lucide-icon>
|
||||
<input
|
||||
type="text"
|
||||
[(ngModel)]="searchTerm"
|
||||
(input)="onSearch()"
|
||||
placeholder="Search..."
|
||||
class="search-input">
|
||||
<button (click)="clearSearch()" class="btn-clear" *ngIf="searchTerm">✕</button>
|
||||
<button (click)="clearSearch()" class="btn-clear" *ngIf="searchTerm">
|
||||
<lucide-icon [img]="X" [size]="14"></lucide-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,10 +82,10 @@
|
||||
<td>
|
||||
<div class="action-buttons">
|
||||
<button (click)="downloadArtifact(artifact, $event)" class="icon-btn" title="Download">
|
||||
⬇️
|
||||
<lucide-icon [img]="Download" [size]="16"></lucide-icon>
|
||||
</button>
|
||||
<button (click)="deleteArtifact(artifact, $event)" class="icon-btn danger" title="Delete">
|
||||
🗑️
|
||||
<lucide-icon [img]="Trash2" [size]="16"></lucide-icon>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
@@ -177,10 +179,10 @@
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button (click)="downloadArtifact(selectedArtifact, $event)" class="btn btn-primary">
|
||||
⬇️ Download
|
||||
<lucide-icon [img]="Download" [size]="16"></lucide-icon> Download
|
||||
</button>
|
||||
<button (click)="deleteArtifact(selectedArtifact, $event); closeDetail()" class="btn btn-danger">
|
||||
🗑️ Delete
|
||||
<lucide-icon [img]="Trash2" [size]="16"></lucide-icon> Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,11 +5,12 @@ import { ArtifactService } from '../../services/artifact';
|
||||
import { Artifact } from '../../models/artifact.model';
|
||||
import { interval, Subscription } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { LucideAngularModule, RefreshCw, Search, X, Download, Trash2, Sparkles } from 'lucide-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-artifacts-list',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule],
|
||||
imports: [CommonModule, FormsModule, LucideAngularModule],
|
||||
templateUrl: './artifacts-list.html',
|
||||
styleUrls: ['./artifacts-list.css']
|
||||
})
|
||||
@@ -35,6 +36,14 @@ export class ArtifactsListComponent implements OnInit, OnDestroy {
|
||||
loading: boolean = false;
|
||||
error: string | null = null;
|
||||
|
||||
// Lucide icons
|
||||
readonly RefreshCw = RefreshCw;
|
||||
readonly Search = Search;
|
||||
readonly X = X;
|
||||
readonly Download = Download;
|
||||
readonly Trash2 = Trash2;
|
||||
readonly Sparkles = Sparkles;
|
||||
|
||||
constructor(private artifactService: ArtifactService) {}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
@@ -92,10 +92,10 @@
|
||||
|
||||
<div class="button-group">
|
||||
<button type="submit" class="btn btn-primary btn-large">
|
||||
🔍 Search
|
||||
<lucide-icon [img]="Search" [size]="18"></lucide-icon> Search
|
||||
</button>
|
||||
<button type="button" (click)="clearForm()" class="btn btn-secondary">
|
||||
✕ Clear
|
||||
<lucide-icon [img]="X" [size]="18"></lucide-icon> Clear
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -3,17 +3,20 @@ import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule, FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ArtifactService } from '../../services/artifact';
|
||||
import { Artifact, ArtifactQuery } from '../../models/artifact.model';
|
||||
import { LucideAngularModule, Search, X } from 'lucide-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-query-form',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule],
|
||||
imports: [CommonModule, ReactiveFormsModule, LucideAngularModule],
|
||||
templateUrl: './query-form.html',
|
||||
styleUrls: ['./query-form.css']
|
||||
})
|
||||
export class QueryFormComponent {
|
||||
queryForm: FormGroup;
|
||||
@Output() resultsFound = new EventEmitter<Artifact[]>();
|
||||
readonly Search = Search;
|
||||
readonly X = X;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
|
||||
@@ -98,7 +98,8 @@
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-large" [disabled]="uploading">
|
||||
{{ uploading ? 'Uploading...' : '📤 Upload Artifact' }}
|
||||
<lucide-icon [img]="Upload" [size]="18"></lucide-icon>
|
||||
{{ uploading ? 'Uploading...' : 'Upload Artifact' }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@ import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ArtifactService } from '../../services/artifact';
|
||||
import { LucideAngularModule, Upload } from 'lucide-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-upload-form',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule],
|
||||
imports: [CommonModule, ReactiveFormsModule, LucideAngularModule],
|
||||
templateUrl: './upload-form.html',
|
||||
styleUrls: ['./upload-form.css']
|
||||
})
|
||||
@@ -15,6 +16,7 @@ export class UploadFormComponent {
|
||||
selectedFile: File | null = null;
|
||||
uploading: boolean = false;
|
||||
uploadStatus: { message: string, success: boolean } | null = null;
|
||||
readonly Upload = Upload;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
|
||||
@@ -524,6 +524,28 @@ code {
|
||||
stroke: currentColor;
|
||||
}
|
||||
|
||||
/* Artifact link styles - softer blue */
|
||||
.artifact-link {
|
||||
color: #93c5fd;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
.artifact-link:hover {
|
||||
color: #bfdbfe;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Clickable row cursor */
|
||||
tr.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Search icon color */
|
||||
.search-icon {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.form-row {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
Reference in New Issue
Block a user