From a341fe2629fc013e63d3e28aeb5fa61225679ae2 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 14 Oct 2026 23:48:22 +0100 Subject: [PATCH] Switch icons to Hugeicons --- web/package-lock.json | 31 ++++++----- web/package.json | 3 +- web/src/components/icons.ts | 30 +++++++++++ web/src/components/toast/toast-provider.tsx | 4 +- web/src/components/ui/checkbox.tsx | 5 +- web/src/components/ui/input.tsx | 5 +- web/src/routes/__root.tsx | 9 ++-- web/src/routes/admin/route.tsx | 30 ++++------- web/src/routes/client/route.tsx | 57 ++++++++------------- web/src/routes/index.tsx | 8 ++- web/vite.config.ts | 1 - 11 files changed, 93 insertions(+), 90 deletions(-) create mode 100644 web/src/components/icons.ts diff --git a/web/package-lock.json b/web/package-lock.json index 1bf0cf5..2e04766 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "@fontsource-variable/inter": "^5.3.0", - "@phosphor-icons/react": "^2.1.10", + "@hugeicons/core-free-icons": "^4.3.5", + "@hugeicons/react": "^1.1.10", "@tanstack/react-query": "^5.104.0", "@tanstack/react-router": "^1.170.40", "clsx": "^2.1.1", @@ -438,6 +439,21 @@ "url": "https://github.com/sponsors/ayuhito" } }, + "node_modules/@hugeicons/core-free-icons": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@hugeicons/core-free-icons/-/core-free-icons-4.3.5.tgz", + "integrity": "sha512-Sv+NjHRPnQk+yZsGCMcGznCHdTfJR9PMMOEKcJYAQU4gy90dmlc9PwdtvYOImBZIjiheMsTLL5eMn2DmHxUiUg==", + "license": "MIT" + }, + "node_modules/@hugeicons/react": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@hugeicons/react/-/react-1.1.10.tgz", + "integrity": "sha512-9tAsd92yMVVGP+E+d8cM+wc0VnXuYZHNbWQi7TOe8k2neawmhiaFmVFbzyruejhOMa197/LbgvSED32ayUo3ZA==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.0.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", @@ -588,19 +604,6 @@ "url": "https://github.com/sponsors/oxc-project" } }, - "node_modules/@phosphor-icons/react": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/@phosphor-icons/react/-/react-2.1.10.tgz", - "integrity": "sha512-vt8Tvq8GLjheAZZYa+YG/pW7HDbov8El/MANW8pOAz4eGxrwhnbfrQZq0Cp4q8zBEu8NIhHdnr+r8thnfRSNYA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">= 16.8", - "react-dom": ">= 16.8" - } - }, "node_modules/@rolldown/binding-android-arm-eabi": { "version": "1.2.12", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", diff --git a/web/package.json b/web/package.json index bbe2d36..a1a5994 100644 --- a/web/package.json +++ b/web/package.json @@ -13,7 +13,8 @@ }, "dependencies": { "@fontsource-variable/inter": "^5.3.0", - "@phosphor-icons/react": "^2.1.10", + "@hugeicons/core-free-icons": "^4.3.5", + "@hugeicons/react": "^1.1.10", "@tanstack/react-query": "^5.104.0", "@tanstack/react-router": "^1.170.40", "clsx": "^2.1.1", diff --git a/web/src/components/icons.ts b/web/src/components/icons.ts new file mode 100644 index 0000000..3aa728d --- /dev/null +++ b/web/src/components/icons.ts @@ -0,0 +1,30 @@ +export { HugeiconsIcon } from "@hugeicons/react"; +export { default as Activity01Icon } from "@hugeicons/core-free-icons/Activity01Icon"; +export { default as Add01Icon } from "@hugeicons/core-free-icons/Add01Icon"; +export { default as ArrowDataTransferHorizontalIcon } from "@hugeicons/core-free-icons/ArrowDataTransferHorizontalIcon"; +export { default as ArrowRight02Icon } from "@hugeicons/core-free-icons/ArrowRight02Icon"; +export { default as BookOpen01Icon } from "@hugeicons/core-free-icons/BookOpen01Icon"; +export { default as Cancel01Icon } from "@hugeicons/core-free-icons/Cancel01Icon"; +export { default as CreditCardIcon } from "@hugeicons/core-free-icons/CreditCardIcon"; +export { default as CustomerSupportIcon } from "@hugeicons/core-free-icons/CustomerSupportIcon"; +export { default as DashboardSquare01Icon } from "@hugeicons/core-free-icons/DashboardSquare01Icon"; +export { default as FileEditIcon } from "@hugeicons/core-free-icons/FileEditIcon"; +export { default as HandshakeIcon } from "@hugeicons/core-free-icons/HandshakeIcon"; +export { default as Invoice01Icon } from "@hugeicons/core-free-icons/Invoice01Icon"; +export { default as Logout03Icon } from "@hugeicons/core-free-icons/Logout03Icon"; +export { default as Megaphone01Icon } from "@hugeicons/core-free-icons/Megaphone01Icon"; +export { default as Menu01Icon } from "@hugeicons/core-free-icons/Menu01Icon"; +export { default as PackageIcon } from "@hugeicons/core-free-icons/PackageIcon"; +export { default as ReturnRequestIcon } from "@hugeicons/core-free-icons/ReturnRequestIcon"; +export { default as SecurityCheckIcon } from "@hugeicons/core-free-icons/SecurityCheckIcon"; +export { default as ServerStack01Icon } from "@hugeicons/core-free-icons/ServerStack01Icon"; +export { default as Settings01Icon } from "@hugeicons/core-free-icons/Settings01Icon"; +export { default as ShieldUserIcon } from "@hugeicons/core-free-icons/ShieldUserIcon"; +export { default as ShoppingCart01Icon } from "@hugeicons/core-free-icons/ShoppingCart01Icon"; +export { default as Tick02Icon } from "@hugeicons/core-free-icons/Tick02Icon"; +export { default as UserCircleIcon } from "@hugeicons/core-free-icons/UserCircleIcon"; +export { default as UserGroupIcon } from "@hugeicons/core-free-icons/UserGroupIcon"; +export { default as UserIcon } from "@hugeicons/core-free-icons/UserIcon"; +export { default as ViewIcon } from "@hugeicons/core-free-icons/ViewIcon"; +export { default as ViewOffSlashIcon } from "@hugeicons/core-free-icons/ViewOffSlashIcon"; +export { default as Wallet01Icon } from "@hugeicons/core-free-icons/Wallet01Icon"; diff --git a/web/src/components/toast/toast-provider.tsx b/web/src/components/toast/toast-provider.tsx index f62ca94..8f6c4ef 100644 --- a/web/src/components/toast/toast-provider.tsx +++ b/web/src/components/toast/toast-provider.tsx @@ -1,6 +1,6 @@ import { useCallback, useMemo, useRef, useState, type ReactNode } from "react"; -import { X } from "@phosphor-icons/react/X"; +import { HugeiconsIcon, Cancel01Icon } from "@/components/icons"; import { ToastContext, type ToastInput, type ToastStatus } from "@/components/toast/use-toast"; import { cn } from "@/lib/utils"; @@ -56,7 +56,7 @@ export function ToastProvider({ children }: { children: ReactNode }) { onClick={() => dismissToast(toast.id)} className="text-muted-foreground hover:text-foreground" > - + ))} diff --git a/web/src/components/ui/checkbox.tsx b/web/src/components/ui/checkbox.tsx index b86ac01..e622b23 100644 --- a/web/src/components/ui/checkbox.tsx +++ b/web/src/components/ui/checkbox.tsx @@ -1,5 +1,6 @@ import type { ReactNode } from "react"; -import { Check } from "@phosphor-icons/react/Check"; + +import { HugeiconsIcon, Tick02Icon } from "@/components/icons"; type CheckboxProps = { label: ReactNode; @@ -19,7 +20,7 @@ export function Checkbox({ label, checked, error, onCheckedChange }: CheckboxPro onChange={(e) => onCheckedChange(e.target.checked)} className="peer size-4 cursor-pointer appearance-none border border-input bg-input/30 transition-colors outline-none checked:border-primary checked:bg-primary focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-0" /> - + {label} diff --git a/web/src/components/ui/input.tsx b/web/src/components/ui/input.tsx index 6628580..9c6e7ed 100644 --- a/web/src/components/ui/input.tsx +++ b/web/src/components/ui/input.tsx @@ -1,7 +1,6 @@ import { useId, useState, type InputHTMLAttributes } from "react"; -import { Eye } from "@phosphor-icons/react/Eye"; -import { EyeSlash } from "@phosphor-icons/react/EyeSlash"; +import { HugeiconsIcon, ViewIcon, ViewOffSlashIcon } from "@/components/icons"; import { cn } from "@/lib/utils"; interface InputProps extends InputHTMLAttributes { @@ -36,7 +35,7 @@ export function Input({ error, className, id: idProp, type, ...props }: InputPro onClick={() => setRevealed((prev) => !prev)} className="absolute top-1/2 right-1 flex size-8 -translate-y-1/2 items-center justify-center text-muted-foreground hover:text-foreground" > - {revealed ? : } + {revealed ? : } )} diff --git a/web/src/routes/__root.tsx b/web/src/routes/__root.tsx index 1afa6f6..017517e 100644 --- a/web/src/routes/__root.tsx +++ b/web/src/routes/__root.tsx @@ -1,5 +1,4 @@ import type { QueryClient } from "@tanstack/react-query"; -import { IconContext } from "@phosphor-icons/react/dist/lib/context"; import { Outlet, createRootRouteWithContext } from "@tanstack/react-router"; import { ToastProvider } from "@/components/toast/toast-provider"; @@ -11,10 +10,8 @@ export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()( function RootLayout() { return ( - - - - - + + + ); } diff --git a/web/src/routes/admin/route.tsx b/web/src/routes/admin/route.tsx index c56f0ff..091bfc7 100644 --- a/web/src/routes/admin/route.tsx +++ b/web/src/routes/admin/route.tsx @@ -1,16 +1,8 @@ import { Link, Outlet, createFileRoute, redirect } from "@tanstack/react-router"; -import { ArrowUUpLeft } from "@phosphor-icons/react/ArrowUUpLeft"; -import { GearSix } from "@phosphor-icons/react/GearSix"; -import { HardDrives } from "@phosphor-icons/react/HardDrives"; -import { Package } from "@phosphor-icons/react/Package"; -import { Receipt } from "@phosphor-icons/react/Receipt"; -import { SignOut } from "@phosphor-icons/react/SignOut"; -import { SquaresFour } from "@phosphor-icons/react/SquaresFour"; -import { User } from "@phosphor-icons/react/User"; -import { UsersThree } from "@phosphor-icons/react/UsersThree"; import { meQuery } from "@/api/auth/me"; import { Permission } from "@/api/auth/permissions"; +import { HugeiconsIcon, DashboardSquare01Icon, Invoice01Icon, Logout03Icon, PackageIcon, ReturnRequestIcon, ServerStack01Icon, Settings01Icon, UserGroupIcon, UserIcon } from "@/components/icons"; export const Route = createFileRoute("/admin")({ beforeLoad: async ({ context, location }) => { @@ -28,15 +20,15 @@ export const Route = createFileRoute("/admin")({ const NAV_GROUPS = [ [ - { label: "Overview", to: "/admin", icon: SquaresFour }, - { label: "Clients", to: "/admin/clients", icon: UsersThree, permission: Permission.ClientsView }, - { label: "Products", to: "/admin/products", icon: Package, permission: Permission.ProductsManage }, - { label: "Services", to: "/admin/services", icon: HardDrives, permission: Permission.ServicesManage }, - { label: "Invoices", to: "/admin/invoices", icon: Receipt, permission: Permission.InvoicesManage }, - { label: "Refunds", to: "/admin/refunds", icon: ArrowUUpLeft, permission: Permission.PaymentsRefund }, - { label: "Settings", to: "/admin/settings", icon: GearSix, permission: Permission.SettingsManage }, + { label: "Overview", to: "/admin", icon: DashboardSquare01Icon }, + { label: "Clients", to: "/admin/clients", icon: UserGroupIcon, permission: Permission.ClientsView }, + { label: "Products", to: "/admin/products", icon: PackageIcon, permission: Permission.ProductsManage }, + { label: "Services", to: "/admin/services", icon: ServerStack01Icon, permission: Permission.ServicesManage }, + { label: "Invoices", to: "/admin/invoices", icon: Invoice01Icon, permission: Permission.InvoicesManage }, + { label: "Refunds", to: "/admin/refunds", icon: ReturnRequestIcon, permission: Permission.PaymentsRefund }, + { label: "Settings", to: "/admin/settings", icon: Settings01Icon, permission: Permission.SettingsManage }, ], - [{ label: "Client area", to: "/client", icon: User }], + [{ label: "Client area", to: "/client", icon: UserIcon }], ] as const; function AdminLayout() { @@ -68,7 +60,7 @@ function AdminLayout() { title="Sign out" className="grid size-8 place-items-center text-muted-foreground transition-colors hover:text-foreground" > - + @@ -88,7 +80,7 @@ function AdminLayout() { aria-label={item.label} className="group relative grid size-8 place-items-center border border-transparent text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[status=active]:border-border data-[status=active]:bg-muted data-[status=active]:text-foreground" > - +