Compare commits

...

2 Commits

Author SHA1 Message Date
Craig
f9c6b607cd Add gifs to expertise sections 2025-03-06 15:51:47 +00:00
Craig
206e180948 Add links to header and contact section 2025-02-28 12:41:37 +00:00
15 changed files with 77 additions and 44 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title> <title>Craig Macfadyen</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@@ -21,6 +21,7 @@
"lucide-react": "^0.476.0", "lucide-react": "^0.476.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-icons": "^5.5.0",
"tailwind-merge": "^3.0.2", "tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.8", "tailwindcss": "^4.0.8",
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7"
@@ -3809,6 +3810,15 @@
"react": "^19.0.0" "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==",
"license": "MIT",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.14.2", "version": "0.14.2",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",

View File

@@ -23,6 +23,7 @@
"lucide-react": "^0.476.0", "lucide-react": "^0.476.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-icons": "^5.5.0",
"tailwind-merge": "^3.0.2", "tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.8", "tailwindcss": "^4.0.8",
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7"

View File

@@ -8,7 +8,8 @@ import Navbar04Page from './components/navbar-04/navbar-04';
import Testimonial06 from './components/testimonial-06/testimonial-06'; import Testimonial06 from './components/testimonial-06/testimonial-06';
function App() { function App() {
return ( return (
<div className="App min-h-screen bg-muted rounded-lg"> <div className="App min-h-screen bg-muted rounded-3xl">
<title>Home | Craig Macfadyen</title>
<Navbar04Page /> <Navbar04Page />
<Hero /> <Hero />
<About /> <About />

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

View File

@@ -1,20 +1,20 @@
import React from 'react'; import React from 'react';
import ExpertiseSection from './ExpertiseSection'; import ExpertiseSection from './ExpertiseSection';
import outputGif from '@/assets/output.gif';
import openWebUIGif from '@/assets/open-webui.gif';
const About = () => { const About = () => {
return ( return (
<section id="about" className="about py-20 bg-gray-100"> <section id="about" className="about py-20 bg-gray-100">
<div className="container mx-auto"> <div className="container mx-auto">
<h2 className="text-3xl font-bold mb-4">About</h2>
<p className="text-lg mb-8"> <p className="text-lg mb-8">
You have data, I have the skills to help you make sense of it. You have data, I have the skills to help you understand it.
</p> </p>
<ExpertiseSection <ExpertiseSection
title="Computer Vision" title="Computer Vision"
content="Expertise in developing and deploying computer vision models for various applications, including object detection, image classification, and more. Ask me about state-of-the-art real-time models for your business." content="Expertise in developing and deploying computer vision models for various applications, including object detection, image classification, and more. Ask me about state-of-the-art real-time models for your business."
images={[ images={[
{ url: "https://gifs.cc/congratulation/congrats-animation-smiley-2018.gif", alt: "Computer Vision 1" }, { url: outputGif, alt: "Video Segmentation with SAM2." },
{ url: "https://example.com/image2.jpg", alt: "Computer Vision 2" },
]} ]}
viewMoreLink="/computer-vision" viewMoreLink="/computer-vision"
imageOnLeft={true} imageOnLeft={true}
@@ -23,8 +23,7 @@ const About = () => {
title="Natural Language Processing" title="Natural Language Processing"
content="Building NLP models for tasks such as sentiment analysis, text classification, and language generation. If you need a chatbot for your business and care about privacy, or a simple text classification algorithm to understand your data, I can help." content="Building NLP models for tasks such as sentiment analysis, text classification, and language generation. If you need a chatbot for your business and care about privacy, or a simple text classification algorithm to understand your data, I can help."
images={[ images={[
{ url: "/path/to/nlp-image.jpg", alt: "NLP 1" }, { url: openWebUIGif, alt: "Locally hosted LLM using oLLama and OpenWebUI." },
{ url: "/path/to/nlp-image2.jpg", alt: "NLP 2" },
]} ]}
viewMoreLink="/nlp" viewMoreLink="/nlp"
imageOnLeft={false} imageOnLeft={false}

View File

@@ -1,13 +1,25 @@
import React from 'react'; import { Button } from "@/components/ui/button";
import { Button } from "@/components/ui/button" import { SiLinkedin } from "react-icons/si";
const Contact = () => { const Contact = () => {
return ( return (
<section id="contact" className="contact py-20 bg-gray-100"> <section id="contact" className="contact py-20">
<div className="container mx-auto"> <div className="container mx-auto">
<h2 className="text-3xl font-bold mb-4">Contact Me</h2> <h2 className="text-3xl font-bold mb-4">Contact Me</h2>
<p className="text-lg mb-4">Feel free to reach out!</p> <p className="text-lg mb-4">
<Button>Contact</Button> Get in touch with me at <a href="mailto:cdmacfadyen@proton.me" className="text-blue-500">cdmacfadyen@proton.me</a>, or drop me a message on LinkedIn.
</p>
<div className="flex items-center justify-center gap-3">
<Button asChild>
<a href="mailto:cdmacfadyen@proton.me">Email Me</a>
</Button>
<Button asChild>
<a href="https://www.linkedin.com/in/craig-macfadyen-9a2041197/" target="_blank" rel="noopener noreferrer">
<SiLinkedin className="w-6 h-6 mr-2" />
LinkedIn
</a>
</Button>
</div>
</div> </div>
</section> </section>
); );

View File

@@ -26,9 +26,9 @@ const ExpertiseSection: React.FC<ExpertiseSectionProps> = ({
<div className="md:w-2/3 md:px-8"> <div className="md:w-2/3 md:px-8">
<h2 className="text-3xl font-bold mb-4">{title}</h2> <h2 className="text-3xl font-bold mb-4">{title}</h2>
<p className="text-lg mb-4">{content}</p> <p className="text-lg mb-4">{content}</p>
<Button asChild> {/* <Button asChild>
<a href={viewMoreLink}>View More</a> <a href={viewMoreLink}>View More</a>
</Button> </Button> */}
</div> </div>
</div> </div>
</section> </section>

View File

@@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button"
const Hero = () => { const Hero = () => {
return ( return (
<section id="hero" className="hero py-20"> <section id="hero" className="hero">
<div className="container mx-auto text-center"> <div className="container mx-auto text-center">
<h1 className="text-5xl font-bold mb-4">Craig Macfadyen</h1> <h1 className="text-5xl font-bold mb-4">Craig Macfadyen</h1>
<p className="text-xl mb-8"> <p className="text-xl mb-8">

View File

@@ -27,6 +27,9 @@ const ImageCarousel: React.FC<ImageCarouselProps> = ({ images, delay = 8000 }) =
{images.map((image, index) => ( {images.map((image, index) => (
<CarouselItem key={index}> <CarouselItem key={index}>
<img src={image.url} alt={image.alt} className="rounded-lg shadow-md" /> <img src={image.url} alt={image.alt} className="rounded-lg shadow-md" />
<div className="text-center py-2 rounded-lg bg-white">
{image.alt}
</div>
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>

View File

@@ -11,7 +11,7 @@ export const NavMenu = (props: NavigationMenuProps) => (
<NavigationMenuList className="gap-6 space-x-0 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-start"> <NavigationMenuList className="gap-6 space-x-0 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-start">
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuLink asChild> <NavigationMenuLink asChild>
<a href="#">Home</a> <a href="/">Home</a>
</NavigationMenuLink> </NavigationMenuLink>
</NavigationMenuItem> </NavigationMenuItem>
{/* <NavigationMenuItem> {/* <NavigationMenuItem>
@@ -21,7 +21,7 @@ export const NavMenu = (props: NavigationMenuProps) => (
</NavigationMenuItem> */} </NavigationMenuItem> */}
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuLink asChild> <NavigationMenuLink asChild>
<a href="#">Contact</a> <a href="#contact">Contact</a>
</NavigationMenuLink> </NavigationMenuLink>
</NavigationMenuItem> </NavigationMenuItem>
</NavigationMenuList> </NavigationMenuList>

View File

@@ -1,35 +1,42 @@
import { Button } from "@/components/ui/button";
import { Logo } from "./logo"; import { Logo } from "./logo";
import { NavMenu } from "./nav-menu"; import { NavMenu } from "./nav-menu";
import { NavigationSheet } from "./navigation-sheet"; import { NavigationSheet } from "./navigation-sheet";
import { SiLinkedin, SiGithub, SiGitea } from "react-icons/si";
const Navbar04Page = () => { const Navbar04Page = () => {
return ( return (
// <div className="min-h-screen bg-muted"> <nav className="top-6 inset-x-4 h-16 bg-background border dark:border-slate-700/70 max-w-screen-xl mx-auto rounded-full">
<nav className="top-6 inset-x-4 h-16 bg-background border dark:border-slate-700/70 max-w-screen-xl mx-auto rounded-full"> <div className="h-full flex items-center justify-between mx-auto px-4">
<div className="h-full flex items-center justify-between mx-auto px-4">
<Logo />
{/* Desktop Menu */}
<NavMenu className="hidden md:block" />
{/* Desktop Menu */}
<NavMenu className="hidden md:block" />
<div className="flex items-center gap-3">
{/* Social Media Links */}
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Button <a href="https://www.linkedin.com/in/craig-macfadyen-9a2041197/" target="_blank" rel="noopener noreferrer">
variant="outline" <SiLinkedin className="w-6 h-6 text-gray-700 dark:text-gray-300" />
className="hidden sm:inline-flex rounded-full" </a>
> <a href="https://github.com/cdmacfadyen" target="_blank" rel="noopener noreferrer">
Sign In <SiGithub className="w-6 h-6 text-gray-700 dark:text-gray-300" />
</Button> </a>
<a href="https://gitea.craigmacfadyen.co.uk/" target="_blank" rel="noopener noreferrer">
{/* Mobile Menu */} <SiGitea className="w-6 h-6 text-gray-700 dark:text-gray-300" />
<div className="md:hidden"> </a>
<NavigationSheet /> </div>
</div> {/* <Button
variant="outline"
className="hidden sm:inline-flex rounded-full"
>
Sign In
</Button> */}
{/* Mobile Menu */}
<div className="md:hidden">
<NavigationSheet />
</div> </div>
</div> </div>
</nav> </div>
// </div> </nav>
); );
}; };
export default Navbar04Page; export default Navbar04Page;

View File

@@ -41,7 +41,7 @@ const Testimonial06 = () => {
}, [api]); }, [api]);
return ( return (
<div className="min-h-screen w-full flex justify-center items-center py-12 px-6"> <div className="w-full flex justify-center items-center px-6">
<div className="w-full"> <div className="w-full">
<h2 className="mb-14 text-5xl md:text-6xl font-bold text-center tracking-tight"> <h2 className="mb-14 text-5xl md:text-6xl font-bold text-center tracking-tight">
Testimonials Testimonials
@@ -58,7 +58,7 @@ const Testimonial06 = () => {
<CarouselPrevious /> <CarouselPrevious />
<CarouselNext /> <CarouselNext />
</Carousel> </Carousel>
<div className="flex items-center justify-center gap-2"> {/* <div className="flex items-center justify-center gap-2">
{Array.from({ length: count }).map((_, index) => ( {Array.from({ length: count }).map((_, index) => (
<button <button
key={index} key={index}
@@ -68,7 +68,7 @@ const Testimonial06 = () => {
})} })}
/> />
))} ))}
</div> </div> */}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -55,4 +55,4 @@ function Button({
) )
} }
export { Button, buttonVariants } export { Button }