From 0a0297581fb6c6919983b81759a807f6e5a63925 Mon Sep 17 00:00:00 2001 From: c0mputerGuy11 Date: Sat, 29 Mar 2025 04:05:37 +0100 Subject: [PATCH] Fix Copy Button + Add Navbar + Update Blog, About & Projects Pages Solved issue #4 (copy button), added navbar, and refined the blog, about, and projects pages with better layout and styling --- .hintrc | 13 +++ app/about/page.jsx | 77 +++++++++++++++ .../page.mdx | 0 app/blog/{ => (post)}/layout.tsx | 16 ++- app/blog/page.jsx | 56 +++++++++++ app/header.tsx | 18 +++- app/layout.tsx | 2 +- app/solutions/page.jsx | 98 +++++++++++++++++++ package-lock.json | 9 ++ package.json | 1 + public/solutions/projects.json | 15 +++ 11 files changed, 296 insertions(+), 9 deletions(-) create mode 100644 .hintrc create mode 100644 app/about/page.jsx rename app/blog/{ => (post)}/exploring-the-intersection-of-design-ai-and-design-engineering/page.mdx (100%) rename app/blog/{ => (post)}/layout.tsx (79%) create mode 100644 app/blog/page.jsx create mode 100644 app/solutions/page.jsx create mode 100644 public/solutions/projects.json diff --git a/.hintrc b/.hintrc new file mode 100644 index 00000000..9024f9c7 --- /dev/null +++ b/.hintrc @@ -0,0 +1,13 @@ +{ + "extends": [ + "development" + ], + "hints": { + "axe/name-role-value": [ + "default", + { + "button-name": "off" + } + ] + } +} \ No newline at end of file diff --git a/app/about/page.jsx b/app/about/page.jsx new file mode 100644 index 00000000..903b5e6a --- /dev/null +++ b/app/about/page.jsx @@ -0,0 +1,77 @@ +"use client"; + +import { motion } from "framer-motion"; +import { FaGithub } from "react-icons/fa"; + +import Image from "next/image"; + +export default function AboutPage() { + return ( + + {/* 🌟 About Me Section */} + +

+ About Me +

+

+ Hey, I'm Khalil! I love building intuitive and performant web experiences. + My focus is on bridging design and development, ensuring that every digital + product I create is smooth, functional, and visually appealing. +

+
+ + {/* 🔥 Now Section */} + +

+ Now +

+

+ I'm building tools that leverage DevOps to optimize software engineering workflows, exploring cloud computing to enhance scalability, and diving into distributed ledgers to push the boundaries of secure and decentralized systems. Through tackling complex logic challenges, I continuously refine my problem-solving skills, bridging the gap between infrastructure and innovation. +

+ +
+ + {/* 🎉 Fun Facts Section */} + +

+ Fun Facts +

+
+
+

🔥 Night Owl Coder

+

+ I do my best work late at night with a cup of coffee. +

+
+
+

🎮 Gamer at Heart

+

+ I enjoy playing strategy and open-world games in my free time. +

+
+
+
+ +

More

+

+ Once, I heard "software is just code." But then I realized—it really is just code. + The magic isn’t in the lines themselves, but in how you put them together. +

+

+ Check out my + I keep it updated with projects, experiments, and things I break on purpose. + You might find something useful or at least interesting. +

+ +
+ +
+ ); +} diff --git a/app/blog/exploring-the-intersection-of-design-ai-and-design-engineering/page.mdx b/app/blog/(post)/exploring-the-intersection-of-design-ai-and-design-engineering/page.mdx similarity index 100% rename from app/blog/exploring-the-intersection-of-design-ai-and-design-engineering/page.mdx rename to app/blog/(post)/exploring-the-intersection-of-design-ai-and-design-engineering/page.mdx diff --git a/app/blog/layout.tsx b/app/blog/(post)/layout.tsx similarity index 79% rename from app/blog/layout.tsx rename to app/blog/(post)/layout.tsx index d398a325..7c612fd9 100644 --- a/app/blog/layout.tsx +++ b/app/blog/(post)/layout.tsx @@ -2,10 +2,11 @@ import { TextMorph } from '@/components/ui/text-morph' import { ScrollProgress } from '@/components/ui/scroll-progress' import { useEffect, useState } from 'react' +import { FaRegCopy } from "react-icons/fa6"; function CopyButton() { const [text, setText] = useState('Copy') - const currentUrl = typeof window !== 'undefined' ? window.location.href : '' + const [currentUrl, setCurrentUrl] = useState('') useEffect(() => { setTimeout(() => { @@ -13,6 +14,10 @@ function CopyButton() { }, 2000) }, [text]) + useEffect(() => { + setCurrentUrl(window.location.href) + }, []) + return ( ) } @@ -43,9 +47,11 @@ export default function LayoutBlogPost({ }} /> -
- -
+
+ +
+ +
{children}
diff --git a/app/blog/page.jsx b/app/blog/page.jsx new file mode 100644 index 00000000..f163f90d --- /dev/null +++ b/app/blog/page.jsx @@ -0,0 +1,56 @@ +"use client"; + +import { motion } from "framer-motion"; +import { useEffect, useState } from "react"; +import Link from "next/link"; +import { AnimatedBackground } from '@/components/ui/animated-background' +import { + + BLOG_POSTS, + + } from '../data' +const VARIANTS_SECTION = { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0 } +}; + +const TRANSITION_SECTION = { duration: 0.3, ease: "easeInOut" }; + +export default function BlogPage() { + const [posts, setPosts] = useState([]); + + + return ( + +

Blog

+
+ + {BLOG_POSTS.map((post) => ( + +
+

{post.title}

+

+ {post.description} +

+
+ + ))} +
+
+
+ ); +} diff --git a/app/header.tsx b/app/header.tsx index 872f234e..3599e128 100644 --- a/app/header.tsx +++ b/app/header.tsx @@ -4,11 +4,11 @@ import Link from 'next/link' export function Header() { return ( -
-
+
+
Julien Nim - + -
+
+ + Solutions + + + About + + + Blog + + +
) } diff --git a/app/layout.tsx b/app/layout.tsx index a43b5408..f73fea9b 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -35,7 +35,7 @@ export default function RootLayout({ return ( { + fetch("/solutions/projects.json") + .then((res) => res.json()) + .then((data) => setProjects(data)) + .catch((error) => console.error("Error loading projects:", error)); + }, []); + + return ( + +

Solutions

+
+ {projects.map((project) => ( + + ))} +
+
+ + ); +} + +function ProjectItem({ project }) { + const [hovered, setHovered] = useState(false); + const [position, setPosition] = useState({ x: 0, y: 0 }); + + const handleMouseMove = (event) => { + setPosition({ x: event.clientX + 15, y: event.clientY + 15 }); + }; + + return ( +
setHovered(true)} + onMouseLeave={() => setHovered(false)} + onMouseMove={handleMouseMove} + > + {/* Project Info */} +
+ + {project.name} + +  •  {project.description} +
+ + + {/* Icons */} +
+ + + + + + + + +
+ + + {/* Floating Image Next to Cursor */} + {hovered && ( + {project.name} + )} +
+ ); +} diff --git a/package-lock.json b/package-lock.json index 149b8403..52c9001d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "next-themes": "^0.4.4", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-icons": "^5.5.0", "tailwind-merge": "^2.5.5" }, "devDependencies": { @@ -5710,6 +5711,14 @@ "react": "^19.0.0" } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index d84bc9f2..c2f3d1fe 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "next-themes": "^0.4.4", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-icons": "^5.5.0", "tailwind-merge": "^2.5.5" }, "devDependencies": { diff --git a/public/solutions/projects.json b/public/solutions/projects.json new file mode 100644 index 00000000..9cf9498c --- /dev/null +++ b/public/solutions/projects.json @@ -0,0 +1,15 @@ +[{ + "name": "Project 1", + "description": "This is a cool project.", + "link": "https://example.com", + "github": "https://github.com/example", + "image": "https://images.unsplash.com/photo-1742943679521-f4736500a471?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" + }, + { + "name": "Project 2", + "description": "Another awesome project.", + "link": "https://example.com", + "github": "https://github.com/example", + "image": "/images/project2.jpg" + } +] \ No newline at end of file