diff --git a/.env.example b/.env.example index c0f1740..326f506 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,7 @@ VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX +VITE_BC_NAME=XXX XXXXXXX +VITE_BC_POSITION=XXXXXXXXXX +VITE_BC_VAT=ITXXXXXXXXXX +VITE_BC_PHONE=+39XXXXXXXXXX +VITE_BC_EMAIL=XXXX@XXXX.XX +VITE_BC_LINKEDIN=XXXXXXXXXX diff --git a/public/images/qr.svg b/public/images/qr.svg new file mode 100644 index 0000000..7470ba9 --- /dev/null +++ b/public/images/qr.svg @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/App.tsx b/src/App.tsx index a429bed..3b7fb4f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,6 +10,7 @@ const ProjectsPage = React.lazy(() => import('components/pages/ProjectsPage/inde const CurriculumPage = React.lazy(() => import('components/pages/CurriculumPage/index.js')) const ContactPage = React.lazy(() => import('components/pages/ContactPage/index.js')) const PrivacyPage = React.lazy(() => import('components/pages/PrivacyPage/index.js')) +const BusinessCardPage = React.lazy(() => import('components/pages/BusinessCardPage/index.js')) const router = createBrowserRouter([ { @@ -57,6 +58,14 @@ const router = createBrowserRouter([ ), }, + { + path: 'card', + element: ( + }> + + + ), + }, ], }, ]) diff --git a/src/components/pages/BusinessCardPage/index.css b/src/components/pages/BusinessCardPage/index.css new file mode 100644 index 0000000..1fb5fd5 --- /dev/null +++ b/src/components/pages/BusinessCardPage/index.css @@ -0,0 +1,31 @@ +/* Print styles for business card */ +@media print { + body * { + visibility: hidden; + } + + #main, + #page-content { + margin-bottom: 0; + margin-top: 0; + min-height: 0; + } + + #footer { + display: none; + } + + .print-business-card, + .print-business-card * { + visibility: visible; + } + + .print-business-card { + width: 85mm; + height: 55mm; + } + + @page { + size: 85mm 55mm; + } +} diff --git a/src/components/pages/BusinessCardPage/index.tsx b/src/components/pages/BusinessCardPage/index.tsx new file mode 100644 index 0000000..dcf891f --- /dev/null +++ b/src/components/pages/BusinessCardPage/index.tsx @@ -0,0 +1,192 @@ +import React from 'react' +import { Box, Typography, Stack, Button, Paper, Link, TypographyProps, SvgIcon, PaperProps, ThemeProvider, createTheme } from '@mui/material' +import { Email, LinkedIn, Print, PhoneInTalk, Public } from '@mui/icons-material' + +import { Page } from 'components/templates/index.js' +import typography from 'style/typography/index.js' +import palette from 'style/palette/index.js' +import './index.css' + +const NAME = import.meta.env.VITE_BC_NAME || '[FULL NAME]' +const POSITION = import.meta.env.VITE_BC_POSITION || '[POSITION]' +const VAT = import.meta.env.VITE_BC_VAT || '[VAT NUMBER]' +const PHONE = import.meta.env.VITE_BC_PHONE || '[Redacted for privacy]' +const EMAIL = import.meta.env.VITE_BC_EMAIL || '[Redacted for privacy]' +const LINKEDIN = import.meta.env.VITE_BC_LINKEDIN || '[Redacted for privacy]' + +const TypographyLink = ({ icon: Icon, children, ...props }: TypographyProps) => ( + + + + {children} + + +) + +const theme = { + light: createTheme({ + typography: typography, + palette: palette.light, + }), + dark: createTheme({ + typography: typography, + palette: palette.dark, + }), +} + +type BusinessCardProps = { + mode?: 'light' | 'dark' + src: string + alt?: string +} & PaperProps +const BusinessCard = ({ mode = 'dark', src, alt, sx, ...props }: BusinessCardProps) => ( + + + + + {/* Right side with content */} + + {props.children} + + + +) + +/** + * BusinessCardPage component - A digital business card + * Designed to be printable as a standard business card (3.5 x 2 inches) + */ +const BusinessCardPage = () => { + return ( + + + + + {NAME} + + + {POSITION} + + + + + + + {NAME} + + + {VAT} + + + {PHONE} + + + {EMAIL} + + + www.m-tartari.eu + + + {LINKEDIN} + + + + + + + + + + ) +} + +export default BusinessCardPage diff --git a/src/components/pages/index.ts b/src/components/pages/index.ts index 10e8aab..a296ebb 100644 --- a/src/components/pages/index.ts +++ b/src/components/pages/index.ts @@ -2,5 +2,6 @@ export { default as MainPage } from './MainPage' export { default as ContactPage } from './ContactPage' export { default as CurriculumPage } from './CurriculumPage' export { default as ProjectsPage } from './ProjectsPage' +export { default as BusinessCardPage } from './BusinessCardPage' export { default as ErrorPage } from './ErrorPage' diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index c8142b1..500b864 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -2,6 +2,12 @@ interface ImportMetaEnv { readonly VITE_GA_MEASUREMENT_ID: string + readonly VITE_BC_NAME: string + readonly VITE_BC_POSITION: string + readonly VITE_BC_VAT: string + readonly VITE_BC_PHONE: string + readonly VITE_BC_EMAIL: string + readonly VITE_BC_LINKEDIN: string } interface ImportMeta {