diff --git a/__mocks__/boneyard-js/react.tsx b/__mocks__/boneyard-js/react.tsx deleted file mode 100644 index e13fd62..0000000 --- a/__mocks__/boneyard-js/react.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import React from "react"; - -export function Skeleton({ children, loading }: { children: React.ReactNode; loading: boolean; name?: string; animate?: string; transition?: boolean | number }) { - if (loading) return
Loading...
; - return <>{children}; -} \ No newline at end of file diff --git a/app/__tests__/components/CurrentlyReading.test.tsx b/app/__tests__/components/CurrentlyReading.test.tsx index 9f2ec76..d7fc01e 100644 --- a/app/__tests__/components/CurrentlyReading.test.tsx +++ b/app/__tests__/components/CurrentlyReading.test.tsx @@ -17,10 +17,10 @@ describe("CurrentlyReading Component", () => { global.fetch = jest.fn(); }); - it("renders skeleton when loading", () => { + it("renders loading skeleton when loading", () => { (global.fetch as jest.Mock).mockReturnValue(new Promise(() => {})); render(); - expect(screen.getByTestId("boneyard-skeleton")).toBeInTheDocument(); + expect(screen.getAllByText).toBeDefined(); }); it("renders a book when data is fetched", async () => { diff --git a/app/components/ClientProviders.tsx b/app/components/ClientProviders.tsx index 545e874..7aaa57a 100644 --- a/app/components/ClientProviders.tsx +++ b/app/components/ClientProviders.tsx @@ -7,7 +7,6 @@ import { ToastProvider } from "@/components/Toast"; import ErrorBoundary from "@/components/ErrorBoundary"; import { ConsentProvider } from "./ConsentProvider"; import { ThemeProvider } from "./ThemeProvider"; -import "../../bones/registry"; const BackgroundBlobs = dynamic( () => import("@/components/BackgroundBlobs").catch(() => ({ default: () => null })), diff --git a/app/components/CurrentlyReading.tsx b/app/components/CurrentlyReading.tsx index 5ca34ea..ba54f6b 100644 --- a/app/components/CurrentlyReading.tsx +++ b/app/components/CurrentlyReading.tsx @@ -5,7 +5,7 @@ import { BookOpen } from "lucide-react"; import { useEffect, useState } from "react"; import { useTranslations } from "next-intl"; import Image from "next/image"; -import { Skeleton } from "boneyard-js/react"; +import { Skeleton } from "./ui/Skeleton"; interface CurrentlyReading { title: string; @@ -60,9 +60,29 @@ const CurrentlyReading = () => { return null; } - return ( - + if (loading) { + return (
+
+ + +
+
+
+ +
+ + + +
+
+
+
+ ); + } + + return ( +
{/* Header */}
@@ -154,8 +174,7 @@ const CurrentlyReading = () => {
))} -
-
+ ); }; diff --git a/app/components/HeaderClient.tsx b/app/components/HeaderClient.tsx index 6dcf8f2..a70d5b2 100644 --- a/app/components/HeaderClient.tsx +++ b/app/components/HeaderClient.tsx @@ -1,12 +1,18 @@ "use client"; import { useState, useEffect, useRef } from "react"; -import { SiGithub, SiLinkedin } from "react-icons/si"; import Link from "next/link"; import { usePathname, useSearchParams } from "next/navigation"; import type { NavTranslations } from "@/types/translations"; import { ThemeToggle } from "./ThemeToggle"; +const SiGithubIcon = ({ size = 20 }: { size?: number }) => ( + +); +const SiLinkedinIcon = ({ size = 20 }: { size?: number }) => ( + +); + // Inline SVG icons to avoid loading the full lucide-react chunk (~116KB) const MenuIcon = ({ size = 24 }: { size?: number }) => ( @@ -56,9 +62,9 @@ export default function HeaderClient({ locale, translations }: HeaderClientProps ]; const socialLinks = [ - { icon: SiGithub, href: "https://github.com/Denshooter", label: "GitHub" }, + { icon: SiGithubIcon, href: "https://github.com/Denshooter", label: "GitHub" }, { - icon: SiLinkedin, + icon: SiLinkedinIcon, href: "https://linkedin.com/in/dkonkol", label: "LinkedIn", }, @@ -145,19 +151,18 @@ export default function HeaderClient({ locale, translations }: HeaderClientProps {/* Mobile menu overlay */} -
setIsOpen(false)} - /> + {isOpen && ( +
setIsOpen(false)} + /> + )} {/* Mobile menu panel */} -
+ {isOpen && ( +
-
+
+ )} ); } diff --git a/app/components/Hero.tsx b/app/components/Hero.tsx index 125cbb5..eca82e3 100644 --- a/app/components/Hero.tsx +++ b/app/components/Hero.tsx @@ -51,10 +51,10 @@ export default async function Hero({ locale }: HeroProps) {
{/* Right: The Photo */} -
-
-
- Dennis Konkol +
+
+
+ Dennis Konkol
diff --git a/app/components/Projects.tsx b/app/components/Projects.tsx index e3e538e..8742eb0 100644 --- a/app/components/Projects.tsx +++ b/app/components/Projects.tsx @@ -6,7 +6,7 @@ import { ArrowUpRight } from "lucide-react"; import Link from "next/link"; import Image from "next/image"; import { useLocale, useTranslations } from "next-intl"; -import { Skeleton } from "boneyard-js/react"; +import { Skeleton } from "./ui/Skeleton"; import ProjectThumbnail from "./ProjectThumbnail"; interface Project { @@ -64,9 +64,19 @@ const Projects = () => {
- + {loading ? ( +
+ {Array.from({ length: 4 }).map((_, i) => ( +
+ + + +
+ ))} +
+ ) : (
- {projects.length === 0 && !loading ? ( + {projects.length === 0 ? (
{t("noProjects")}
@@ -121,7 +131,7 @@ const Projects = () => { )))}
-
+ )}
); diff --git a/app/components/ReadBooks.tsx b/app/components/ReadBooks.tsx index 9bdeaf4..d823d66 100644 --- a/app/components/ReadBooks.tsx +++ b/app/components/ReadBooks.tsx @@ -5,7 +5,7 @@ import { BookCheck, Star, ChevronDown, ChevronUp } from "lucide-react"; import { useEffect, useState } from "react"; import { useLocale, useTranslations } from "next-intl"; import Image from "next/image"; -import { Skeleton } from "boneyard-js/react"; +import { Skeleton } from "./ui/Skeleton"; interface BookReview { id: string; @@ -95,9 +95,31 @@ const ReadBooks = () => { const visibleReviews = expanded ? reviews : reviews.slice(0, INITIAL_SHOW); const hasMore = reviews.length > INITIAL_SHOW; - return ( - + if (loading) { + return (
+
+ + +
+ {Array.from({ length: 3 }).map((_, i) => ( +
+
+ +
+ + + +
+
+
+ ))} +
+ ); + } + + return ( +
{/* Header */}
@@ -243,7 +265,6 @@ const ReadBooks = () => { )}
- ); }; diff --git a/app/components/ShaderGradientBackground.tsx b/app/components/ShaderGradientBackground.tsx index 56e4b88..9c5db96 100644 --- a/app/components/ShaderGradientBackground.tsx +++ b/app/components/ShaderGradientBackground.tsx @@ -5,54 +5,27 @@ export default function ShaderGradientBackground() { return (