Refactor imports and improve layout in various components; update styles for consistency and readability.

This commit is contained in:
Craig
2025-04-10 15:04:30 +01:00
parent 55f56123ad
commit 0dc593c817
12 changed files with 116 additions and 106 deletions

View File

@@ -1,6 +1,6 @@
import { ActionIcon, useMantineColorScheme } from '@mantine/core';
import { TbSun, TbMoon } from 'react-icons/tb';
import cx from 'clsx';
import { TbMoon, TbSun } from 'react-icons/tb';
import { ActionIcon, useMantineColorScheme } from '@mantine/core';
import classes from './ColorSchemeToggle.module.css';
export function ColorSchemeToggle() {

View File

@@ -1,4 +1,4 @@
import { Container, Stack, Title, Text, Anchor } from '@mantine/core';
import { Anchor, Container, Stack, Text, Title } from '@mantine/core';
import classes from './Contact.module.css';
export function Contact() {
@@ -7,13 +7,17 @@ export function Contact() {
<Stack gap="md">
<Title className={classes.title}>Get in Touch</Title>
<Text className={classes.description}>
If you'd like to collaborate, have any questions, or just want to say hello, feel free to reach out!
If you'd like to collaborate, have any questions, or just want to say hello, feel free to
reach out!
</Text>
<Text>
Email: <Anchor href="mailto:cdmacfadyen@proton.me">cdmacfadyen@proton.me</Anchor>
</Text>
<Text>
LinkedIn: <Anchor href="https://www.linkedin.com/in/craig-macfadyen-9a2041197" target="_blank">linkedin.com/in/craigmacfadyen</Anchor>
LinkedIn:{' '}
<Anchor href="https://www.linkedin.com/in/craig-macfadyen-9a2041197" target="_blank">
linkedin.com/in/craigmacfadyen
</Anchor>
</Text>
</Stack>
</Container>

View File

@@ -1,4 +1,4 @@
import { TbAt, TbMapPin, TbPhone, TbSun } from 'react-icons/tb';
import { TbAt, TbSun } from 'react-icons/tb';
import { Box, Stack, Text } from '@mantine/core';
import classes from './ContactIcons.module.css';
@@ -25,9 +25,7 @@ function ContactIcon({ icon: Icon, title, description, ...others }: ContactIconP
);
}
const MOCKDATA = [
{ title: 'Email', description: 'hello@mantine.dev', icon: TbAt },
];
const MOCKDATA = [{ title: 'Email', description: 'hello@mantine.dev', icon: TbAt }];
export function ContactIconsList() {
const items = MOCKDATA.map((item, index) => <ContactIcon key={index} {...item} />);

View File

@@ -15,7 +15,7 @@
.title {
font-family:
Greycliff CF,
"Greycliff CF",
var(--mantine-font-family);
color: var(--mantine-color-white);
line-height: 1;

View File

@@ -17,7 +17,7 @@ const social = [TbBrandInstagram, TbBrandTwitter, TbBrandYoutube];
export function ContactUs() {
const icons = social.map((Icon, index) => (
<ActionIcon key={index} size={28} className={classes.social} variant="transparent">
<Icon size={22} stroke={1.5} />
<Icon size={22} stroke="1.5" />
</ActionIcon>
));

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { Button, Text, Title, Container, Stack, Grid, Image, Center } from '@mantine/core';
import { Carousel } from '@mantine/carousel';
import { Container, Grid, Image, Stack, Text, Title } from '@mantine/core';
import classes from './ExpertiseSection.module.css';
interface ExpertiseSectionProps {
@@ -15,12 +15,16 @@ const ExpertiseSection: React.FC<ExpertiseSectionProps> = ({
title,
content,
images,
viewMoreLink,
viewMoreLink: _viewMoreLink,
imageOnLeft = false,
}) => {
const slides = images.map((image) => (
<Carousel.Slide key={image.url}>
<Image src={image.url} alt={image.alt} style={{ width: '100%', height: 'auto', objectFit: 'cover' }} />
<Image
src={image.url}
alt={image.alt}
style={{ width: '100%', height: 'auto', objectFit: 'cover' }}
/>
</Carousel.Slide>
));
@@ -37,7 +41,15 @@ const ExpertiseSection: React.FC<ExpertiseSectionProps> = ({
</Stack>
</Grid.Col>
<Grid.Col order={imageOnLeft ? 1 : 2} span={{ xs: 6, md: 4 }}>
<Carousel slideSize={300} align="start" slideGap="md" controlsOffset="xl" controlSize={28} loop withIndicators>
<Carousel
slideSize={300}
align="start"
slideGap="md"
controlsOffset="xl"
controlSize={28}
loop
withIndicators
>
{slides}
</Carousel>
</Grid.Col>

View File

@@ -2,8 +2,8 @@ import { useState } from 'react';
import { Burger, Container, Group } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { MantineLogo } from '@mantinex/mantine-logo';
import classes from './HeaderSimple.module.css';
import { ColorSchemeToggle } from '../ColorSchemeToggle/ColorSchemeToggle';
import classes from './HeaderSimple.module.css';
const links = [
{ link: '/about', label: 'Features' },

View File

@@ -9,6 +9,7 @@
padding-top: 200px;
padding-bottom: 120px;
width: 80%;
@media (max-width: $mantine-breakpoint-sm) {
padding-bottom: 80px;
padding-top: 80px;
@@ -17,7 +18,7 @@
.title {
font-family:
Greycliff CF,
"Greycliff CF",
var(--mantine-font-family);
font-size: 62px;
font-weight: 900;

View File

@@ -5,7 +5,7 @@ import classes from './HeroTitle.module.css';
export function HeroTitle() {
return (
<div className={classes.wrapper}>
<Container fluid={true} size={700} className={classes.inner}>
<Container fluid size={700} className={classes.inner}>
<h1 className={classes.title}>
{' '}
<Text component="span" variant="gradient" gradient={{ from: 'blue', to: 'cyan' }} inherit>
@@ -14,8 +14,9 @@ export function HeroTitle() {
</h1>
<Text className={classes.description} c="dimmed">
Data Scientist with experience in consulting and research. Expertise in Computer Vision and Large Language Models. Take a look at what
I can do for your business and get in touch if you have any questions or you'd like to work together!
Data Scientist with experience in consulting and research. Expertise in Computer Vision
and Large Language Models. Take a look at what I can do for your business and get in touch
if you have any questions or you'd like to work together!
</Text>
<Group className={classes.controls}>

View File

@@ -1,29 +1,27 @@
import { Carousel } from '@mantine/carousel';
import { Card, Text, Avatar, Group, Stack, Title } from '@mantine/core';
import Autoplay from 'embla-carousel-autoplay';
import { Carousel } from '@mantine/carousel';
import { Avatar, Card, Group, Stack, Text, Title } from '@mantine/core';
import styles from './Testimonial.module.css';
const testimonials = [
{
text: "What set Craig apart was his ability to understand our business challenges and deliver a solution that worked for us. He didn't just build a model, he delivered a system our team could actually use.",
clientName: "Steven Adair",
role: "Director",
business: "Managing Utilities Limited",
clientName: 'Steven Adair',
role: 'Director',
business: 'Managing Utilities Limited',
},
];
function TestimonialsCarousel() {
const autoplay = Autoplay();
return (
<>
<Title align="center" mb="xl">
<Title ta="center" mb="xl">
Testimonials
</Title>
<Carousel
slideSize={'100%'}
slideSize="100%"
slideGap="md"
loop
align="start"
@@ -38,11 +36,11 @@ function TestimonialsCarousel() {
<Stack gap="sm">
<Text size="lg">{testimonial.text}</Text>
<Group gap="sm">
<Avatar radius="xl">
{testimonial.clientName.charAt(0)}
</Avatar>
<Avatar radius="xl">{testimonial.clientName.charAt(0)}</Avatar>
<div>
<Text size="lg" fw={700}>{testimonial.clientName}</Text>
<Text size="lg" fw={700}>
{testimonial.clientName}
</Text>
<Text size="sm" c="dimmed">
{testimonial.role}, {testimonial.business}
</Text>

View File

@@ -1,4 +1,6 @@
import ReactDOM from 'react-dom/client';
import App from './App';
import '@mantine/carousel/styles.css';
ReactDOM.createRoot(document.getElementById('root')!).render(<App />);

View File

@@ -1,13 +1,11 @@
import { HeroTitle } from '@/components/HeroTitle/HeroTitle';
import { Welcome } from '../components/Welcome/Welcome';
import { HeaderSimple } from '@/components/HeaderSimple/HeaderSimple';
import ExpertiseSection from '@/components/ExpertiseSection/ExpertiseSection';
import outputGif from '@/assets/output.gif';
import openWebUIGif from '@/assets/open-webui.gif';
import Testimonial from '@/components/Testimonial/Testimonial';
import { Container } from '@mantine/core';
import { ContactUs } from '@/components/ContactUs/ContactUs';
import openWebUIGif from '@/assets/open-webui.gif';
import outputGif from '@/assets/output.gif';
import { Contact } from '@/components/ContactUs/Contact';
import ExpertiseSection from '@/components/ExpertiseSection/ExpertiseSection';
import { HeaderSimple } from '@/components/HeaderSimple/HeaderSimple';
import { HeroTitle } from '@/components/HeroTitle/HeroTitle';
import Testimonial from '@/components/Testimonial/Testimonial';
export function HomePage() {
return (
@@ -17,18 +15,14 @@ export function HomePage() {
<ExpertiseSection
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."
images={[
{ url: outputGif, alt: "Video Segmentation with SAM2." },
]}
images={[{ url: outputGif, alt: 'Video Segmentation with SAM2.' }]}
viewMoreLink="/computer-vision"
imageOnLeft={true}
imageOnLeft
/>
<ExpertiseSection
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."
images={[
{ url: openWebUIGif, alt: "Locally hosted LLM using oLLama and OpenWebUI." },
]}
images={[{ url: openWebUIGif, alt: 'Locally hosted LLM using oLLama and OpenWebUI.' }]}
viewMoreLink="/nlp"
imageOnLeft={false}
/>