From b2d95bf156ae4339c2eee35471c5441efd231816 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Mon, 3 Nov 2025 19:24:28 -0800 Subject: [PATCH 01/35] Built rough structure using Solid-nextjs template. --- .prettierrc.json | 3 + app/(site)/error/page.tsx | 55 + app/(site)/head.tsx | 10 + app/(site)/layout.tsx | 37 + app/(site)/page.tsx | 24 + app/context/ToastContext.tsx | 12 + app/favicon.ico | Bin 25931 -> 15406 bytes app/globals.css | 233 ++- app/layout.tsx | 34 - app/page.tsx | 65 - bun.lock | 136 +- components/Common/SectionHeader.tsx | 49 + components/Contact/index.tsx | 117 ++ components/Features/SingleFeature.tsx | 41 + components/Features/featuresData.tsx | 34 + components/Features/index.tsx | 39 + components/Footer/index.tsx | 168 ++ components/FunFact/index.tsx | 135 ++ components/Header/ThemeToggler.tsx | 32 + components/Header/index.tsx | 125 ++ components/Header/menuData.tsx | 7 + components/Hero/index.tsx | 73 + components/Lines/index.tsx | 13 + components/ScrollToTop/index.tsx | 44 + package.json | 36 +- postcss.config.js | 5 + postcss.config.mjs | 7 - public/file.svg | 1 - public/globe.svg | 1 - public/images/favicon.ico | Bin 0 -> 15406 bytes public/images/features/features-dark-01.svg | 14 + public/images/hero/Hero.gif | Bin 0 -> 11627107 bytes public/images/hero/hero-dark.svg | 183 ++ public/images/hero/hero-light.svg | 183 ++ public/images/icon/icon-01.svg | 11 + public/images/icon/icon-02.svg | 11 + public/images/icon/icon-03.svg | 11 + public/images/icon/icon-04.svg | 11 + public/images/icon/icon-05.svg | 11 + public/images/icon/icon-moon.svg | 10 + public/images/icon/icon-plus-dark.svg | 10 + public/images/icon/icon-plus-light.svg | 10 + public/images/icon/icon-sun.svg | 10 + public/images/logo/logo-dark.svg | 9 + public/images/logo/logo-light.svg | 9 + public/images/shape/404.svg | 1235 ++++++++++++ public/images/shape/shape-01.png | Bin 0 -> 2842 bytes public/images/shape/shape-02.svg | 3 + public/images/shape/shape-03.svg | 3 + public/images/shape/shape-04.png | Bin 0 -> 159257 bytes public/images/shape/shape-05.png | Bin 0 -> 8713 bytes public/images/shape/shape-06.png | Bin 0 -> 95380 bytes public/images/shape/shape-dotted-dark-02.svg | 1767 +++++++++++++++++ public/images/shape/shape-dotted-dark.svg | 1424 +++++++++++++ public/images/shape/shape-dotted-light-02.svg | 1767 +++++++++++++++++ public/images/shape/shape-dotted-light.svg | 1424 +++++++++++++ public/next.svg | 1 - public/vercel.svg | 1 - public/window.svg | 1 - tsconfig.json | 33 +- types/feature.ts | 6 + types/menu.ts | 7 + 62 files changed, 9463 insertions(+), 238 deletions(-) create mode 100644 .prettierrc.json create mode 100644 app/(site)/error/page.tsx create mode 100644 app/(site)/head.tsx create mode 100644 app/(site)/layout.tsx create mode 100644 app/(site)/page.tsx create mode 100644 app/context/ToastContext.tsx delete mode 100644 app/layout.tsx delete mode 100644 app/page.tsx create mode 100644 components/Common/SectionHeader.tsx create mode 100644 components/Contact/index.tsx create mode 100644 components/Features/SingleFeature.tsx create mode 100644 components/Features/featuresData.tsx create mode 100644 components/Features/index.tsx create mode 100644 components/Footer/index.tsx create mode 100644 components/FunFact/index.tsx create mode 100644 components/Header/ThemeToggler.tsx create mode 100644 components/Header/index.tsx create mode 100644 components/Header/menuData.tsx create mode 100644 components/Hero/index.tsx create mode 100644 components/Lines/index.tsx create mode 100644 components/ScrollToTop/index.tsx create mode 100644 postcss.config.js delete mode 100644 postcss.config.mjs delete mode 100644 public/file.svg delete mode 100644 public/globe.svg create mode 100644 public/images/favicon.ico create mode 100644 public/images/features/features-dark-01.svg create mode 100644 public/images/hero/Hero.gif create mode 100644 public/images/hero/hero-dark.svg create mode 100644 public/images/hero/hero-light.svg create mode 100644 public/images/icon/icon-01.svg create mode 100644 public/images/icon/icon-02.svg create mode 100644 public/images/icon/icon-03.svg create mode 100644 public/images/icon/icon-04.svg create mode 100644 public/images/icon/icon-05.svg create mode 100644 public/images/icon/icon-moon.svg create mode 100644 public/images/icon/icon-plus-dark.svg create mode 100644 public/images/icon/icon-plus-light.svg create mode 100644 public/images/icon/icon-sun.svg create mode 100644 public/images/logo/logo-dark.svg create mode 100644 public/images/logo/logo-light.svg create mode 100644 public/images/shape/404.svg create mode 100644 public/images/shape/shape-01.png create mode 100644 public/images/shape/shape-02.svg create mode 100644 public/images/shape/shape-03.svg create mode 100644 public/images/shape/shape-04.png create mode 100644 public/images/shape/shape-05.png create mode 100644 public/images/shape/shape-06.png create mode 100644 public/images/shape/shape-dotted-dark-02.svg create mode 100644 public/images/shape/shape-dotted-dark.svg create mode 100644 public/images/shape/shape-dotted-light-02.svg create mode 100644 public/images/shape/shape-dotted-light.svg delete mode 100644 public/next.svg delete mode 100644 public/vercel.svg delete mode 100644 public/window.svg create mode 100644 types/feature.ts create mode 100644 types/menu.ts diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..b4bfed3 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/app/(site)/error/page.tsx b/app/(site)/error/page.tsx new file mode 100644 index 0000000..d094638 --- /dev/null +++ b/app/(site)/error/page.tsx @@ -0,0 +1,55 @@ +import { Metadata } from "next"; +import Image from "next/image"; + +export const metadata: Metadata = { + title: "Error Page - Solid SaaS Boilerplate", + + // other metadata + description: "This is Error page for Solid Pro" +}; + +const ErroPage = () => { + return ( +
+
+ 404 + +

+ This Page Does Not Exist +

+

+ The page you were looking for appears to have been moved, deleted or + does not exist. +

+ + + Return to Home + + + + +
+
+ ); +}; + +export default ErroPage; diff --git a/app/(site)/head.tsx b/app/(site)/head.tsx new file mode 100644 index 0000000..049a09f --- /dev/null +++ b/app/(site)/head.tsx @@ -0,0 +1,10 @@ +export default function Head() { + return ( + <> + Solid | Next.js Template for Startup and SaaS + + + + + ); +} diff --git a/app/(site)/layout.tsx b/app/(site)/layout.tsx new file mode 100644 index 0000000..13ecd1d --- /dev/null +++ b/app/(site)/layout.tsx @@ -0,0 +1,37 @@ +"use client"; + +import Footer from "@/components/Footer"; +import Header from "@/components/Header"; +import Lines from "@/components/Lines"; +import ScrollToTop from "@/components/ScrollToTop"; +import { ThemeProvider } from "next-themes"; +import { Inter } from "next/font/google"; +import "../globals.css"; +const inter = Inter({ subsets: ["latin"] }); + +import ToasterContext from "../context/ToastContext"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + +
+ + {children} +
From 4959e5a8074921743c86d8eb1ed50200225b677a Mon Sep 17 00:00:00 2001 From: AOzmond Date: Tue, 4 Nov 2025 06:57:05 -0800 Subject: [PATCH 11/35] Replace `Image` components with `img` tags, remove unused SVGs, and clean up CSS for improved consistency and reduced complexity. --- app/(site)/error/page.tsx | 9 +- app/globals.css | 84 ------------------- components/Download/index.tsx | 46 +++------- components/Features/SingleFeature.tsx | 3 +- components/Header/ThemeToggler.tsx | 9 +- components/Header/index.tsx | 4 +- components/Hero/index.tsx | 21 +---- public/images/logo/logo-light.svg | 9 -- .../images/logo/{logo-dark.svg => logo.svg} | 0 9 files changed, 21 insertions(+), 164 deletions(-) delete mode 100644 public/images/logo/logo-light.svg rename public/images/logo/{logo-dark.svg => logo.svg} (100%) diff --git a/app/(site)/error/page.tsx b/app/(site)/error/page.tsx index 39e9e09..10e3882 100644 --- a/app/(site)/error/page.tsx +++ b/app/(site)/error/page.tsx @@ -1,5 +1,4 @@ import { Metadata } from "next"; -import Image from "next/image"; export const metadata: Metadata = { title: "Error Page - Solid SaaS Boilerplate", @@ -12,13 +11,7 @@ const ErrorPage = () => { return (
- 404 + 404

This Page Does Not Exist diff --git a/app/globals.css b/app/globals.css index 02c28ff..b09026b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -119,96 +119,12 @@ brightness(100%) contrast(105%); } -@layer utilities { - /* third-party libraries CSS */ - - .testimonial-01 .swiper-pagination-bullet { - @apply bg-stroke h-2.5 w-2.5 opacity-100; - } - .testimonial-01 .swiper-pagination-bullet-active { - @apply bg-primary w-5 rounded-full; - } - - .testimonial-01 .swiper-pagination { - @apply relative pt-[50px]; - } - - #supportCheckbox:checked ~ div span { - @apply opacity-100; - } -} - @layer base { body { @apply font-inter text-regular text-waterloo dark:text-manatee relative z-1 font-normal; } } -@layer utilities { - @media (max-width: 1280px) { - .navbar { - @apply max-h-[400px] overflow-y-scroll; - } - } -} - -.blog-details-docs { - @apply shadow-solid-3 dark:border-strokedark dark:bg-blacksection rounded-lg border border-white p-7.5 transition-all xl:p-12.5; -} - -.blog-details p { - @apply text-titlebgdark dark:text-waterloo mb-8 text-base leading-relaxed; -} - -.blog-details p strong { - @apply text-primary dark:text-waterloo; -} -.blog-details h3 strong, -.blog-details h3 { - @apply mb-10 text-xl leading-tight font-semibold! text-black sm:text-2xl sm:leading-tight lg:text-xl lg:leading-tight xl:text-2xl xl:leading-tight dark:text-white; -} - -.blog-details h4 strong, -.blog-details h4 { - @apply text-xl leading-tight font-semibold! text-black sm:text-2xl sm:leading-tight lg:text-xl lg:leading-tight xl:text-2xl xl:leading-tight dark:text-white; -} - -.blog-details h5 strong, -.blog-details h5 { - @apply mb-3 text-lg leading-tight font-semibold! text-black sm:text-xl dark:text-white; -} - -.blog-details h1 { - @apply mb-4 text-3xl leading-tight! font-bold! text-black sm:text-4xl md:text-[45px] lg:text-4xl xl:text-[45px] dark:text-white; -} -.blog-details h2 strong, -.blog-details h2 { - @apply mb-4 text-[26px] leading-tight! font-bold! text-black sm:text-3xl md:text-4xl dark:text-white; -} - -.blog-details ul, -.blog-details ol { - @apply text-titlebgdark mb-10 list-inside list-disc; -} - -.blog-details li, -.blog-details li { - @apply text-titlebgdark dark:text-waterloo mb-2 text-base; -} - -.blog-details blockquote { - @apply bg-manatee dark:bg-titlebgdark relative z-10 mb-10 overflow-hidden rounded-xs p-8 text-center text-base font-medium text-black italic md:py-9 lg:px-10; -} - -.blog-details blockquote::after { - content: ""; - @apply absolute right-0 bottom-0 h-20 w-20 bg-[url(/images/blog/quote-shape-2.svg)] bg-contain bg-right-bottom bg-no-repeat; -} - -.blog-details blockquote::before { - content: ""; - @apply absolute top-0 left-0 h-[106px] w-[140px] bg-[url(/images/blog/quote-shape-1.svg)] bg-contain bg-left-top bg-no-repeat dark:bg-[url(/images/blog/quote-shape-1.svg)]; -} pre { @apply bg-strokedark relative mb-2 rounded-lg px-4 py-2; diff --git a/components/Download/index.tsx b/components/Download/index.tsx index 1f3c5bf..a3677c1 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -3,57 +3,33 @@ import React from "react"; import Image from "next/image"; import { motion } from "framer-motion"; +import SectionHeader from "@/components/Common/SectionHeader"; const FunFact = () => { return ( <> - {/* */} + {/* */}
+
- Doodle - Dotted Dotted - - -

- Download USB Tree for Desktop -

-
-
{ @@ -27,7 +26,7 @@ const SingleFeature = ({ feature }: { feature: Feature }) => { className="animate_top shadow-solid-3 hover:shadow-solid-4 dark:border-strokedark dark:bg-blacksection dark:hover:bg-hoverdark z-40 rounded-lg border border-white bg-white p-7.5 transition-all xl:p-12.5" >
- title + title

{title} diff --git a/components/Header/ThemeToggler.tsx b/components/Header/ThemeToggler.tsx index 8772af8..f2f7750 100644 --- a/components/Header/ThemeToggler.tsx +++ b/components/Header/ThemeToggler.tsx @@ -1,5 +1,4 @@ import { useTheme } from "next-themes"; -import Image from "next/image"; const ThemeToggler = () => { const { theme, setTheme } = useTheme(); @@ -10,19 +9,15 @@ const ThemeToggler = () => { onClick={() => setTheme(theme === "dark" ? "light" : "dark")} className="bg-gray-2 dark:bg-dark-bg absolute right-17 mr-1.5 flex cursor-pointer items-center justify-center rounded-full text-black lg:static dark:text-white" > - logo - logo diff --git a/components/Header/index.tsx b/components/Header/index.tsx index 24fa992..bfcc91b 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -29,10 +29,10 @@ const Header = () => { : "" }`} > -
+
{/* Logo and Title - Left Side */} - logo + logo

USB Tree

diff --git a/components/Hero/index.tsx b/components/Hero/index.tsx index 642ddfe..aedb2d9 100644 --- a/components/Hero/index.tsx +++ b/components/Hero/index.tsx @@ -28,37 +28,24 @@ const Hero = () => {
- shape - shape - shape
Hero - Hero - - - - - - - - diff --git a/public/images/logo/logo-dark.svg b/public/images/logo/logo.svg similarity index 100% rename from public/images/logo/logo-dark.svg rename to public/images/logo/logo.svg From 1a2c740fe8754ab4196787d94b08d3012b18a9fc Mon Sep 17 00:00:00 2001 From: AOzmond Date: Wed, 5 Nov 2025 22:51:12 -0800 Subject: [PATCH 12/35] Refactor components to use named function declarations for consistency and improve readability --- app/(site)/error/page.tsx | 6 ++--- components/Common/SectionHeader.tsx | 10 +++++---- components/Contact/index.tsx | 32 +++++++++++---------------- components/Download/index.tsx | 6 ++--- components/Features/SingleFeature.tsx | 6 ++--- components/Features/index.tsx | 14 ++++++------ components/Footer/index.tsx | 6 ++--- components/Header/ThemeToggler.tsx | 12 +++++----- components/Header/index.tsx | 19 ++++++++-------- components/Hero/index.tsx | 14 ++++++------ components/Lines/index.tsx | 6 ++--- components/ScrollToTop/index.tsx | 20 +++++++++++------ 12 files changed, 72 insertions(+), 79 deletions(-) diff --git a/app/(site)/error/page.tsx b/app/(site)/error/page.tsx index 10e3882..deb6f98 100644 --- a/app/(site)/error/page.tsx +++ b/app/(site)/error/page.tsx @@ -7,7 +7,7 @@ export const metadata: Metadata = { description: "This is Error page for Solid Pro", }; -const ErrorPage = () => { +export default function ErrorPage() { return (
@@ -41,6 +41,4 @@ const ErrorPage = () => {
); -}; - -export default ErrorPage; +} diff --git a/components/Common/SectionHeader.tsx b/components/Common/SectionHeader.tsx index de74eeb..1d5f9cf 100644 --- a/components/Common/SectionHeader.tsx +++ b/components/Common/SectionHeader.tsx @@ -8,7 +8,11 @@ type HeaderInfo = { description: string; }; -const SectionHeader = ({ headerInfo }: { headerInfo: HeaderInfo }) => { +export default function SectionHeader({ + headerInfo, +}: { + headerInfo: HeaderInfo; +}) { const { title, subtitle, description } = headerInfo; return ( @@ -45,6 +49,4 @@ const SectionHeader = ({ headerInfo }: { headerInfo: HeaderInfo }) => { {/* */} ); -}; - -export default SectionHeader; +} diff --git a/components/Contact/index.tsx b/components/Contact/index.tsx index 86afa72..ef219ba 100644 --- a/components/Contact/index.tsx +++ b/components/Contact/index.tsx @@ -3,36 +3,32 @@ import { motion } from "framer-motion"; import Image from "next/image"; import React from "react"; +import SectionHeader from "@/components/Common/SectionHeader"; -const Contact = () => { - /** - * Source: https://www.joshwcomeau.com/react/the-perils-of-rehydration/ - * Reason: To fix rehydration error - */ - const [hasMounted, setHasMounted] = React.useState(false); - React.useEffect(() => { - setHasMounted(true); - }, []); - if (!hasMounted) { - return null; - } - +export default function Contact() { return ( <> {/* */}
+
Dotted Dotted @@ -107,7 +103,7 @@ const Contact = () => {
-
+
Now accepting applications for employers
@@ -115,6 +111,4 @@ const Contact = () => { {/* */} ); -}; - -export default Contact; +} diff --git a/components/Download/index.tsx b/components/Download/index.tsx index a3677c1..91f6894 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -5,7 +5,7 @@ import Image from "next/image"; import { motion } from "framer-motion"; import SectionHeader from "@/components/Common/SectionHeader"; -const FunFact = () => { +export default function FunFact() { return ( <> {/* */} @@ -101,6 +101,4 @@ const FunFact = () => { {/* */} ); -}; - -export default FunFact; +} diff --git a/components/Features/SingleFeature.tsx b/components/Features/SingleFeature.tsx index feaab6d..5bfaa1a 100644 --- a/components/Features/SingleFeature.tsx +++ b/components/Features/SingleFeature.tsx @@ -2,7 +2,7 @@ import React from "react"; import { Feature } from "@/types/feature"; import { motion } from "framer-motion"; -const SingleFeature = ({ feature }: { feature: Feature }) => { +export default function SingleFeature({ feature }: { feature: Feature }) { const { icon, title } = feature; return ( @@ -34,6 +34,4 @@ const SingleFeature = ({ feature }: { feature: Feature }) => { ); -}; - -export default SingleFeature; +} diff --git a/components/Features/index.tsx b/components/Features/index.tsx index 962115c..019b3a4 100644 --- a/components/Features/index.tsx +++ b/components/Features/index.tsx @@ -5,7 +5,11 @@ import featuresData from "./featuresData"; import SingleFeature from "./SingleFeature"; import SectionHeader from "../Common/SectionHeader"; -const Feature = () => { +function renderFeature(feature: any, key: number) { + return ; +} + +export default function Feature() { return ( <> {/* */} @@ -24,9 +28,7 @@ const Feature = () => {
{/* */} - {featuresData.map((feature, key) => ( - - ))} + {featuresData.map(renderFeature)} {/* */}
@@ -35,6 +37,4 @@ const Feature = () => { {/* */} ); -}; - -export default Feature; +} diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 215f885..8b2de78 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -2,7 +2,7 @@ import { motion } from "framer-motion"; -const Footer = () => { +export default function Footer() { return ( <>
@@ -158,6 +158,4 @@ const Footer = () => {
); -}; - -export default Footer; +} diff --git a/components/Header/ThemeToggler.tsx b/components/Header/ThemeToggler.tsx index f2f7750..d98ec8c 100644 --- a/components/Header/ThemeToggler.tsx +++ b/components/Header/ThemeToggler.tsx @@ -1,12 +1,16 @@ import { useTheme } from "next-themes"; -const ThemeToggler = () => { +export default function ThemeToggler() { const { theme, setTheme } = useTheme(); + function handleThemeToggle() { + setTheme(theme === "dark" ? "light" : "dark"); + } + return ( ); -}; - -export default ThemeToggler; +} diff --git a/components/Header/index.tsx b/components/Header/index.tsx index bfcc91b..41a84fc 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -5,21 +5,22 @@ import { useEffect, useState } from "react"; import ThemeToggler from "./ThemeToggler"; -const Header = () => { +export default function Header() { const [stickyMenu, setStickyMenu] = useState(false); // Sticky menu - const handleStickyMenu = () => { + function handleStickyMenu() { if (window.scrollY >= 80) { setStickyMenu(true); } else { setStickyMenu(false); } - }; + } - useEffect(() => { + function addStickyMenuEventListener() { window.addEventListener("scroll", handleStickyMenu); - }); + } + useEffect(addStickyMenuEventListener, []); return (
{
{/* Logo and Title - Left Side */} - logo -

+ logo +

USB Tree

@@ -52,8 +53,6 @@ const Header = () => {
); -}; +} // w-full delay-300 - -export default Header; diff --git a/components/Hero/index.tsx b/components/Hero/index.tsx index aedb2d9..39b1316 100644 --- a/components/Hero/index.tsx +++ b/components/Hero/index.tsx @@ -2,7 +2,7 @@ import Image from "next/image"; -const Hero = () => { +export default function Hero() { return ( <>
@@ -19,9 +19,11 @@ const Hero = () => { USB Tree is a free and open-source utility for when you're trying to see what USB devices are connected to which of your USB ports, when you want to find out what speeds they're running - at, or you're diagnosing any USB device related issues. You'll - quickly be able to identify which devices are connected or - disconnected, and see if there's just too many USB devices + at, or you're diagnosing any USB device related issues. +

+

+ You'll quickly be able to identify which devices are connected + or disconnected, and see if there's just too many USB devices connected to a single USB root hub.

@@ -59,6 +61,4 @@ const Hero = () => {

); -}; - -export default Hero; +} diff --git a/components/Lines/index.tsx b/components/Lines/index.tsx index 335ad25..a1799bf 100644 --- a/components/Lines/index.tsx +++ b/components/Lines/index.tsx @@ -1,6 +1,6 @@ import React from "react"; -const Lines = () => { +export default function Lines() { return (
@@ -8,6 +8,4 @@ const Lines = () => {
); -}; - -export default Lines; +} diff --git a/components/ScrollToTop/index.tsx b/components/ScrollToTop/index.tsx index 0e1e7c1..6e6237b 100644 --- a/components/ScrollToTop/index.tsx +++ b/components/ScrollToTop/index.tsx @@ -5,27 +5,33 @@ export default function ScrollToTop() { // Top: 0 takes us all the way back to the top of the page // Behavior: smooth keeps it smooth! - const scrollToTop = () => { + function scrollToTop() { window.scrollTo({ top: 0, behavior: "smooth", }); - }; + } - useEffect(() => { + function addScrollToTopEventListener() { // Button is displayed after scrolling for 500 pixels - const toggleVisibility = () => { + function toggleVisibility() { if (window.scrollY > 300) { setIsVisible(true); } else { setIsVisible(false); } - }; + } + + function removeScrollToTopEventListener() { + window.removeEventListener("scroll", toggleVisibility); + } window.addEventListener("scroll", toggleVisibility); - return () => window.removeEventListener("scroll", toggleVisibility); - }, []); + return removeScrollToTopEventListener; + } + + useEffect(addScrollToTopEventListener, []); return (
From 326050897ed59034ee03c874115ba6d87c24c567 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Wed, 5 Nov 2025 23:07:15 -0800 Subject: [PATCH 13/35] Update Contact component styling and content --- components/Contact/index.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/components/Contact/index.tsx b/components/Contact/index.tsx index ef219ba..d098bc0 100644 --- a/components/Contact/index.tsx +++ b/components/Contact/index.tsx @@ -59,13 +59,16 @@ export default function Contact() {

I am currently open to new work opportunities.

-

Skills

+

I'm skilled in

Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer Computer{" "}

+
+ Now accepting applications for employers +
-

+

About me

- -
-

+
+

Junior full-stack developer

@@ -103,9 +105,6 @@ export default function Contact() {
-
- Now accepting applications for employers -

{/* */} From 7d43d4b730aae8dff3518ba7706633496008a5c2 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Wed, 5 Nov 2025 23:20:24 -0800 Subject: [PATCH 14/35] styled Download dropdown/button and view on github button --- components/Download/index.tsx | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/components/Download/index.tsx b/components/Download/index.tsx index 91f6894..b9cba00 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -49,15 +49,25 @@ export default function FunFact() { viewport={{ once: true }} className="animate_top text-center" > -
+

Packages for your OS From 6c6efc733acb8e094575abc91c7e53c6adab914f Mon Sep 17 00:00:00 2001 From: AOzmond Date: Wed, 5 Nov 2025 23:54:23 -0800 Subject: [PATCH 15/35] Replace `Link` components with `a` tags in Header for simplicity and update styling; minor content improvements in Hero component. --- components/Header/index.tsx | 21 +++++++++++++-------- components/Hero/index.tsx | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/components/Header/index.tsx b/components/Header/index.tsx index 41a84fc..6925c69 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -1,6 +1,5 @@ "use client"; -import Link from "next/link"; import { useEffect, useState } from "react"; import ThemeToggler from "./ThemeToggler"; @@ -32,23 +31,29 @@ export default function Header() { >
{/* Logo and Title - Left Side */} - + logo

USB Tree

- +
{/* Links - Right Side */}
- - GitHub Repo 🌟 - + github logo +
diff --git a/components/Hero/index.tsx b/components/Hero/index.tsx index 39b1316..14ad94e 100644 --- a/components/Hero/index.tsx +++ b/components/Hero/index.tsx @@ -21,7 +21,7 @@ export default function Hero() { USB ports, when you want to find out what speeds they're running at, or you're diagnosing any USB device related issues.

-

+

You'll quickly be able to identify which devices are connected or disconnected, and see if there's just too many USB devices connected to a single USB root hub. From 2505a911b369cdb83b77f11cf8000b63b9e2f5a0 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Thu, 6 Nov 2025 00:42:26 -0800 Subject: [PATCH 16/35] Replace social media SVGs in Footer with `img` tags, update hrefs to valid links, and simplify markup. --- components/Footer/index.tsx | 104 +++++++++--------------------------- 1 file changed, 24 insertions(+), 80 deletions(-) diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 8b2de78..be5247f 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -59,95 +59,39 @@ export default function Footer() { >

From 940d7e8b73041dfee71a07447c26119c1904515d Mon Sep 17 00:00:00 2001 From: AOzmond Date: Thu, 6 Nov 2025 01:46:54 -0800 Subject: [PATCH 17/35] Remove `animate_top` CSS class from components for cleaner code. Adjust imports in layout and Features for consistency. --- app/(site)/error/page.tsx | 2 +- app/(site)/layout.tsx | 2 +- components/Common/SectionHeader.tsx | 2 +- components/Contact/index.tsx | 4 ++-- components/Download/index.tsx | 3 +-- components/Features/SingleFeature.tsx | 2 +- components/Features/index.tsx | 2 +- components/Footer/index.tsx | 2 -- components/Header/index.tsx | 2 -- 9 files changed, 8 insertions(+), 13 deletions(-) diff --git a/app/(site)/error/page.tsx b/app/(site)/error/page.tsx index deb6f98..f5951af 100644 --- a/app/(site)/error/page.tsx +++ b/app/(site)/error/page.tsx @@ -10,7 +10,7 @@ export const metadata: Metadata = { export default function ErrorPage() { return (
-
+
404

diff --git a/app/(site)/layout.tsx b/app/(site)/layout.tsx index 816c095..7ac12aa 100644 --- a/app/(site)/layout.tsx +++ b/app/(site)/layout.tsx @@ -6,7 +6,7 @@ import Lines from "@/components/Lines"; import ScrollToTop from "@/components/ScrollToTop"; import { ThemeProvider } from "next-themes"; import { Inter } from "next/font/google"; -import "../globals.css"; +import "@/app/globals.css"; const inter = Inter({ subsets: ["latin"] }); diff --git a/components/Common/SectionHeader.tsx b/components/Common/SectionHeader.tsx index 1d5f9cf..e012b34 100644 --- a/components/Common/SectionHeader.tsx +++ b/components/Common/SectionHeader.tsx @@ -34,7 +34,7 @@ export default function SectionHeader({ whileInView="visible" transition={{ duration: 1, delay: 0.1 }} viewport={{ once: true }} - className="animate_top mx-auto text-center" + className="mx-auto text-center" >
diff --git a/components/Contact/index.tsx b/components/Contact/index.tsx index d098bc0..e491193 100644 --- a/components/Contact/index.tsx +++ b/components/Contact/index.tsx @@ -51,7 +51,7 @@ export default function Contact() { whileInView="visible" transition={{ duration: 1, delay: 0.1 }} viewport={{ once: true }} - className="animate_top shadow-solid-8 dark:border-strokedark w-full rounded-lg bg-white p-7.5 md:w-3/5 lg:w-3/4 xl:p-15 dark:border dark:bg-black" + className="shadow-solid-8 dark:border-strokedark w-full rounded-lg bg-white p-7.5 md:w-3/5 lg:w-3/4 xl:p-15 dark:border dark:bg-black" >

I'm Alastair, Software Engineer from scottish flag @@ -87,7 +87,7 @@ export default function Contact() { whileInView="visible" transition={{ duration: 2, delay: 0.1 }} viewport={{ once: true }} - className="animate_top w-full md:w-2/5 md:p-7.5 lg:w-[26%] xl:pt-15" + className="w-full md:w-2/5 md:p-7.5 lg:w-[26%] xl:pt-15" >

About me diff --git a/components/Download/index.tsx b/components/Download/index.tsx index b9cba00..c370691 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -47,7 +47,7 @@ export default function FunFact() { whileInView="visible" transition={{ duration: 1, delay: 0.5 }} viewport={{ once: true }} - className="animate_top text-center" + className="text-center" >

@@ -86,7 +86,6 @@ export default function FunFact() { whileInView="visible" transition={{ duration: 1, delay: 0.7 }} viewport={{ once: true }} - className="animate_top" >

Packages for your OS diff --git a/components/Features/SingleFeature.tsx b/components/Features/SingleFeature.tsx index 5bfaa1a..14b90b2 100644 --- a/components/Features/SingleFeature.tsx +++ b/components/Features/SingleFeature.tsx @@ -23,7 +23,7 @@ export default function SingleFeature({ feature }: { feature: Feature }) { whileInView="visible" transition={{ duration: 0.5 }} viewport={{ once: true }} - className="animate_top shadow-solid-3 hover:shadow-solid-4 dark:border-strokedark dark:bg-blacksection dark:hover:bg-hoverdark z-40 rounded-lg border border-white bg-white p-7.5 transition-all xl:p-12.5" + className="shadow-solid-3 hover:shadow-solid-4 dark:border-strokedark dark:bg-blacksection dark:hover:bg-hoverdark z-40 rounded-lg border border-white bg-white p-7.5 transition-all xl:p-12.5" >
title diff --git a/components/Features/index.tsx b/components/Features/index.tsx index 019b3a4..72a4233 100644 --- a/components/Features/index.tsx +++ b/components/Features/index.tsx @@ -3,7 +3,7 @@ import React from "react"; import featuresData from "./featuresData"; import SingleFeature from "./SingleFeature"; -import SectionHeader from "../Common/SectionHeader"; +import SectionHeader from "@/components/Common/SectionHeader"; function renderFeature(feature: any, key: number) { return ; diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index be5247f..965a149 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -34,7 +34,6 @@ export default function Footer() { whileInView="visible" transition={{ duration: 1, delay: 0.1 }} viewport={{ once: true }} - className="animate_top" >

© {new Date().getFullYear()} Alastair Ozmond

@@ -55,7 +54,6 @@ export default function Footer() { whileInView="visible" transition={{ duration: 1, delay: 0.1 }} viewport={{ once: true }} - className="animate_top" >
- +

- I'm Alastair, Software Engineer from scottish flag - Glasgow,Scotland, Currently living in usa flag Oregon, USA. + I'm Alastair, Software Engineer from Glasgow,Scotland, Currently + living in Oregon, USA.

I am currently open to new work opportunities.

I'm skilled in

-

- Computer Computer Computer Computer Computer Computer Computer - Computer Computer Computer Computer Computer Computer Computer - Computer Computer Computer Computer Computer Computer - Computer{" "} -

-
- visible: { - opacity: 1, - y: 0, - }, - }} - initial="hidden" - whileInView="visible" - transition={{ duration: 2, delay: 0.1 }} - viewport={{ once: true }} - className="w-full md:w-2/5 md:p-7.5 lg:w-[26%] xl:pt-15" - > +

About me

@@ -96,14 +66,58 @@ export default function Contact() {

Junior full-stack developer

-
- - - - + +
- +

diff --git a/components/Contact/skill.tsx b/components/Contact/skill.tsx new file mode 100644 index 0000000..ac0f225 --- /dev/null +++ b/components/Contact/skill.tsx @@ -0,0 +1,16 @@ +import React from "react"; + +interface SkillBoxProps { + word: string; + color?: string; +} + +export const SkillBox: React.FC = ({ word }) => { + return ( + + {word} + + ); +}; + +export default SkillBox; diff --git a/components/Contact/skills.yaml b/components/Contact/skills.yaml new file mode 100644 index 0000000..961e3e2 --- /dev/null +++ b/components/Contact/skills.yaml @@ -0,0 +1,18 @@ +skills: + - word: "React" + + - word: "TypeScript" + + - word: "JavaScript" + + - word: "Next.js" + + - word: "Tailwind CSS" + + - word: "Node.js" + + - word: "Python" + + - word: "potato" + + - word: "Git" \ No newline at end of file diff --git a/components/Contact/skillsData.tsx b/components/Contact/skillsData.tsx new file mode 100644 index 0000000..574bc90 --- /dev/null +++ b/components/Contact/skillsData.tsx @@ -0,0 +1,17 @@ +import { readFileSync } from "fs"; +import { join } from "path"; +import yaml from "js-yaml"; + +export type Skill = { + word: string; + color?: string; +}; + +const fileContents = readFileSync( + join(process.cwd(), "components", "Contact", "skills.yaml"), + "utf8", +); + +const data = yaml.load(fileContents) as { skills: Skill[] }; + +export const skillsData: Skill[] = data.skills; diff --git a/components/Download/index.tsx b/components/Download/index.tsx index c370691..5e05d40 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -63,6 +63,8 @@ export default function FunFact() { diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 965a149..60e8448 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -10,8 +10,20 @@ export default function Footer() { {/* */} {/* */} @@ -57,7 +69,11 @@ export default function Footer() { >

From 8171178857076c99c0039d207c975b3b7403f174 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Fri, 7 Nov 2025 07:29:49 -0800 Subject: [PATCH 28/35] Add OS detection to `Download` component; simplify `ThemeProvider` props in layout --- app/(site)/layout.tsx | 6 +----- components/Download/index.tsx | 10 ++++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/(site)/layout.tsx b/app/(site)/layout.tsx index 295d1cc..c729a1e 100644 --- a/app/(site)/layout.tsx +++ b/app/(site)/layout.tsx @@ -19,11 +19,7 @@ export default function RootLayout({ // suppressHydrationWarning is for dark mode support (next-themes). - +
{children} diff --git a/components/Download/index.tsx b/components/Download/index.tsx index 94a304a..3bbb908 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -4,10 +4,20 @@ import React, { useState } from "react"; import Image from "next/image"; import { motion } from "framer-motion"; import SectionHeader from "@/components/Common/SectionHeader"; +import { useEffect } from "react"; export default function FunFact() { const [selectedOS, setSelectedOS] = useState(""); + useEffect(() => { + const userAgent = navigator.userAgent; + if (userAgent.includes("Win")) { + setSelectedOS("windows"); + } else if (userAgent.includes("Linux")) { + setSelectedOS("linux"); + } + }, []); + const downloadUrls: Record = { windows: "https://github.com/AOzmond/usb-tree/releases/latest/download/usb-tree-windows-amd64.zip", From 342cf454f927b82b00fcce1bb0a0971260b397eb Mon Sep 17 00:00:00 2001 From: AOzmond Date: Fri, 7 Nov 2025 07:47:19 -0800 Subject: [PATCH 29/35] Refactor `SectionHeader` to remove unused `subtitle` and `description` properties; improve accessibility for social media icons and enhance `ThemeToggler` with resolved theme detection. --- components/Common/SectionHeader.tsx | 10 ++-------- components/Contact/index.tsx | 10 ++++------ components/Download/index.tsx | 2 -- components/Features/index.tsx | 2 -- components/Header/ThemeToggler.tsx | 24 ++++++++++++++++++++++-- components/Header/index.tsx | 1 - 6 files changed, 28 insertions(+), 21 deletions(-) diff --git a/components/Common/SectionHeader.tsx b/components/Common/SectionHeader.tsx index e012b34..e7a334d 100644 --- a/components/Common/SectionHeader.tsx +++ b/components/Common/SectionHeader.tsx @@ -4,8 +4,6 @@ import { motion } from "framer-motion"; type HeaderInfo = { title: string; - subtitle: string; - description: string; }; export default function SectionHeader({ @@ -13,7 +11,7 @@ export default function SectionHeader({ }: { headerInfo: HeaderInfo; }) { - const { title, subtitle, description } = headerInfo; + const { title } = headerInfo; return ( <> @@ -36,15 +34,11 @@ export default function SectionHeader({ viewport={{ once: true }} className="mx-auto text-center" > -
+
{title}
-

- {subtitle} -

-

{description}

{/* */} diff --git a/components/Contact/index.tsx b/components/Contact/index.tsx index f8973b4..a271172 100644 --- a/components/Contact/index.tsx +++ b/components/Contact/index.tsx @@ -12,8 +12,6 @@ export default function Contact() {
@@ -78,7 +76,7 @@ export default function Contact() { > GitHub @@ -101,7 +99,7 @@ export default function Contact() { > Bluesky @@ -113,7 +111,7 @@ export default function Contact() { > Dev.to diff --git a/components/Download/index.tsx b/components/Download/index.tsx index 3bbb908..e7e7145 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -32,8 +32,6 @@ export default function FunFact() {
diff --git a/components/Features/index.tsx b/components/Features/index.tsx index 72a4233..0c1a541 100644 --- a/components/Features/index.tsx +++ b/components/Features/index.tsx @@ -19,8 +19,6 @@ export default function Feature() { {/* */} diff --git a/components/Header/ThemeToggler.tsx b/components/Header/ThemeToggler.tsx index d98ec8c..778c29a 100644 --- a/components/Header/ThemeToggler.tsx +++ b/components/Header/ThemeToggler.tsx @@ -1,10 +1,30 @@ import { useTheme } from "next-themes"; +import { useEffect, useState } from "react"; export default function ThemeToggler() { - const { theme, setTheme } = useTheme(); + const { theme, setTheme, resolvedTheme } = useTheme(); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); function handleThemeToggle() { - setTheme(theme === "dark" ? "light" : "dark"); + // Use resolvedTheme to get the actual current theme (including system preference) + const currentTheme = resolvedTheme || theme; + setTheme(currentTheme === "dark" ? "light" : "dark"); + } + + // Avoid hydration mismatch by not rendering until mounted + if (!mounted) { + return ( + + ); } return ( diff --git a/components/Header/index.tsx b/components/Header/index.tsx index 08162cf..5c87cc0 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -47,7 +47,6 @@ export default function Header() { rel="noopener" target="_blank" href="https://github.com/AOzmond/usb-tree" - className="" > Date: Fri, 7 Nov 2025 08:08:40 -0800 Subject: [PATCH 30/35] Enhance accessibility across components with improved `alt` attributes, header structure adjustments, and `aria-label` addition; update feature data with descriptive `alt` text. --- components/Download/index.tsx | 11 +++++++---- components/Features/SingleFeature.tsx | 4 ++-- components/Features/featuresData.tsx | 4 ++++ components/Footer/index.tsx | 4 +++- components/Header/ThemeToggler.tsx | 4 ++-- components/Header/index.tsx | 6 +++++- components/Hero/index.tsx | 16 ++++++++-------- types/feature.ts | 1 + 8 files changed, 32 insertions(+), 18 deletions(-) diff --git a/components/Download/index.tsx b/components/Download/index.tsx index e7e7145..e28f756 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -67,15 +67,18 @@ export default function FunFact() { className="text-center" >
-

+

Direct Download -

+ diff --git a/components/Features/SingleFeature.tsx b/components/Features/SingleFeature.tsx index 14b90b2..5dc26f8 100644 --- a/components/Features/SingleFeature.tsx +++ b/components/Features/SingleFeature.tsx @@ -3,7 +3,7 @@ import { Feature } from "@/types/feature"; import { motion } from "framer-motion"; export default function SingleFeature({ feature }: { feature: Feature }) { - const { icon, title } = feature; + const { icon, title, alt } = feature; return ( <> @@ -26,7 +26,7 @@ export default function SingleFeature({ feature }: { feature: Feature }) { className="shadow-solid-3 hover:shadow-solid-4 dark:border-strokedark dark:bg-blacksection dark:hover:bg-hoverdark z-40 rounded-lg border border-white bg-white p-7.5 transition-all xl:p-12.5" >
- title + {alt}

{title} diff --git a/components/Features/featuresData.tsx b/components/Features/featuresData.tsx index c4fcc43..e8802a9 100644 --- a/components/Features/featuresData.tsx +++ b/components/Features/featuresData.tsx @@ -4,18 +4,22 @@ const featuresData: Feature[] = [ { icon: "/images/features/multi-os.png", title: "Cross-platform support for Windows and Linux", + alt: "A screenshot showing the application interface on Windows and Linux.", }, { icon: "/images/features/device-tree.png", title: "Tree of USB devices", + alt: "Hierarchical tree diagram showing connected USB devices. Their hierarchy is shown with indentation.", }, { icon: "/images/features/logging.png", title: "Monitor for changes", + alt: "USB device connection events are shown in the log, and device tree.", }, { icon: "/images/features/lightmode.png", title: "Dark and Light Mode", + alt: "Split screen showing the application interface in both dark and light theme modes.", }, ]; diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 01e915b..9211e5a 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -49,7 +49,9 @@ export default function Footer() { transition={{ duration: 1, delay: 0.1 }} viewport={{ once: true }} > -

© {new Date().getFullYear()} Alastair Ozmond

+

+ © {new Date().getFullYear()} Alastair Ozmond +

logo logo diff --git a/components/Header/index.tsx b/components/Header/index.tsx index 5c87cc0..5c069a2 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -33,7 +33,11 @@ export default function Header() {
{/* Logo and Title - Left Side */} - logo + USB Tree logo

USB Tree

diff --git a/components/Hero/index.tsx b/components/Hero/index.tsx index b3e2a2d..b2ff625 100644 --- a/components/Hero/index.tsx +++ b/components/Hero/index.tsx @@ -9,12 +9,12 @@ export default function Hero() {
-

+

👀 Cross-platform USB device viewer, monitor, and logger -

-

+

+

The USB buddy you've always wanted -

+

USB Tree is a free and open-source utility for when you're trying to see what USB devices are connected to which of your @@ -32,24 +32,24 @@ export default function Hero() {

shape shape shape
Hero diff --git a/types/feature.ts b/types/feature.ts index 1ec7053..da46bfb 100644 --- a/types/feature.ts +++ b/types/feature.ts @@ -1,4 +1,5 @@ export type Feature = { icon: string; title: string; + alt: string; }; From 7bd348e55c97404140a6badc077feeab7c672f43 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Fri, 7 Nov 2025 08:21:18 -0800 Subject: [PATCH 31/35] Refactor `Header` component to use flex-row layout --- components/Header/index.tsx | 2 +- eslint.config.mjs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/Header/index.tsx b/components/Header/index.tsx index 5c069a2..5532752 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -30,7 +30,7 @@ export default function Header() { : "" }`} > -
+
{/* Logo and Title - Left Side */} Date: Fri, 7 Nov 2025 08:24:23 -0800 Subject: [PATCH 32/35] Update metadata for Error Page to reflect USB Tree branding --- app/(site)/error/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/(site)/error/page.tsx b/app/(site)/error/page.tsx index 9a4ce93..6ddabb3 100644 --- a/app/(site)/error/page.tsx +++ b/app/(site)/error/page.tsx @@ -2,10 +2,10 @@ import { Metadata } from "next"; import Link from "next/link"; export const metadata: Metadata = { - title: "Error Page - Solid SaaS Boilerplate", + title: "Error Page - USB Tree", // other metadata - description: "This is Error page for Solid Pro", + description: "This is Error page for USB Tree", }; export default function ErrorPage() { From 6894dbaeba7a678e6aeb52f7b24dde9846b34a15 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Fri, 7 Nov 2025 08:25:22 -0800 Subject: [PATCH 33/35] Remove unused SVG icon from Error Page link button --- app/(site)/error/page.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/(site)/error/page.tsx b/app/(site)/error/page.tsx index 6ddabb3..20ea783 100644 --- a/app/(site)/error/page.tsx +++ b/app/(site)/error/page.tsx @@ -27,17 +27,6 @@ export default function ErrorPage() { className="hover:bg-blackho dark:bg-btndark dark:hover:bg-blackho inline-flex items-center gap-2.5 rounded-full bg-black px-6 py-3 font-medium text-white duration-300 ease-in-out" > Return to Home - - -
From 684fb9df597f2e023f203ee44d53f3445c2bb92e Mon Sep 17 00:00:00 2001 From: AOzmond Date: Fri, 7 Nov 2025 08:30:05 -0800 Subject: [PATCH 34/35] Update metadata to include detailed description for USB Tree --- app/(site)/head.tsx | 5 ++++- app/(site)/page.tsx | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/(site)/head.tsx b/app/(site)/head.tsx index 919e69a..d3ba0b2 100644 --- a/app/(site)/head.tsx +++ b/app/(site)/head.tsx @@ -3,7 +3,10 @@ export default function Head() { <> USB Tree - The USB device tree viewer and monitor. - + ); diff --git a/app/(site)/page.tsx b/app/(site)/page.tsx index 35383ee..09520ea 100644 --- a/app/(site)/page.tsx +++ b/app/(site)/page.tsx @@ -8,7 +8,8 @@ export const metadata: Metadata = { title: "USB Tree - The USB device tree viewer and monitor.", // other metadata - description: "This is the homepage for USB Tree", + description: + "USB Tree - A free, open-source desktop app for Windows and Linux. View connected USB devices in a tree structure and monitor real-time connection changes.", }; export default function Home() { From c01eaa1e10080265a96d59c035ff7a80ce3341a0 Mon Sep 17 00:00:00 2001 From: AOzmond Date: Fri, 7 Nov 2025 08:42:08 -0800 Subject: [PATCH 35/35] Remove unused icons, deprecated `Menu` type, and related assets; rename `FunFact` component to `Download`; update package metadata. --- components/Download/index.tsx | 4 ++-- package.json | 4 ++-- public/images/icon/icon-01.svg | 11 ----------- public/images/icon/icon-02.svg | 11 ----------- public/images/icon/icon-03.svg | 11 ----------- public/images/icon/icon-04.svg | 11 ----------- public/images/shape/shape-05.png | Bin 8713 -> 0 bytes types/menu.ts | 7 ------- 8 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 public/images/icon/icon-01.svg delete mode 100644 public/images/icon/icon-02.svg delete mode 100644 public/images/icon/icon-03.svg delete mode 100644 public/images/icon/icon-04.svg delete mode 100644 public/images/shape/shape-05.png delete mode 100644 types/menu.ts diff --git a/components/Download/index.tsx b/components/Download/index.tsx index e28f756..9777ec4 100644 --- a/components/Download/index.tsx +++ b/components/Download/index.tsx @@ -6,7 +6,7 @@ import { motion } from "framer-motion"; import SectionHeader from "@/components/Common/SectionHeader"; import { useEffect } from "react"; -export default function FunFact() { +export default function Download() { const [selectedOS, setSelectedOS] = useState(""); useEffect(() => { @@ -147,7 +147,7 @@ export default function FunFact() {
- {/* */} + {/* */} ); } diff --git a/package.json b/package.json index 36bc031..f3f2fb6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "solid-nextjs", - "version": "1.3.1", + "name": "usb-tree.github.io", + "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", diff --git a/public/images/icon/icon-01.svg b/public/images/icon/icon-01.svg deleted file mode 100644 index 164ab77..0000000 --- a/public/images/icon/icon-01.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/public/images/icon/icon-02.svg b/public/images/icon/icon-02.svg deleted file mode 100644 index 52a1f3d..0000000 --- a/public/images/icon/icon-02.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/public/images/icon/icon-03.svg b/public/images/icon/icon-03.svg deleted file mode 100644 index 14e06c7..0000000 --- a/public/images/icon/icon-03.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/public/images/icon/icon-04.svg b/public/images/icon/icon-04.svg deleted file mode 100644 index c831db7..0000000 --- a/public/images/icon/icon-04.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/public/images/shape/shape-05.png b/public/images/shape/shape-05.png deleted file mode 100644 index fc1286a70e73396d08032c98c0eabfd2cfa6eded..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8713 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 m