refactor: migrate from react-hot-toast to react-toastify and replace all emoji icons with Lucide React

- Replaced react-hot-toast with react-toastify (ToastContainer in providers.tsx)
- Removed @heroicons/react dependency
- Added lucide-react for consistent SVG icon system
- Migrated all 18 frontend pages from emoji icons to Lucide components
- Updated sidebar navigation, login/register, dashboard, apps, deploy,
  tickets, admin users/clusters/pools pages
- All emoji indicators (status, runtime, actions) now use proper SVG icons
- Build passes with zero TypeScript errors
This commit is contained in:
keyhan
2026-04-06 17:20:56 +03:30
parent 5d281b85d6
commit 3c3e0e48fa
18 changed files with 248 additions and 229 deletions
@@ -3,8 +3,9 @@
import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import api from '@/lib/api';
import toast from 'react-hot-toast';
import { toast } from 'react-toastify';
import type { Cluster, ClusterResources } from '@/types';
import { Server, CheckCircle, XCircle, BarChart3, Clock, RotateCw, Plug, X } from 'lucide-react';
function ResourcePanel({ clusterId }: { clusterId: string }) {
const { data, isLoading, error } = useQuery<ClusterResources>({
@@ -201,7 +202,7 @@ export default function AdminClustersPage() {
<p className="page-subtitle">{clusters.length} cluster{clusters.length !== 1 ? 's' : ''} registered</p>
</div>
<button onClick={() => setShowForm(!showForm)} className={showForm ? 'btn-ghost' : 'btn-primary'}>
{showForm ? '✕ Cancel' : '+ Add Cluster'}
{showForm ? <><X className="w-4 h-4 inline" /> Cancel</> : '+ Add Cluster'}
</button>
</div>
@@ -263,7 +264,7 @@ export default function AdminClustersPage() {
disabled={!form.name || !form.apiServer || !form.kubeconfig || createMutation.isPending}
className="btn-primary"
>
{createMutation.isPending ? '🔄 Verifying connection & adding...' : 'Add Cluster'}
{createMutation.isPending ? <><RotateCw className="w-4 h-4 inline animate-spin" /> Verifying connection & adding...</> : 'Add Cluster'}
</button>
</div>
)}
@@ -283,7 +284,7 @@ export default function AdminClustersPage() {
</div>
) : clusters.length === 0 ? (
<div className="card text-center py-16">
<div className="text-5xl mb-4">🖥</div>
<Server className="w-12 h-12 mx-auto text-gray-300 mb-4" />
<p className="text-gray-600 font-medium">No clusters registered yet.</p>
<p className="text-gray-400 text-sm mt-1">Add a Kubernetes cluster to start deploying applications.</p>
</div>
@@ -296,7 +297,7 @@ export default function AdminClustersPage() {
<div className={`w-11 h-11 rounded-xl flex items-center justify-center shrink-0 ${
cluster.status === 'active' ? 'bg-emerald-50' : 'bg-red-50'
}`}>
{cluster.status === 'active' ? '✅' : '❌'}
{cluster.status === 'active' ? <CheckCircle className="w-5 h-5 text-emerald-500" /> : <XCircle className="w-5 h-5 text-red-500" />}
</div>
<div className="min-w-0">
<div className="flex items-center gap-2 flex-wrap">
@@ -322,14 +323,14 @@ export default function AdminClustersPage() {
onClick={() => toggleResources(cluster.id)}
className={`btn-ghost text-sm ${expandedResources.has(cluster.id) ? 'bg-purple-50 text-purple-700' : ''}`}
>
📊 Resources
<BarChart3 className="w-4 h-4 inline" /> Resources
</button>
<button
onClick={() => testMutation.mutate(cluster.id)}
disabled={testingId === cluster.id}
className="btn-ghost text-sm disabled:opacity-50"
>
{testingId === cluster.id ? '⏳ Testing...' : '🔌 Test'}
{testingId === cluster.id ? <><Clock className="w-3 h-3 inline animate-spin" /> Testing...</> : <><Plug className="w-3 h-3 inline" /> Test</>}
</button>
<button
onClick={() => { if (confirm('Remove this cluster?')) deleteMutation.mutate(cluster.id); }}