From 971a79737fbf4b11a06feab909c828b634e2df68 Mon Sep 17 00:00:00 2001 From: Davide Crestini Date: Wed, 17 Jul 2024 21:58:04 +0300 Subject: [PATCH] chore: bunch of UI fixes --- src/app/_components/Contact/index.tsx | 45 ++++++ src/app/_components/Hero.tsx | 4 +- src/app/_components/Projects/ProjectsList.tsx | 2 +- src/app/about/_components/Hero.tsx | 12 +- src/app/about/_components/ThingsToCare.tsx | 72 +++++----- src/app/page.tsx | 12 +- .../services/_components/DesignProcess.tsx | 82 ++++++----- src/app/services/_components/Expertise.tsx | 53 +++---- src/app/services/_components/GetInTouch.tsx | 28 ++-- src/app/services/_components/WhereToStart.tsx | 4 +- .../services/_components/WorthyClients.tsx | 76 ---------- src/app/services/page.tsx | 7 +- src/components/LetsWorkTogether.tsx | 33 +++++ src/components/Marquee.tsx | 132 ++++++++++++++++++ src/components/Navbar/Navbar.tsx | 10 +- src/components/Navbar/links.ts | 2 +- src/components/TitleAndCopy.tsx | 2 +- src/components/WorthyClients.tsx | 110 +++++++++++++++ src/globals.css | 2 +- tailwind.config.js | 9 +- 20 files changed, 479 insertions(+), 218 deletions(-) create mode 100644 src/app/_components/Contact/index.tsx delete mode 100644 src/app/services/_components/WorthyClients.tsx create mode 100644 src/components/LetsWorkTogether.tsx create mode 100644 src/components/Marquee.tsx create mode 100644 src/components/WorthyClients.tsx diff --git a/src/app/_components/Contact/index.tsx b/src/app/_components/Contact/index.tsx new file mode 100644 index 0000000..1d11e36 --- /dev/null +++ b/src/app/_components/Contact/index.tsx @@ -0,0 +1,45 @@ +"use client"; + +import { motion, Variants } from "framer-motion"; + +import { LetsWorkTogether } from "@/components/LetsWorkTogether"; + +const variants: Variants = { + offscreen: { + y: 10, + opacity: 0, + }, + onscreen: { + y: 0, + opacity: 1, + transition: { + type: "spring", + duration: 1, + }, + }, +}; + +export const Contact = () => { + return ( + + + Art Direction, Branding, Campaign Strategy, Digital, Identity, Label + design, Packaging, Print, Social Media, Online Strategy, Web Design, + Interior Branding and Visualisation, Book Design. + + + + + + + ); +}; diff --git a/src/app/_components/Hero.tsx b/src/app/_components/Hero.tsx index 28a73de..3c9a17d 100644 --- a/src/app/_components/Hero.tsx +++ b/src/app/_components/Hero.tsx @@ -27,7 +27,7 @@ const variants: Variants = { export const Hero: React.FC = ({ homepageCopy }) => (
-
+
= ({ homepageCopy }) => ( transition={{ staggerChildren: 0.3 }} > {homepageCopy.quote && ( - + )} diff --git a/src/app/_components/Projects/ProjectsList.tsx b/src/app/_components/Projects/ProjectsList.tsx index d5f35fe..93c4d9b 100644 --- a/src/app/_components/Projects/ProjectsList.tsx +++ b/src/app/_components/Projects/ProjectsList.tsx @@ -32,7 +32,7 @@ export const ProjectsList: React.FC = ({ projects }) => { return (
-
+
{leftColumnProjects.map((project) => ( diff --git a/src/app/about/_components/Hero.tsx b/src/app/about/_components/Hero.tsx index aa2c49e..669a92a 100644 --- a/src/app/about/_components/Hero.tsx +++ b/src/app/about/_components/Hero.tsx @@ -29,7 +29,7 @@ interface AboutHeroProps { export const AboutHero: React.FC = ({ headerText, links }) => { return ( = ({ headerText, links }) => { > - Art Direction, Branding, Campaign Strategy, Digital, Identity, - Packaging, Photography, Print, Social Media, Strategy, Web Design, - Interior Visualisation. + Art Direction, Branding, Campaign Strategy, Digital, Identity, Label + design, Packaging, Print, Social Media, Online Strategy, Web Design, + Interior Branding and Visualisation, Book Design. diff --git a/src/app/about/_components/ThingsToCare.tsx b/src/app/about/_components/ThingsToCare.tsx index 72097f1..375113d 100644 --- a/src/app/about/_components/ThingsToCare.tsx +++ b/src/app/about/_components/ThingsToCare.tsx @@ -1,49 +1,49 @@ import { TitleAndCopy } from "@/components/TitleAndCopy"; +const items = [ + { + title: "Design Impact", + description: + "Design has a lot to answer for. Which means as a designer I have the responsibility to do what I can to keep things organic, help smaller realities and keep my attention on sustainable outcomes.", + }, + { + title: "Community", + description: ( + <> + I{"'"}m an active community member for Humanitarian Designers and{" "} + Let{"'"}s Talk Palestine. I{"'"}ve also volunteered for the{" "} + Migration museum in London and{" "} + Bandstand Beds, a community garden + + ), + }, + { + title: "Different Mediums", + description: + "Should I say integrated? Multi-disciplined? Versatile? I love architecture, sculpture, photography, digital art and all forms of design, which make any chance to use as many variations of art in my work the more exciting.", + }, + { + title: "Collaborations", + description: + "I love working with other professionals and creatives, if you're looking for people to join you on a project or even just get a second opinion, please contact me - I would love to help any way I can.", + }, +]; + export const ThingsToCare: React.FC = () => { return (
-

+

Things I care about

-
- -

- Design has a lot to answer for. Which means as a designer I have the - responsibility to do what I can to keep things organic, help smaller - realities and keep my attention on sustainable outcomes. -

-
- - -

- I{"'"}m an active community member for Humanitarian Designers{" "} - and Let{"'"}s Talk Palestine. I{"'"}ve also volunteered for - the Migration museum in London and{" "} - Bandstand Beds, a community garden. -

-
- - -

- Should I say integrated? Multi-disciplined? Versatile? I love - architecture, sculpture, photography, digital art and all forms of - design, which make any chance to use as many variations of art in my - work the more exciting. -

-
- - -

- I love working with other professionals and creatives, if you’re - looking for people to join you on a project or even just get a - second opinion, please contact me - I would love to help any way I - can. -

-
+
+ {items.map((item, index) => ( + +

{item.description}

+
+ ))}
); diff --git a/src/app/page.tsx b/src/app/page.tsx index 54f6218..f3d15a3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,17 +1,15 @@ import { Suspense } from "react"; import { draftMode } from "next/headers"; -import { Footer } from "@/components/Footer"; +import { WorthyClients } from "@/components/WorthyClients"; import { ProjectsFilterContextProvider } from "@/contexts/ProjectsFilterContext"; import { getHomepageCopy } from "@/graphql/queries/get-homepage-copy"; -import { Blog } from "./_components/Blog"; -import { GetInTouch } from "./_components/GetInTouch"; +import { Contact } from "./_components/Contact"; import { Hero } from "./_components/Hero"; import ProjectsListSection from "./_components/Projects"; import { Filterbar } from "./_components/Projects/Filterbar"; import { ProjectsListLoading } from "./_components/Projects/ProjectsListLoading"; -import { Skills } from "./_components/Skills"; export default async function Home() { const { isEnabled: isPreviewEnabled } = draftMode(); @@ -31,11 +29,9 @@ export default async function Home() {
- + - - - +
); } diff --git a/src/app/services/_components/DesignProcess.tsx b/src/app/services/_components/DesignProcess.tsx index 6f98732..2f8f9d7 100644 --- a/src/app/services/_components/DesignProcess.tsx +++ b/src/app/services/_components/DesignProcess.tsx @@ -3,45 +3,57 @@ import classNames from "classnames"; import { TitleAndCopy } from "@/components/TitleAndCopy"; import { ChevronRightIcon } from "@/icons/ChevronRight"; +const items = [ + { + number: "01", + title: "Discovery", + description: + "It's about understanding your goals and needs, by analysing your current brand, market position, target customer experience and, above all, the message you want to convey.", + }, + { + number: "02", + title: "Concept Dev", + description: + "Based on our discussion, we create a solid base by defining the key conceptual elements to use for our brand strategy.", + }, + { + number: "03", + title: "Design & Revision", + description: + "Now for the really fun bit! Starting with initial rough concepts we then collaborate with you through additional rounds of feedback to close in on a final result. Once you are happy with the outcome we can begin final production.", + }, + { + number: "04", + title: "Delivery", + description: + "When you're happy and everything is tested we will package and deliver the finished product. This means putting websites live, sending designs to the printers, and handing over new brand guides.", + }, + { + number: "05", + title: "Support", + description: + "Once we've opened the door to your new brand your journey has just begun! If needed we can continue to support you to ensure your brand is applied correctly and is continuously developed.", + }, +]; + export const DesignProcess: React.FC = () => { return (
-

+

Design Process

- - - - - - - - - + {items.map((item, index) => ( + + ))}
); @@ -65,13 +77,13 @@ const Item: React.FC = ({ return (
{number} -

+

{title}

{description}

diff --git a/src/app/services/_components/Expertise.tsx b/src/app/services/_components/Expertise.tsx index d8070ab..bb4b9dd 100644 --- a/src/app/services/_components/Expertise.tsx +++ b/src/app/services/_components/Expertise.tsx @@ -1,32 +1,35 @@ import { TitleAndCopy } from "@/components/TitleAndCopy"; +const items = [ + { + title: "Brand Strategy", + variant: "light" as "dark" | "light", + description: + "Working with businesses to create or improve their identities, creating harmonious and consistent brands on multiple levels by habilitating people to tell their unique story.", + }, + { + title: "Packaging", + variant: "light" as "dark" | "light", + description: + "Moulding your brand to coherent packaging and label design, from studying the design to preparing technical artwork, I create bespoke solutions for primary, secondary and tertiary packaging.", + }, + { + title: "UX/UI & Digital", + variant: "light" as "dark" | "light", + description: + "Whether it's a one-page marketing website, an e-commerce or a launch on social, I have helped clients get all three and know how to take your idea from prototype to the final product.", + }, +]; + export const Expertise: React.FC = () => { return ( -
-
- -

- Working with businesses{"'"} to create or improve their identities, - creating harmonious and consistent brands on multiple levels by - habilitating people to tell their unique story. -

-
- - -

- Moulding your brand to coherent packaging and label design, from - studying the design to preparing technical artwork, I create bespoke - solutions for primary, secondary and tertiary packaging. -

-
- - -

- Whether it{"'"}s a one-page marketing website, an e-commerce or a - launch on social, I have helped clients get all three and know how - to take your idea from prototype to the final product. -

-
+
+
+ {items.map((item, index) => ( + +

{item.description}

+
+ ))}
); diff --git a/src/app/services/_components/GetInTouch.tsx b/src/app/services/_components/GetInTouch.tsx index f217003..2dbbd8b 100644 --- a/src/app/services/_components/GetInTouch.tsx +++ b/src/app/services/_components/GetInTouch.tsx @@ -1,6 +1,9 @@ "use client"; import { motion, Variants } from "framer-motion"; +import Link from "next/link"; + +import { LetsWorkTogether } from "@/components/LetsWorkTogether"; const textVariants: Variants = { offscreen: { @@ -32,35 +35,30 @@ const feedbackVariants: Variants = { }, }; +// const feedbacks = [ +// { +// text: "Beatrice delivered the perfect deliverables, even ahead of schedule! This will definitely not be the last time working with her.", +// author: "Stasha Clerk @ Gulp", +// }, +// ]; + export const GetInTouch: React.FC = () => { return ( - -
-

- Let{"'"}s work together. -

- -
- If you like the look of the projects I{"'"}ve worked on or would - like to collaborate on something together, and would like to get in - touch, I would love to hear from you! Please feel free to book a - call or email me. -
-
+ + - {/* */}

{ return ( -
-
+
+

I{"'"}ll provide an intro of myself and study a project proposal diff --git a/src/app/services/_components/WorthyClients.tsx b/src/app/services/_components/WorthyClients.tsx deleted file mode 100644 index 2c08403..0000000 --- a/src/app/services/_components/WorthyClients.tsx +++ /dev/null @@ -1,76 +0,0 @@ -"use client"; - -import { useEffect } from "react"; -import { useMeasure } from "@uidotdev/usehooks"; -import { animate, motion, useMotionValue } from "framer-motion"; -import Image from "next/image"; - -import babingtonImage from "../../../../public/partner-logos/babingtons.png"; -import berviniImage from "../../../../public/partner-logos/bervini.png"; -import bonaveriImage from "../../../../public/partner-logos/bonaveri.png"; -import bonolloImage from "../../../../public/partner-logos/bonollo.png"; -import buieseImage from "../../../../public/partner-logos/buiese.png"; -import castelloDiSpessaImage from "../../../../public/partner-logos/castello-di-spessa.png"; -import gulpImage from "../../../../public/partner-logos/gulp.png"; -import luisaImage from "../../../../public/partner-logos/luisa.png"; -import ourHutImage from "../../../../public/partner-logos/our-hut.png"; -import saltyCommuneImage from "../../../../public/partner-logos/salty-commune.png"; -import trentinoImage from "../../../../public/partner-logos/trentino.png"; - -const logos = [ - babingtonImage, - berviniImage, - bonaveriImage, - bonolloImage, - buieseImage, - castelloDiSpessaImage, - gulpImage, - luisaImage, - ourHutImage, - saltyCommuneImage, - trentinoImage, -]; - -const FAST_DURATION = 30; - -export const WorthyClients = () => { - let [ref, { width }] = useMeasure(); - const xTranslation = useMotionValue(0); - - useEffect(() => { - if (!width) return; - - const finalPosition = -(width / 2) - 4; - - const controls = animate(xTranslation, [0, finalPosition], { - ease: "linear", - duration: FAST_DURATION, - repeat: Infinity, - repeatType: "loop", - repeatDelay: 0, - }); - - return controls?.stop; - }, [xTranslation, width]); - - return ( -

- - {[...logos, ...logos].map((logo, index) => ( - - logo - - ))} - -
- ); -}; diff --git a/src/app/services/page.tsx b/src/app/services/page.tsx index b6285b6..bc5667f 100644 --- a/src/app/services/page.tsx +++ b/src/app/services/page.tsx @@ -1,12 +1,13 @@ +import { WorthyClients } from "@/components/WorthyClients"; + import { DesignProcess } from "./_components/DesignProcess"; import { Expertise } from "./_components/Expertise"; import { GetInTouch } from "./_components/GetInTouch"; import { WhereToStart } from "./_components/WhereToStart"; -import { WorthyClients } from "./_components/WorthyClients"; export default async function ServicesPage() { return ( -
+
@@ -15,7 +16,7 @@ export default async function ServicesPage() { - {/* */} +
); } diff --git a/src/components/LetsWorkTogether.tsx b/src/components/LetsWorkTogether.tsx new file mode 100644 index 0000000..7b24357 --- /dev/null +++ b/src/components/LetsWorkTogether.tsx @@ -0,0 +1,33 @@ +import Link from "next/link"; + +export const LetsWorkTogether = () => { + return ( +
+

+ Let{"'"}s work together. +

+ +
+ If you like the look of the projects I{"'"}ve worked on or would like to + collaborate on something together, and would like to get in touch, I + would love to hear from you! Please feel free to{" "} + + book a call + {" "} + or{" "} + + {" "} + email me + + . +
+
+ ); +}; diff --git a/src/components/Marquee.tsx b/src/components/Marquee.tsx new file mode 100644 index 0000000..a28aea5 --- /dev/null +++ b/src/components/Marquee.tsx @@ -0,0 +1,132 @@ +// "use client"; + +// import React, { useRef, useEffect } from "react"; +// import { motion, useSpring, useTransform, MotionValue } from "framer-motion"; +// import { useWindowSize } from "@uidotdev/usehooks"; + +// type MarqueeItemProps = { +// children: React.ReactNode; +// speed: MotionValue; +// }; + +// const MarqueeItem: React.FC = (props) => { +// const { children, speed } = props; + +// const itemRef = useRef(null); +// const rectRef = useRef(null); +// const x = useRef(0); +// const { width, height } = useWindowSize(); + +// const setX = () => { +// if (!itemRef.current || !rectRef.current) { +// return; +// } + +// const xPercentage = (x.current / rectRef.current.width) * 100; + +// if (xPercentage < -100) { +// x.current = 0; +// } + +// if (xPercentage > 0) { +// x.current = -rectRef.current.width; +// } + +// itemRef.current.style.transform = `translate3d(${xPercentage}%, 0, 0)`; +// }; + +// useEffect(() => { +// if (itemRef.current) { +// rectRef.current = itemRef.current.getBoundingClientRect(); +// } +// }, [width, height]); + +// const loop = () => { +// //Substracts the current x from the speed set by useSpring +// x.current -= speed.get(); +// setX(); +// }; + +// const [_, loopStart] = useRaf(loop, false); + +// useEffect(() => { +// loopStart(); +// }, []); + +// return ( +// +// {children} +// +// ); +// }; + +// type MarqueeProps = { +// speed?: number; +// threshold?: number; +// wheelFactor?: number; +// dragFactor?: number; +// children: React.ReactNode; +// }; + +// export const InteractiveMarquee: React.FC = (props) => { +// const { speed = 1, threshold = 0.014, children } = props; + +// const marqueeRef = useRef(null); +// const slowDown = useRef(false); + +// const x = useRef(0); +// const { width: wWidth } = useWindowSize(); + +// const speedSpring = useSpring(speed, { +// damping: 40, +// stiffness: 90, +// mass: 5, +// }); + +// const skewX = useTransform( +// speedSpring, +// [-(wWidth || 0) * 0.05, 0, (wWidth || 0) * 0.05], +// [1, 0, 1] +// ); + +// const loop = () => { +// /** +// * Do nothing if we're slowing down +// * or +// * Our x is less than the threshold +// * +// * The threshold basically tells how much to speed up +// * +// * Without this stop - x.current will mutiple expodentially +// */ +// if (slowDown.current || Math.abs(x.current) < threshold) { +// return; +// } + +// /** +// * This portion speeds up the spring until it reaches the `threshold` +// */ +// x.current *= 0.66; + +// if (x.current < 0) { +// x.current = Math.min(x.current, 0); +// } else { +// x.current = Math.max(x.current, 0); +// } + +// //speedSpring sets the speed for the marquee items that gets passed to the item components +// speedSpring.set(speed + x.current); +// }; + +// useRafLoop(loop); + +// return ( +// <> +// {/* */} +// +// {children} +// {children} +// +// +// ); +// }; diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index 141ff29..9428ce4 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -51,10 +51,10 @@ export const Navbar: React.FC = () => { {({ open }: { open: boolean }) => ( <> -
+
- + Beatrice Duguid Cox Logo { viewport={{ once: true, amount: 0.7 }} transition={{ staggerChildren: 0.4 }} > - {LINKS.map(({ label, href, target }) => ( + {LINKS.map(({ label, href }) => ( { > > = ({

{ +// return ( +//
+//
+// +//

+// Let's Work Together. Let's Work Together. Let's Work Together. Let's +// Work Together. Let's Work Together. Let's Work Together. Let's Work +// Together +//

+//
+//
+//
+// ); +// }; + +export const WorthyClients = () => { + let [ref, { width }] = useMeasure(); + const xTranslation = useMotionValue(0); + + useEffect(() => { + if (!width) return; + + const finalPosition = -(width / 2) - 4; + + const controls = animate(xTranslation, [0, finalPosition], { + ease: "linear", + duration: FAST_DURATION, + repeat: Infinity, + repeatType: "loop", + repeatDelay: 0, + }); + + return controls?.stop; + }, [xTranslation, width]); + + return ( +
+ + {[...logos, ...logos].map((logo, index) => ( + + logo + + ))} + +
+ ); +}; diff --git a/src/globals.css b/src/globals.css index 3f218c4..551fc4a 100644 --- a/src/globals.css +++ b/src/globals.css @@ -16,7 +16,7 @@ } .container-x-padding { - @apply px-8 md:px-16 lg:px-32 xl:px-48; + @apply px-8 md:px-16 lg:px-24 3xl:px-48 4xl:px-64; } #editor > p { diff --git a/tailwind.config.js b/tailwind.config.js index 1a36241..bd755e9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -7,7 +7,7 @@ const newColors = { accent: "#B8CDED", secondary: "#B8CDED", link: "#80ED99", - black: "#1E1E1E", + black: "#272727", "light-gray": "#F5F5F5", }; @@ -45,10 +45,17 @@ module.exports = { "50%": { transform: "translateX(3px)" }, }, }, + letterSpacing: { + titles: ".3rem", + }, animation: { wiggle: "wiggle 1s ease-in-out infinite", slide: "slide 1s ease-in-out infinite", }, + screens: { + "3xl": "1600px", + "4xl": "1900px", + }, spacing: { 128: "32rem", 144: "36rem",