style(web): refactor dashboard icons to lucide-react for consistency

This commit is contained in:
dyzulk
2026-01-09 22:32:41 +07:00
parent 5958b93f84
commit b883715c26
7 changed files with 64 additions and 61 deletions

View File

@@ -6,7 +6,7 @@ import axios from "@/lib/axios";
import ComponentCard from "../common/ComponentCard";
import Button from "../ui/button/Button";
import Badge from "../ui/badge/Badge";
import { TrashBinIcon, CopyIcon, CheckLineIcon, PlusIcon, LockIcon, BoltIcon } from "@/icons";
import { Trash2, Copy, Check, Plus, Lock, RefreshCw } from "lucide-react";
import { useToast } from "@/context/ToastContext";
import ConfirmationModal from "../common/ConfirmationModal";
import { useTranslations } from "next-intl";
@@ -130,7 +130,7 @@ export default function ApiKeyManagement() {
loading={isCreating}
disabled={!newKeyName.trim()}
>
<PlusIcon className="w-4 h-4 mr-2" />
<Plus className="w-4 h-4 mr-2" />
{t("btn_generate")}
</Button>
</form>
@@ -149,7 +149,7 @@ export default function ApiKeyManagement() {
className="p-3 bg-white dark:bg-gray-800 border border-brand-200 dark:border-brand-500/30 rounded-lg text-brand-500 hover:bg-brand-50 dark:hover:bg-brand-500/10 transition-colors"
title={t("copy_tooltip")}
>
{copied ? <CheckLineIcon className="w-5 h-5" /> : <CopyIcon className="w-5 h-5" />}
{copied ? <Check className="w-5 h-5" /> : <Copy className="w-5 h-5" />}
</button>
</div>
<div className="mt-4 flex justify-end">
@@ -188,7 +188,7 @@ export default function ApiKeyManagement() {
<td className="px-4 py-4">
<div className="flex items-center gap-3">
<div className="w-8 h-8 rounded-full bg-gray-100 dark:bg-gray-800 flex items-center justify-center text-gray-500">
<LockIcon className="w-4 h-4" />
<Lock className="w-4 h-4" />
</div>
<span className="text-sm font-medium text-gray-800 dark:text-white/90">{key.name}</span>
</div>
@@ -218,7 +218,7 @@ export default function ApiKeyManagement() {
className="p-2 text-gray-400 hover:text-brand-500 transition-colors disabled:opacity-50"
title={t("tooltip_regenerate")}
>
<BoltIcon className={`w-5 h-5 ${isRegenerating === key.id ? "animate-spin" : ""}`} />
<RefreshCw className={`w-5 h-5 ${isRegenerating === key.id ? "animate-spin" : ""}`} />
</button>
<button
onClick={() => setConfirmRevokeId(key.id)}
@@ -226,7 +226,7 @@ export default function ApiKeyManagement() {
className="p-2 text-gray-400 hover:text-error-500 transition-colors disabled:opacity-50"
title={t("tooltip_revoke")}
>
<TrashBinIcon className="w-5 h-5" />
<Trash2 className="w-5 h-5" />
</button>
</div>
</td>

View File

@@ -9,7 +9,7 @@ import {
TableRow,
} from "../ui/table";
import Badge from "../ui/badge/Badge";
import { DownloadIcon, TrashBinIcon, EyeIcon } from "@/icons";
import { Download, Trash2, Eye } from "lucide-react";
import Link from "next/link";
import InputField from "../form/input/InputField";
import { useTranslations } from "next-intl";
@@ -237,14 +237,14 @@ export default function CertificateTable({
className="p-2 text-gray-500 hover:text-brand-500 transition-colors"
title={t("tooltip_view")}
>
<EyeIcon className="w-5 h-5" />
<Eye className="w-5 h-5" />
</Link>
<button
onClick={() => onDelete(cert.uuid)}
className="p-2 text-gray-500 hover:text-error-500 transition-colors"
title={t("tooltip_delete")}
>
<TrashBinIcon className="w-5 h-5" />
<Trash2 className="w-5 h-5" />
</button>
</div>
</TableCell>

View File

@@ -3,7 +3,7 @@
import React from "react";
import { Modal } from "../ui/modal";
import Button from "../ui/button/Button";
import { AlertIcon } from "@/icons";
import { AlertTriangle } from "lucide-react";
interface ConfirmationModalProps {
isOpen: boolean;
@@ -76,7 +76,7 @@ const ConfirmationModal: React.FC<ConfirmationModalProps> = ({
<div className="p-6">
<div className="flex flex-col items-center text-center">
<div className={`mb-4 flex h-14 w-14 items-center justify-center rounded-full ${styles.iconBg}`}>
<AlertIcon className={`h-7 w-7 ${styles.iconColor}`} />
<AlertTriangle className={`h-7 w-7 ${styles.iconColor}`} />
</div>
<h3 className="mb-2 text-xl font-bold text-gray-800 dark:text-white/90">

View File

@@ -1,7 +1,7 @@
"use client";
import React from "react";
import Badge from "../ui/badge/Badge";
import { ArrowDownIcon, ArrowUpIcon, BoxIconLine, GroupIcon } from "@/icons";
import { ArrowUp, ArrowDown, Users, Package } from "lucide-react";
export const EcommerceMetrics = () => {
return (
@@ -9,7 +9,7 @@ export const EcommerceMetrics = () => {
{/* <!-- Metric Item Start --> */}
<div className="rounded-2xl border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03] md:p-6">
<div className="flex items-center justify-center w-12 h-12 bg-gray-100 rounded-xl dark:bg-gray-800">
<GroupIcon className="text-gray-800 size-6 dark:text-white/90" />
<Users className="text-gray-800 size-6 dark:text-white/90" />
</div>
<div className="flex items-end justify-between mt-5">
@@ -22,7 +22,7 @@ export const EcommerceMetrics = () => {
</h4>
</div>
<Badge color="success">
<ArrowUpIcon />
<ArrowUp size={14} />
11.01%
</Badge>
</div>
@@ -32,7 +32,7 @@ export const EcommerceMetrics = () => {
{/* <!-- Metric Item Start --> */}
<div className="rounded-2xl border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03] md:p-6">
<div className="flex items-center justify-center w-12 h-12 bg-gray-100 rounded-xl dark:bg-gray-800">
<BoxIconLine className="text-gray-800 dark:text-white/90" />
<Package className="text-gray-800 size-6 dark:text-white/90" />
</div>
<div className="flex items-end justify-between mt-5">
<div>
@@ -45,7 +45,7 @@ export const EcommerceMetrics = () => {
</div>
<Badge color="error">
<ArrowDownIcon className="text-error-500" />
<ArrowDown size={14} className="text-error-500" />
9.05%
</Badge>
</div>

View File

@@ -4,7 +4,7 @@ import ComponentCard from "../../common/ComponentCard";
import Label from "../Label";
import Select from "../Select";
import MultiSelect from "../MultiSelect";
import { ChevronDownIcon } from "@/icons";
import { ChevronDown } from "lucide-react";
export default function SelectInputs() {
const options = [
@@ -40,7 +40,7 @@ export default function SelectInputs() {
className="dark:bg-dark-900"
/>
<span className="absolute text-gray-500 -translate-y-1/2 pointer-events-none right-3 top-1/2 dark:text-gray-400">
<ChevronDownIcon/>
<ChevronDown size={18} />
</span>
</div>
</div>

View File

@@ -3,21 +3,22 @@
import React from "react";
import { useToast, ToastMessage, ToastType } from "@/context/ToastContext";
import {
CheckCircleIcon,
ErrorIcon,
AlertIcon,
InfoIcon,
CloseIcon,
} from "@/icons";
import {
CheckCircle,
AlertCircle,
AlertTriangle,
Info,
X,
} from "lucide-react";
const Toast: React.FC<{ toast: ToastMessage }> = ({ toast }) => {
const { removeToast } = useToast();
const icons = {
success: <CheckCircleIcon className="w-5 h-5 text-green-500" />,
error: <ErrorIcon className="w-5 h-5 text-red-500" />,
warning: <AlertIcon className="w-5 h-5 text-yellow-500" />,
info: <InfoIcon className="w-5 h-5 text-blue-500" />,
success: <CheckCircle className="w-5 h-5 text-green-500" />,
error: <AlertCircle className="w-5 h-5 text-red-500" />,
warning: <AlertTriangle className="w-5 h-5 text-yellow-500" />,
info: <Info className="w-5 h-5 text-blue-500" />,
};
const bgClasses = {
@@ -45,7 +46,7 @@ const Toast: React.FC<{ toast: ToastMessage }> = ({ toast }) => {
aria-label="Close"
>
<span className="sr-only">Close</span>
<CloseIcon className="w-4 h-4" />
<X className="w-4 h-4" />
</button>
</div>
);

View File

@@ -8,21 +8,22 @@ import { useSidebar } from "../context/SidebarContext";
import useSWR from "swr";
import axios from "@/lib/axios";
import {
BoxCubeIcon,
CalenderIcon,
ChevronDownIcon,
GridIcon,
HorizontaLDots,
ListIcon,
PageIcon,
PieChartIcon,
PlugInIcon,
TableIcon,
UserCircleIcon,
LockIcon,
MailIcon,
PaperPlaneIcon,
} from "../icons/index";
LayoutGrid,
Calendar,
Users,
ShieldCheck,
LifeBuoy,
FileText,
Send,
Mail,
Server,
Layers,
UserCircle,
Settings,
KeyRound,
ChevronDown,
Ellipsis,
} from "lucide-react";
type NavItem = {
name: string;
@@ -37,23 +38,23 @@ type MenuGroup = {
};
const iconMap: Record<string, React.ReactNode> = {
dashboard: <GridIcon />,
calendar: <CalenderIcon />,
users: <UserCircleIcon />,
certificate: <BoxCubeIcon />,
"support-ticket": <PlugInIcon />,
pages: <PageIcon />,
email: <PaperPlaneIcon />,
inbox: <MailIcon />,
smtp: <PaperPlaneIcon />,
"server-settings": <BoxCubeIcon />,
layers: <BoxCubeIcon />,
"user-profile": <UserCircleIcon />,
settings: <BoxCubeIcon />,
"api-key": <LockIcon />,
dashboard: <LayoutGrid size={20} />,
calendar: <Calendar size={20} />,
users: <Users size={20} />,
certificate: <ShieldCheck size={20} />,
"support-ticket": <LifeBuoy size={20} />,
pages: <FileText size={20} />,
email: <Send size={20} />,
inbox: <Mail size={20} />,
smtp: <Send size={20} />,
"server-settings": <Server size={20} />,
layers: <Layers size={20} />,
"user-profile": <UserCircle size={20} />,
settings: <Settings size={20} />,
"api-key": <KeyRound size={20} />,
};
const getIcon = (iconName: string) => iconMap[iconName] || <BoxCubeIcon />;
const getIcon = (iconName: string) => iconMap[iconName] || <LayoutGrid size={20} />;
// Static items removed in favor of dynamic API data
@@ -101,7 +102,8 @@ const AppSidebar: React.FC = () => {
</span>
)}
{(isExpanded || isHovered || isMobileOpen) && (
<ChevronDownIcon
<ChevronDown
size={20}
className={`ml-auto w-5 h-5 transition-transform duration-200 ${
openSubmenu?.type === menuType &&
openSubmenu?.index === index
@@ -349,7 +351,7 @@ const AppSidebar: React.FC = () => {
try { return t(key); } catch { return group.title; }
})()
) : (
<HorizontaLDots />
<Ellipsis size={16} />
)}
</h2>
{renderMenuItems(group.items, group.title)}