Skip to content

Commit 6c2868f

Browse files
chore: replace emojis with Lucide icons (#68)
- Replace all emojis with Lucide React icons for better accessibility and consistency - Update page header: rocket emoji → Rocket icon - Update tab navigation: package, hard drive, folder open icons - Update terminal controls: Play, Square, Trash2, X icons - Update filter bar: Package, Monitor, Wrench, Server, FileText, Calendar icons - Update version display: Check icon for up-to-date status - Replace emoji prefixes in terminal and error messages with text labels - Remove unused icon imports
1 parent c270543 commit 6c2868f

File tree

6 files changed

+93
-69
lines changed

6 files changed

+93
-69
lines changed

src/app/_components/FilterBar.tsx

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import React, { useState } from "react";
44
import { Button } from "./ui/button";
5+
import { Package, Monitor, Wrench, Server, FileText, Calendar } from "lucide-react";
56

67
export interface FilterState {
78
searchQuery: string;
@@ -20,10 +21,10 @@ interface FilterBarProps {
2021
}
2122

2223
const SCRIPT_TYPES = [
23-
{ value: "ct", label: "LXC Container", icon: "📦" },
24-
{ value: "vm", label: "Virtual Machine", icon: "💻" },
25-
{ value: "addon", label: "Add-on", icon: "🔧" },
26-
{ value: "pve", label: "PVE Host", icon: "🖥️" },
24+
{ value: "ct", label: "LXC Container", Icon: Package },
25+
{ value: "vm", label: "Virtual Machine", Icon: Monitor },
26+
{ value: "addon", label: "Add-on", Icon: Wrench },
27+
{ value: "pve", label: "PVE Host", Icon: Server },
2728
];
2829

2930
export function FilterBar({
@@ -183,38 +184,41 @@ export function FilterBar({
183184
{isTypeDropdownOpen && (
184185
<div className="absolute top-full left-0 z-10 mt-1 w-48 rounded-lg border border-border bg-card shadow-lg">
185186
<div className="p-2">
186-
{SCRIPT_TYPES.map((type) => (
187-
<label
188-
key={type.value}
189-
className="flex cursor-pointer items-center space-x-3 rounded-md px-3 py-2 hover:bg-accent"
190-
>
191-
<input
192-
type="checkbox"
193-
checked={filters.selectedTypes.includes(type.value)}
194-
onChange={(e) => {
195-
if (e.target.checked) {
196-
updateFilters({
197-
selectedTypes: [
198-
...filters.selectedTypes,
199-
type.value,
200-
],
201-
});
202-
} else {
203-
updateFilters({
204-
selectedTypes: filters.selectedTypes.filter(
205-
(t) => t !== type.value,
206-
),
207-
});
208-
}
209-
}}
210-
className="rounded border-input text-primary focus:ring-primary"
211-
/>
212-
<span className="text-lg">{type.icon}</span>
213-
<span className="text-sm text-muted-foreground">
214-
{type.label}
215-
</span>
216-
</label>
217-
))}
187+
{SCRIPT_TYPES.map((type) => {
188+
const IconComponent = type.Icon;
189+
return (
190+
<label
191+
key={type.value}
192+
className="flex cursor-pointer items-center space-x-3 rounded-md px-3 py-2 hover:bg-accent"
193+
>
194+
<input
195+
type="checkbox"
196+
checked={filters.selectedTypes.includes(type.value)}
197+
onChange={(e) => {
198+
if (e.target.checked) {
199+
updateFilters({
200+
selectedTypes: [
201+
...filters.selectedTypes,
202+
type.value,
203+
],
204+
});
205+
} else {
206+
updateFilters({
207+
selectedTypes: filters.selectedTypes.filter(
208+
(t) => t !== type.value,
209+
),
210+
});
211+
}
212+
}}
213+
className="rounded border-input text-primary focus:ring-primary"
214+
/>
215+
<IconComponent className="h-4 w-4" />
216+
<span className="text-sm text-muted-foreground">
217+
{type.label}
218+
</span>
219+
</label>
220+
);
221+
})}
218222
</div>
219223
<div className="border-t border-border p-2">
220224
<Button
@@ -236,16 +240,25 @@ export function FilterBar({
236240
{/* Sort Options */}
237241
<div className="flex items-center space-x-2">
238242
{/* Sort By Dropdown */}
239-
<select
240-
value={filters.sortBy}
241-
onChange={(e) =>
242-
updateFilters({ sortBy: e.target.value as "name" | "created" })
243-
}
244-
className="rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground focus:ring-2 focus:ring-primary focus:outline-none"
245-
>
246-
<option value="name">📝 By Name</option>
247-
<option value="created">📅 By Created Date</option>
248-
</select>
243+
<div className="relative inline-flex items-center">
244+
<select
245+
value={filters.sortBy}
246+
onChange={(e) =>
247+
updateFilters({ sortBy: e.target.value as "name" | "created" })
248+
}
249+
className="rounded-lg border border-input bg-background pl-9 pr-3 py-2 text-sm text-foreground focus:ring-2 focus:ring-primary focus:outline-none appearance-none"
250+
>
251+
<option value="name">By Name</option>
252+
<option value="created">By Created Date</option>
253+
</select>
254+
<div className="absolute left-2 pointer-events-none">
255+
{filters.sortBy === "name" ? (
256+
<FileText className="h-4 w-4 text-muted-foreground" />
257+
) : (
258+
<Calendar className="h-4 w-4 text-muted-foreground" />
259+
)}
260+
</div>
261+
</div>
249262

250263
{/* Sort Order Button */}
251264
<Button

src/app/_components/ScriptDetailModal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,20 @@ export function ScriptDetailModal({
6363
if (data.success) {
6464
const message =
6565
"message" in data ? data.message : "Script loaded successfully";
66-
setLoadMessage(` ${message}`);
66+
setLoadMessage(`[SUCCESS] ${message}`);
6767
// Refetch script files status and comparison data to update the UI
6868
void refetchScriptFiles();
6969
void refetchComparison();
7070
} else {
7171
const error = "error" in data ? data.error : "Failed to load script";
72-
setLoadMessage(` ${error}`);
72+
setLoadMessage(`[ERROR] ${error}`);
7373
}
7474
// Clear message after 5 seconds
7575
setTimeout(() => setLoadMessage(null), 5000);
7676
},
7777
onError: (error) => {
7878
setIsLoading(false);
79-
setLoadMessage(`❌ Error: ${error.message}`);
79+
setLoadMessage(`[ERROR] ${error.message}`);
8080
setTimeout(() => setLoadMessage(null), 5000);
8181
},
8282
});

src/app/_components/Terminal.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { useEffect, useRef, useState } from 'react';
44
import '@xterm/xterm/css/xterm.css';
55
import { Button } from './ui/button';
6+
import { Play, Square, Trash2, X } from 'lucide-react';
67

78
interface TerminalProps {
89
scriptPath: string;
@@ -215,7 +216,7 @@ export function Terminal({ scriptPath, onClose, mode = 'local', server, isUpdate
215216

216217
switch (message.type) {
217218
case 'start':
218-
xtermRef.current.writeln(`${prefix}🚀 ${message.data}`);
219+
xtermRef.current.writeln(`${prefix}[START] ${message.data}`);
219220
setIsRunning(true);
220221
break;
221222
case 'output':
@@ -232,14 +233,14 @@ export function Terminal({ scriptPath, onClose, mode = 'local', server, isUpdate
232233
xtermRef.current.write(message.data);
233234
} else if (message.data.includes('exit code') && message.data.includes('clear')) {
234235
// This is a script error, show it with error prefix
235-
xtermRef.current.writeln(`${prefix} ${message.data}`);
236+
xtermRef.current.writeln(`${prefix}[ERROR] ${message.data}`);
236237
} else {
237238
// This is a real error, show it with error prefix
238-
xtermRef.current.writeln(`${prefix} ${message.data}`);
239+
xtermRef.current.writeln(`${prefix}[ERROR] ${message.data}`);
239240
}
240241
break;
241242
case 'end':
242-
xtermRef.current.writeln(`${prefix} ${message.data}`);
243+
xtermRef.current.writeln(`${prefix}[SUCCESS] ${message.data}`);
243244
setIsRunning(false);
244245
break;
245246
}
@@ -337,7 +338,8 @@ export function Terminal({ scriptPath, onClose, mode = 'local', server, isUpdate
337338
size="sm"
338339
className={isConnected && !isRunning ? 'bg-green-600 hover:bg-green-700' : 'bg-muted text-muted-foreground cursor-not-allowed'}
339340
>
340-
▶️ Start
341+
<Play className="h-4 w-4 mr-1" />
342+
Start
341343
</Button>
342344

343345
<Button
@@ -347,7 +349,8 @@ export function Terminal({ scriptPath, onClose, mode = 'local', server, isUpdate
347349
size="sm"
348350
className={isRunning ? 'bg-red-600 hover:bg-red-700' : 'bg-muted text-muted-foreground cursor-not-allowed'}
349351
>
350-
⏹️ Stop
352+
<Square className="h-4 w-4 mr-1" />
353+
Stop
351354
</Button>
352355

353356
<Button
@@ -356,7 +359,8 @@ export function Terminal({ scriptPath, onClose, mode = 'local', server, isUpdate
356359
size="sm"
357360
className="bg-secondary text-secondary-foreground hover:bg-secondary/80"
358361
>
359-
🗑️ Clear
362+
<Trash2 className="h-4 w-4 mr-1" />
363+
Clear
360364
</Button>
361365
</div>
362366

@@ -366,7 +370,8 @@ export function Terminal({ scriptPath, onClose, mode = 'local', server, isUpdate
366370
size="sm"
367371
className="bg-gray-600 text-white hover:bg-gray-700"
368372
>
369-
✕ Close
373+
<X className="h-4 w-4 mr-1" />
374+
Close
370375
</Button>
371376
</div>
372377
</div>

src/app/_components/VersionDisplay.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { api } from "~/trpc/react";
44
import { Badge } from "./ui/badge";
55
import { Button } from "./ui/button";
6-
import { ExternalLink, Download, RefreshCw, Loader2 } from "lucide-react";
6+
import { ExternalLink, Download, RefreshCw, Loader2, Check } from "lucide-react";
77
import { useState } from "react";
88

99
// Loading overlay component
@@ -223,8 +223,9 @@ export function VersionDisplay() {
223223
)}
224224

225225
{isUpToDate && (
226-
<span className="text-xs text-green-600 dark:text-green-400">
227-
✓ Up to date
226+
<span className="text-xs text-green-600 dark:text-green-400 flex items-center gap-1">
227+
<Check className="h-3 w-3" />
228+
Up to date
228229
</span>
229230
)}
230231
</div>

src/app/api/trpc/[trpc]/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const handler = (req: NextRequest) =>
1515
env.NODE_ENV === "development"
1616
? ({ path, error }) => {
1717
console.error(
18-
` tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
18+
`[ERROR] tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
1919
);
2020
}
2121
: undefined,

src/app/page.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Terminal } from './_components/Terminal';
1010
import { SettingsButton } from './_components/SettingsButton';
1111
import { VersionDisplay } from './_components/VersionDisplay';
1212
import { Button } from './_components/ui/button';
13+
import { Rocket, Package, HardDrive, FolderOpen } from 'lucide-react';
1314

1415
export default function Home() {
1516
const [runningScript, setRunningScript] = useState<{ path: string; name: string; mode?: 'local' | 'ssh'; server?: any } | null>(null);
@@ -28,8 +29,9 @@ export default function Home() {
2829
<div className="container mx-auto px-4 py-8">
2930
{/* Header */}
3031
<div className="text-center mb-8">
31-
<h1 className="text-4xl font-bold text-foreground mb-2">
32-
🚀 PVE Scripts Management
32+
<h1 className="text-4xl font-bold text-foreground mb-2 flex items-center justify-center gap-3">
33+
<Rocket className="h-9 w-9" />
34+
PVE Scripts Management
3335
</h1>
3436
<p className="text-muted-foreground mb-4">
3537
Manage and execute Proxmox helper scripts locally with live output streaming
@@ -59,34 +61,37 @@ export default function Home() {
5961
variant="ghost"
6062
size="null"
6163
onClick={() => setActiveTab('scripts')}
62-
className={`px-3 py-1 text-sm ${
64+
className={`px-3 py-1 text-sm flex items-center gap-2 ${
6365
activeTab === 'scripts'
6466
? 'bg-accent text-accent-foreground'
6567
: 'hover:bg-accent hover:text-accent-foreground'
6668
}`}>
67-
📦 Available Scripts
69+
<Package className="h-4 w-4" />
70+
Available Scripts
6871
</Button>
6972
<Button
7073
variant="ghost"
7174
size="null"
7275
onClick={() => setActiveTab('downloaded')}
73-
className={`px-3 py-1 text-sm ${
76+
className={`px-3 py-1 text-sm flex items-center gap-2 ${
7477
activeTab === 'downloaded'
7578
? 'bg-accent text-accent-foreground'
7679
: 'hover:bg-accent hover:text-accent-foreground'
7780
}`}>
78-
💾 Downloaded Scripts
81+
<HardDrive className="h-4 w-4" />
82+
Downloaded Scripts
7983
</Button>
8084
<Button
8185
variant="ghost"
8286
size="null"
8387
onClick={() => setActiveTab('installed')}
84-
className={`px-3 py-1 text-sm ${
88+
className={`px-3 py-1 text-sm flex items-center gap-2 ${
8589
activeTab === 'installed'
8690
? 'bg-accent text-accent-foreground'
8791
: 'hover:bg-accent hover:text-accent-foreground'
8892
}`}>
89-
🗂️ Installed Scripts
93+
<FolderOpen className="h-4 w-4" />
94+
Installed Scripts
9095
</Button>
9196
</nav>
9297
</div>

0 commit comments

Comments
 (0)