From e5ba1ab65d565eb403160855b7339e028169fd60 Mon Sep 17 00:00:00 2001 From: martapanc Date: Thu, 14 Sep 2023 16:56:16 +0200 Subject: [PATCH 1/3] feat: reorganise header routes --- .../(public)/about/{free-time => }/page.tsx | 0 src/app/(public)/about/work/page.tsx | 108 ------------------ src/app/(public)/cv/cv/page.tsx | 24 ++++ src/app/(public)/cv/page.tsx | 100 ++++++++++++++-- src/components/layout/Header.tsx | 50 +------- .../molecules/MobileMenu/MobileMenu.tsx | 7 +- src/data/locales/en.json | 3 +- src/data/locales/it.json | 4 +- 8 files changed, 123 insertions(+), 173 deletions(-) rename src/app/(public)/about/{free-time => }/page.tsx (100%) delete mode 100644 src/app/(public)/about/work/page.tsx create mode 100644 src/app/(public)/cv/cv/page.tsx diff --git a/src/app/(public)/about/free-time/page.tsx b/src/app/(public)/about/page.tsx similarity index 100% rename from src/app/(public)/about/free-time/page.tsx rename to src/app/(public)/about/page.tsx diff --git a/src/app/(public)/about/work/page.tsx b/src/app/(public)/about/work/page.tsx deleted file mode 100644 index 99a1ac6..0000000 --- a/src/app/(public)/about/work/page.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import Image from 'next/image'; -import * as React from 'react'; -import ReactMarkdown from 'react-markdown'; - -import Heading from '@/components/atoms/headings/Heading'; -import Education from '@/components/organisms/about-work/Education'; -import Intro from '@/components/organisms/about-work/Intro'; -import Languages from '@/components/organisms/about-work/Languages'; -import Publications from '@/components/organisms/about-work/Publications'; -import WorkExperience from '@/components/organisms/about-work/WorkExperience'; - -import { queryJobs } from '@/queries/jobs'; -import { queryLanguages } from '@/queries/languages'; -import { queryPublications } from '@/queries/publications'; -import { querySchools } from '@/queries/schools'; -import { queryIntro } from '@/queries/short-texts'; -import { querySkills } from '@/queries/skills'; - -import { Icon } from '@/types/Icon'; -import { Skill } from '@/types/Skill'; - -export const metadata = { - title: 'About my Work | MartaCodes.it', - description: 'About page', -}; - -const queryData = async () => { - const intro = await queryIntro(); - - const jobs = await queryJobs(); - const languages = await queryLanguages(); - const publications = await queryPublications(); - const schools = await querySchools(); - const skills = await querySkills(); - - return { - intro, - jobs, - languages, - publications, - schools, - skills, - }; -}; - -const AboutPage = async () => { - const { intro, jobs, languages, publications, schools, skills } = - await queryData(); - - const iconDimension = 36; - - return ( -
-
-
- - - - -
- {skills.map((skill: Skill) => ( -
-
- {skill.icons.map((icon: Icon) => ( - {icon.name} - ))} -
- -

{skill.title}

- - - {skill.description} - -
- ))} -
- -
- - - -
- - - -
- - - -
- - -
-
-
- ); -}; - -export default AboutPage; diff --git a/src/app/(public)/cv/cv/page.tsx b/src/app/(public)/cv/cv/page.tsx new file mode 100644 index 0000000..c6f5f93 --- /dev/null +++ b/src/app/(public)/cv/cv/page.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; + +import CvCard from '@/components/organisms/cv/CvCard'; + +export const metadata = { + title: 'CV | MartaCodes.it', + description: 'CV page', +}; + +const CVPage = async () => { + return ( +
+
+
+

CV

+ + +
+
+
+ ); +}; + +export default CVPage; diff --git a/src/app/(public)/cv/page.tsx b/src/app/(public)/cv/page.tsx index c6f5f93..99a1ac6 100644 --- a/src/app/(public)/cv/page.tsx +++ b/src/app/(public)/cv/page.tsx @@ -1,24 +1,108 @@ +import Image from 'next/image'; import * as React from 'react'; +import ReactMarkdown from 'react-markdown'; -import CvCard from '@/components/organisms/cv/CvCard'; +import Heading from '@/components/atoms/headings/Heading'; +import Education from '@/components/organisms/about-work/Education'; +import Intro from '@/components/organisms/about-work/Intro'; +import Languages from '@/components/organisms/about-work/Languages'; +import Publications from '@/components/organisms/about-work/Publications'; +import WorkExperience from '@/components/organisms/about-work/WorkExperience'; + +import { queryJobs } from '@/queries/jobs'; +import { queryLanguages } from '@/queries/languages'; +import { queryPublications } from '@/queries/publications'; +import { querySchools } from '@/queries/schools'; +import { queryIntro } from '@/queries/short-texts'; +import { querySkills } from '@/queries/skills'; + +import { Icon } from '@/types/Icon'; +import { Skill } from '@/types/Skill'; export const metadata = { - title: 'CV | MartaCodes.it', - description: 'CV page', + title: 'About my Work | MartaCodes.it', + description: 'About page', +}; + +const queryData = async () => { + const intro = await queryIntro(); + + const jobs = await queryJobs(); + const languages = await queryLanguages(); + const publications = await queryPublications(); + const schools = await querySchools(); + const skills = await querySkills(); + + return { + intro, + jobs, + languages, + publications, + schools, + skills, + }; }; -const CVPage = async () => { +const AboutPage = async () => { + const { intro, jobs, languages, publications, schools, skills } = + await queryData(); + + const iconDimension = 36; + return (
-
+
-

CV

+ + + + +
+ {skills.map((skill: Skill) => ( +
+
+ {skill.icons.map((icon: Icon) => ( + {icon.name} + ))} +
+ +

{skill.title}

+ + + {skill.description} + +
+ ))} +
+ +
+ + + +
+ + + +
+ + + +
- +
); }; -export default CVPage; +export default AboutPage; diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index b9ef515..d8d4521 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -1,14 +1,10 @@ 'use client'; -import { MenuItem } from '@mui/material'; -import { Menu } from '@mui/material'; -import Link from 'next/link'; import { usePathname } from 'next/navigation'; import * as React from 'react'; import { useEffect, useState } from 'react'; import Headroom from 'react-headroom'; import { useTranslation } from 'react-i18next'; -import { AiFillCaretDown, AiFillCaretUp } from 'react-icons/ai'; import { useOnKeyDown } from '@/hooks/useOnKeyDown'; @@ -23,8 +19,9 @@ import UnstyledLink from '@/components/links/UnstyledLink'; import { MobileMenu } from '@/components/molecules/MobileMenu/MobileMenu'; export const links = [ - { href: '/projects', label: 'headerMenu.projects' }, + { href: '/about', label: 'headerMenu.about' }, { href: '/cv', label: 'headerMenu.cv' }, + { href: '/projects', label: 'headerMenu.projects' }, { href: '/uses', label: 'headerMenu.uses' }, { href: '/contacts', label: 'headerMenu.contact' }, ]; @@ -36,15 +33,6 @@ export default function Header() { const [isOpen, setIsOpen] = useState(false); - const [anchorEl, setAnchorEl] = React.useState(null); - const open = Boolean(anchorEl); - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - const handleClose = () => { - setAnchorEl(null); - }; - const pathname = usePathname(); useEffect(() => { @@ -76,40 +64,6 @@ export default function Header() {
    -
  • - - {t('headerMenu.about')} - {!open && } - {open && } - - - - - 👔 {t('headerMenu.aboutWork')} - - - - - 🪁 {t('headerMenu.aboutFreeTime')} - - - -
  • - {links.map(({ href, label }) => (
  • { const { t } = useTranslation(); - const mobileLinks = [ - { href: '/about/work', label: 'headerMenu.aboutWorkMobile' }, - { href: '/about/free-time', label: 'headerMenu.aboutFreeTimeMobile' }, - ...links, - ]; const navigationVariants = { hidden: { opacity: 0, x: -50 }, visible: (custom: number) => ({ @@ -49,7 +44,7 @@ export const MobileMenu = ({ isOpen }: MobileMenuProps) => { }} >
      - {mobileLinks.map(({ href, label }, i) => ( + {links.map(({ href, label }, i) => ( Date: Thu, 14 Sep 2023 17:53:05 +0200 Subject: [PATCH 2/3] feat: add downloadable CV from Work page --- next.config.js | 9 ++++++ src/app/(public)/about/page.tsx | 2 +- src/app/(public)/cv/cv/page.tsx | 24 ---------------- src/app/(public)/cv/page.tsx | 5 ++++ src/components/organisms/cv/CvCard.tsx | 40 ++++++-------------------- src/data/locales/en.json | 4 ++- src/data/locales/it.json | 15 ++++++---- src/pages/api/cv.pdf.ts | 32 +++++++++++++++++++++ 8 files changed, 67 insertions(+), 64 deletions(-) delete mode 100644 src/app/(public)/cv/cv/page.tsx create mode 100644 src/pages/api/cv.pdf.ts diff --git a/next.config.js b/next.config.js index b97848d..074b341 100644 --- a/next.config.js +++ b/next.config.js @@ -39,6 +39,15 @@ const nextConfig = { }, staticPageGenerationTimeout: 600, + + async rewrites() { + return [ + { + source: '/downloads/cv.pdf', + destination: '/api/cv.pdf', + }, + ]; + }, }; module.exports = nextConfig; diff --git a/src/app/(public)/about/page.tsx b/src/app/(public)/about/page.tsx index 43b02a1..383681e 100644 --- a/src/app/(public)/about/page.tsx +++ b/src/app/(public)/about/page.tsx @@ -109,7 +109,7 @@ const AboutFreeTimePage = async () => {
      -

      Free Time

      +

      About me

      diff --git a/src/app/(public)/cv/cv/page.tsx b/src/app/(public)/cv/cv/page.tsx deleted file mode 100644 index c6f5f93..0000000 --- a/src/app/(public)/cv/cv/page.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from 'react'; - -import CvCard from '@/components/organisms/cv/CvCard'; - -export const metadata = { - title: 'CV | MartaCodes.it', - description: 'CV page', -}; - -const CVPage = async () => { - return ( -

      -
      -
      -

      CV

      - - -
      -
      -
      - ); -}; - -export default CVPage; diff --git a/src/app/(public)/cv/page.tsx b/src/app/(public)/cv/page.tsx index 99a1ac6..09c71f2 100644 --- a/src/app/(public)/cv/page.tsx +++ b/src/app/(public)/cv/page.tsx @@ -8,6 +8,7 @@ import Intro from '@/components/organisms/about-work/Intro'; import Languages from '@/components/organisms/about-work/Languages'; import Publications from '@/components/organisms/about-work/Publications'; import WorkExperience from '@/components/organisms/about-work/WorkExperience'; +import CvCard from '@/components/organisms/cv/CvCard'; import { queryJobs } from '@/queries/jobs'; import { queryLanguages } from '@/queries/languages'; @@ -99,6 +100,10 @@ const AboutPage = async () => {
      + +
      + +
      diff --git a/src/components/organisms/cv/CvCard.tsx b/src/components/organisms/cv/CvCard.tsx index 7a2197e..1babe6d 100644 --- a/src/components/organisms/cv/CvCard.tsx +++ b/src/components/organisms/cv/CvCard.tsx @@ -1,6 +1,5 @@ 'use client'; -import Image from 'next/image'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; import { FaDownload } from 'react-icons/fa'; @@ -10,38 +9,15 @@ import Button from '@/components/buttons/Button'; const CvCard = () => { const { t } = useTranslation(); - const width = 1200; - return ( - <> - - -
      - CV Page 1 - CV Page 2 -
      - + ); }; diff --git a/src/data/locales/en.json b/src/data/locales/en.json index 65489c9..0b191e1 100644 --- a/src/data/locales/en.json +++ b/src/data/locales/en.json @@ -43,7 +43,9 @@ "icon": "https://res.cloudinary.com/dwrurydlt/image/upload/v1692894192/newspaper_e15ec94d21.svg" } }, - "aboutFreeTime": {}, + "about": { + "title": "Su di me" + }, "projects": { "readMore": "Read More" }, diff --git a/src/data/locales/it.json b/src/data/locales/it.json index a4faca4..cd347b2 100644 --- a/src/data/locales/it.json +++ b/src/data/locales/it.json @@ -40,12 +40,15 @@ "publications": { "title": "Pubblicazioni", "icon": "https://res.cloudinary.com/dwrurydlt/image/upload/v1692894192/newspaper_e15ec94d21.svg" - }, - "projects": { - "readMore": "Leggi di più" - }, - "cv": { - "download": "Scarica PDF" } + }, + "about": { + "title": "About me" + }, + "projects": { + "readMore": "Leggi di più" + }, + "cv": { + "download": "Scarica PDF" } } diff --git a/src/pages/api/cv.pdf.ts b/src/pages/api/cv.pdf.ts new file mode 100644 index 0000000..dd90425 --- /dev/null +++ b/src/pages/api/cv.pdf.ts @@ -0,0 +1,32 @@ +/* eslint-disable no-console */ +import { NextApiRequest, NextApiResponse } from 'next'; +import fetch from 'node-fetch'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + try { + const cloudinaryUrl = + 'https://res.cloudinary.com/dwrurydlt/image/upload/v1694634540/Pancaldi_CV_aug23_258811b6b1.pdf'; + + const cloudinaryResponse = await fetch(cloudinaryUrl); + + if (!cloudinaryResponse.ok) { + console.error( + 'Error fetching the PDF from Cloudinary:', + cloudinaryResponse.statusText, + ); + res.status(500).end('Internal Server Error'); + return; + } + + res.setHeader('Content-Type', 'application/pdf'); + res.setHeader('Content-Disposition', 'inline; filename=cv.pdf'); + + cloudinaryResponse.body.pipe(res); + } catch (error) { + console.error('Error:', error); + res.status(500).end('Internal Server Error'); + } +} From 8aa2675e2c8eff074e54c79c997c8649c14da994 Mon Sep 17 00:00:00 2001 From: martapanc Date: Thu, 14 Sep 2023 18:23:28 +0200 Subject: [PATCH 3/3] feat: improve element position on CV page --- src/app/(public)/cv/page.tsx | 2 +- src/components/atoms/headings/SectionHeading.tsx | 2 +- src/components/organisms/about-work/Intro.tsx | 4 +++- src/components/organisms/about-work/Languages.tsx | 4 ++-- src/components/organisms/about-work/Publications.tsx | 8 +++++--- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/app/(public)/cv/page.tsx b/src/app/(public)/cv/page.tsx index 09c71f2..3bb8d65 100644 --- a/src/app/(public)/cv/page.tsx +++ b/src/app/(public)/cv/page.tsx @@ -58,7 +58,7 @@ const AboutPage = async () => { -
      +
      {skills.map((skill: Skill) => (
      { const titleIconDimension = 36; return ( -
      +
      {
      - {intro.content.replace('8', noOfYears)} + + {intro.content.replace('8', noOfYears)} +
      ); diff --git a/src/components/organisms/about-work/Languages.tsx b/src/components/organisms/about-work/Languages.tsx index 960f90c..fd27356 100644 --- a/src/components/organisms/about-work/Languages.tsx +++ b/src/components/organisms/about-work/Languages.tsx @@ -16,11 +16,11 @@ const Languages = ({ languages }: LanguageProps) => {
      -
      +
      {languages.map((language) => (
      {
      -
      +
      {publications.map((publication) => (
      - {publication.title} + + {publication.title} +