♻️ refactor(app): update company assets and references

This commit is contained in:
2026-01-27 16:00:27 +01:00
parent e3b8f6842d
commit d356ffe31c
68 changed files with 266 additions and 1283 deletions
-18
View File
@@ -6,8 +6,6 @@ import RootLayout from 'components/templates/RouteTracker/index.js'
import Loading from 'components/molecules/LoadingScreen/index.js'
const MainPage = React.lazy(() => import('components/pages/MainPage/index.js'))
const ProjectsPage = React.lazy(() => import('components/pages/ProjectsPage/index.js'))
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'))
@@ -26,22 +24,6 @@ const router = createBrowserRouter([
</React.Suspense>
),
},
{
path: 'projects',
element: (
<React.Suspense fallback={<Loading />}>
<ProjectsPage />
</React.Suspense>
),
},
{
path: 'curriculum',
element: (
<React.Suspense fallback={<Loading />}>
<CurriculumPage />
</React.Suspense>
),
},
{
path: 'contacts',
element: (
+5 -5
View File
@@ -4,7 +4,7 @@ import { Box, Link, Stack, Typography } from '@mui/material'
import PolicyIcon from '@mui/icons-material/Policy'
import CookieIcon from '@mui/icons-material/Cookie'
import { EmailIconLink, GitHubIconLink, LinkedInIconLink } from 'components/atoms/IconLinks/index.js'
import { EmailIconLink, InstagramIconLink, FacebookIconLink } from 'components/atoms/IconLinks/index.js'
import CookieConsent from 'components/molecules/CookieConsent/index.js'
type FooterProps = {
@@ -26,13 +26,13 @@ const Footer: React.FC<FooterProps> = ({ showCookieConsent = true }) => {
'@media print': { py: 3 },
}}>
<Stack direction="row" gap={2}>
<LinkedInIconLink fontSize="large" href="https://www.linkedin.com/in/m-tartari/" />
<GitHubIconLink fontSize="large" href="https://www.github.com/m-tartari/" />
<EmailIconLink fontSize="large" href="mailto:info@m-tartari.eu" />
<EmailIconLink fontSize="large" href="mailto:compagniasantoluca@gmail.com" />
<FacebookIconLink fontSize="large" href="https://facebook.com/compagniadarmedelsantoluca/" />
<InstagramIconLink fontSize="large" href="https://www.instagram.com/compagnia_darme_santo_luca/" />
</Stack>
<Typography variant="subtitle2" align="center" color="text.secondary" component="em" mt={3}>
© {year} Michele Tartari. All rights reserved.
© {year} Compagnia d'Arme del Santo Luca. All rights reserved.
</Typography>
<Stack mt={1}>
+20 -22
View File
@@ -2,7 +2,7 @@ import React from 'react'
import { Avatar, Box, IconButton, Stack, Typography } from '@mui/material'
import ExpandMore from '@mui/icons-material/ExpandMore'
import { EmailIconLink, GitHubIconLink, LinkedInIconLink } from 'components/atoms/IconLinks/index.js'
import { EmailIconLink, InstagramIconLink, FacebookIconLink } from 'components/atoms/IconLinks/index.js'
const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) => {
return (
@@ -13,7 +13,7 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
minHeight: '100vh',
boxShadow: '0 0.25em 0.5em 0 rgba(0, 0, 0, 0.25)',
backgroundImage: 'url("images/banner.webp")',
backgroundImage: 'url("images/banner2.webp")',
backgroundPosition: 'center center',
backgroundAttachment: { xs: 'scroll !important', md: 'fixed' },
backgroundSize: 'cover',
@@ -23,10 +23,10 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
wrap: 'wrap',
...(theme.palette.mode === 'dark' && {
backgroundImage: 'url("images/banner-blur.webp")',
backgroundImage: 'url("images/banner2.png")',
}),
...(theme.palette.mode === 'light' && {
backgroundImage: 'url("images/banner.webp")',
backgroundImage: 'url("images/banner2.png")',
'&::before': {
content: '""',
position: 'absolute',
@@ -66,35 +66,33 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
},
})}>
<Box>
<Typography variant="h1">
Robotics
<br /> Engineer
</Typography>
<Typography
variant="h6"
color="text.secondary"
sx={{
color: t => (t.palette.mode === 'light' ? 'inherit' : 'text.secondary'),
margin: '0.5em 0 0 0',
pt: 1,
}}>
Discover some of my works below.
<br /> Send a message to get in touch.
<Typography component="h1" variant="h1" maxWidth="md">
Compagnia d'Arme{' '}
<Typography component="small" variant="h2">
del
</Typography>{' '}
Santo Luca
</Typography>
<Typography variant="h3">Ferrara</Typography>
<Stack
direction="row"
gap={2}
mt={2}
justifyContent={{ xs: 'center', md: 'end' }}
color={t => (t.palette.mode === 'light' ? 'inherit' : 'text.secondary')}>
<LinkedInIconLink fontSize="large" href="https://www.linkedin.com/in/m-tartari/" />
<GitHubIconLink fontSize="large" href="https://www.github.com/m-tartari/" />
<EmailIconLink fontSize="large" href="mailto:info@m-tartari.eu" />
<EmailIconLink fontSize="large" sx={{ ':hover': { color: 'text.primary' } }} href="mailto:compagniasantoluca@gmail.com" />
<FacebookIconLink fontSize="large" sx={{ ':hover': { color: 'text.primary' } }} href="https://facebook.com/compagniadarmedelsantoluca/" />
<InstagramIconLink
fontSize="large"
sx={{ ':hover': { color: 'text.primary' } }}
href="https://www.instagram.com/compagnia_darme_santo_luca/"
/>
</Stack>
</Box>
<Avatar
alt="Avatar"
src="images/me.jpg"
src="logo.png"
variant="square"
sx={{
display: 'inline-block',
verticalAlign: 'middle',
@@ -24,8 +24,9 @@ const PrivacyPolicy: React.FC = () => {
<SectionSubheader>Introduction</SectionSubheader>
<Typography component="p" color="textSecondary">
m-tartari ("we", "our", or "us") respects your privacy and is committed to protecting your personal data. This privacy policy will inform you
about how we look after your personal data when you visit our website and tell you about your privacy rights and how the law protects you.
Compagnia d'Arme del Santo Luca ("we", "our", or "us") respects your privacy and is committed to protecting your personal data. This privacy
policy will inform you about how we look after your personal data when you visit our website and tell you about your privacy rights and how
the law protects you.
</Typography>
<SectionSubheader sx={{ mt: 4 }}>The Data We Collect About You</SectionSubheader>
@@ -101,8 +102,8 @@ const PrivacyPolicy: React.FC = () => {
<SectionSubheader sx={{ mt: 4 }}>Contact Us</SectionSubheader>
<Typography component="p" color="textSecondary">
If you have any questions about this privacy policy or our privacy practices, please contact us at{' '}
<Link color="textPrimary" href="mailto:privacy@m-tartari.eu" target="_blank" rel="noopener noreferrer">
privacy@m-tartari.eu
<Link color="textPrimary" href="mailto:compagniasantoluca@gmail.com" target="_blank" rel="noopener noreferrer">
compagniasantoluca@gmail.com
</Link>
.
</Typography>
@@ -10,7 +10,7 @@ type AnchorType = 'left' | 'top' | 'right' | 'bottom'
type Props = {
image: string
title: string
caption: React.ReactNode
caption?: React.ReactNode
children: React.ReactNode
mobileImage?: string
ref?: React.ForwardedRef<HTMLSelectElement>
@@ -30,7 +30,7 @@ const Description = (props: Props) => {
justifyContent: 'center',
position: 'absolute',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(230, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(155, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backdropFilter: 'blur(8px)',
bottom: '0',
@@ -57,7 +57,7 @@ const Description = (props: Props) => {
display: 'flex',
position: 'absolute',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(230, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(155, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backdropFilter: 'blur(8px)',
top: '0',
ml: 'auto',
@@ -86,7 +86,7 @@ const Description = (props: Props) => {
height: '102%',
width: '28em',
position: 'absolute',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(230, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(155, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backdropFilter: 'blur(8px)',
right: '0',
borderLeftWidth: theme.spacing(0.5),
@@ -108,7 +108,7 @@ const Description = (props: Props) => {
height: '102%',
width: '28em',
position: 'absolute',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(230, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(155, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backdropFilter: 'blur(8px)',
left: '0',
borderRightWidth: theme.spacing(0.5),
+26 -21
View File
@@ -74,8 +74,15 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
textAlign: 'center',
...(theme.palette.mode === 'light' && { backgroundColor: 'background.default' }),
})}>
<Typography variant="h6" sx={{ my: 2 }}>
Michele Tartari
<Typography
variant="h6"
sx={{
// fontFamily: '"Cloister Black", cursive',
textAlign: 'left',
m: 2,
}}>
Compagnia d'Arme <small>del</small>
<br /> Santo Luca
</Typography>
<Divider />
<List>
@@ -84,19 +91,14 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
<ListItemText primary="Home" />
</DrawerButton>
</ListItem>
<ListItem key="Projects" disablePadding>
<DrawerButton component={RouterLink} to="/projects">
<ListItemText primary="Projects" />
<ListItem key="Personaggi" disablePadding>
<DrawerButton component={RouterLink} to="/people">
<ListItemText primary="Personaggi" />
</DrawerButton>
</ListItem>
<ListItem key="Curriculum" disablePadding>
<DrawerButton component={RouterLink} to="/curriculum">
<ListItemText primary="Curriculum" />
</DrawerButton>
</ListItem>
<ListItem key="Contacts" disablePadding>
<ListItem key="Contatti" disablePadding>
<DrawerButton component={RouterLink} to="/contacts">
<ListItemText primary="Contacts" />
<ListItemText primary="Contatti" />
</DrawerButton>
</ListItem>
</List>
@@ -112,7 +114,7 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
backgroundColor: 'transparent',
'@media print': { backgroundColor: 'background.default' },
...(trigger && {
backgroundColor: 'hsla(230, 18%, 13%, 0.75)',
backgroundColor: 'hsla(155, 18%, 13%, 0.75)',
backdropFilter: 'blur(8px)',
boxShadow: theme.shadows[4],
}),
@@ -134,7 +136,6 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
// [theme.breakpoints.up('md')]: { width: theme => theme.breakpoints.values.lg, mx: 'auto' },
}}>
<IconButton
color="primary"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
@@ -154,14 +155,13 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
[theme.breakpoints.down('md')]: { mx: 'auto' },
[theme.breakpoints.up('md')]: { mr: 'auto' },
})}>
Michele Tartari
Compagnia d'Arme del Santo Luca
</AppBarLink>
<Stack component="div" direction="row" spacing={2} sx={{ display: { xs: 'none', md: 'flex', alignItems: 'center' } }}>
<AppBarLink to="/">Home</AppBarLink>
<AppBarLink to="/projects">Projects</AppBarLink>
<AppBarLink to="/curriculum">Curriculum</AppBarLink>
<AppBarLink to="/people">Personaggi</AppBarLink>
<Button component={RouterLink} to="/contacts" color="primary" variant="contained" sx={{ textTransform: 'none' }}>
<Typography variant="h6">Hire me</Typography>
<Typography variant="h6">Contattaci</Typography>
</Button>
</Stack>
</Toolbar>
@@ -173,10 +173,15 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
sx={{
sx={theme => ({
display: { xs: 'block', md: 'none' },
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
}}>
'& .MuiDrawer-paper': {
boxSizing: 'border-box',
width: drawerWidth,
backgroundColor: theme.palette.mode === 'dark' ? 'hsla(155, 18%, 13%, 0.85)' : 'hsla(0, 0%, 100%, 0.75)',
backdropFilter: 'blur(8px)',
},
})}>
{drawer}
</Drawer>
</>
@@ -12,7 +12,7 @@ vi.mock('./envVars.js', () => ({
VAT: 'Test VAT',
PHONE: '+123456789',
EMAIL: 'test@example.com',
LINKEDIN: 'testlinkedin',
FACEBOOK: 'testfacebook',
}))
// Mock window.print
@@ -59,7 +59,7 @@ describe('BusinessCardPage', () => {
const websiteLink = screen.getByText('www.m-tartari.eu').closest('a')
expect(websiteLink).toHaveAttribute('href', 'https://www.m-tartari.eu')
// Check LinkedIn link
// Check Facebook Link
const linkedinLink = screen.getByText('testlinkedin').closest('a')
expect(linkedinLink).toHaveAttribute('href', 'https://www.linkedin.com/in/testlinkedin/')
})
@@ -1,7 +1,7 @@
/* istanbul ignore file */
export const NAME = import.meta.env.VITE_BC_NAME || '[FULL NAME]'
export const POSITION = import.meta.env.VITE_BC_POSITION || '[POSITION]'
export const VAT = import.meta.env.VITE_BC_VAT || '[VAT NUMBER]'
export const PHONE = import.meta.env.VITE_BC_PHONE || '[Redacted for privacy]'
export const POSITION = import.meta.env.VITE_BC_POSITION || 'Ass. di rievocazione storica affiliata C.E.R.S. (XIV-XV secolo)'
export const PHONE = import.meta.env.VITE_BC_PHONE || null
export const EMAIL = import.meta.env.VITE_BC_EMAIL || '[Redacted for privacy]'
export const LINKEDIN = import.meta.env.VITE_BC_LINKEDIN || '[Redacted for privacy]'
export const FACEBOOK = import.meta.env.VITE_BC_FACEBOOK || 'compagniadarmedelsantoluca'
export const INSTAGRAM = import.meta.env.VITE_BC_INSTAGRAM || 'compagnia_darme_santo_luca'
+33 -19
View File
@@ -1,5 +1,19 @@
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 {
Box,
Typography,
Stack,
Button,
Paper,
Link,
TypographyProps,
SvgIcon,
PaperProps,
ThemeProvider,
createTheme,
SxProps,
Theme,
} from '@mui/material'
import { Email, Facebook, Print, PhoneInTalk, Public, Instagram } from '@mui/icons-material'
import { Page } from 'components/templates/index.js'
import typography from 'style/typography/index.js'
@@ -43,8 +57,9 @@ type BusinessCardProps = {
mode?: 'light' | 'dark'
src: string
alt?: string
srcSx?: SxProps<Theme>
} & PaperProps
const BusinessCard = ({ mode = 'dark', src, alt, sx, ...props }: BusinessCardProps) => (
const BusinessCard = ({ mode = 'dark', src, srcSx, alt, sx, ...props }: BusinessCardProps) => (
<ThemeProvider theme={theme[mode]}>
<Paper
className="print-business-card"
@@ -85,6 +100,7 @@ const BusinessCard = ({ mode = 'dark', src, alt, sx, ...props }: BusinessCardPro
height: 'fit-content',
objectFit: 'cover',
// borderRadius: '50%',
...srcSx,
}}
/>
@@ -119,14 +135,7 @@ const BusinessCardPage = () => {
gap: 0,
},
}}>
<BusinessCard src="/fav-icon.svg" alt="logo">
<Typography variant="h5" component="h1" fontFamily="Oswald, sans-serif" textTransform="uppercase" fontWeight={700}>
{env.NAME}
</Typography>
<Typography variant="subtitle2" color="text.secondary" sx={{ fontSize: '0.55rem', mb: 0.5 }}>
{env.POSITION}
</Typography>
</BusinessCard>
<BusinessCard src="/logo_text.png" alt="logo" srcSx={{ width: '100%' }} />
<BusinessCard src="/images/qr.svg" alt="Qr Code" mode="light">
<Stack
@@ -146,19 +155,24 @@ const BusinessCardPage = () => {
{env.NAME}
</Typography>
<Typography variant="caption" color="text.secondary" fontSize="0.55rem" mb={0.5}>
{env.VAT}
{env.POSITION}
</Typography>
<TypographyLink icon={PhoneInTalk} href={`tel:${env.PHONE.replace(/[^\d+]/g, '').replace(/^\+?/, '+')}`}>
{env.PHONE}
</TypographyLink>
{env.PHONE != null && (
<TypographyLink icon={PhoneInTalk} href={`tel:${env.PHONE.replace(/[^\d+]/g, '').replace(/^\+?/, '+')}`}>
{env.PHONE}
</TypographyLink>
)}
<TypographyLink icon={Email} href={`mailto:${env.EMAIL}`}>
{env.EMAIL}
</TypographyLink>
<TypographyLink icon={Public} href="https://www.m-tartari.eu">
www.m-tartari.eu
<TypographyLink icon={Public} href="https://www.compagniadarmedelsantoluca.it/">
www.compagniadarmedelsantoluca.it
</TypographyLink>
<TypographyLink icon={LinkedIn} href={`https://www.linkedin.com/in/${env.LINKEDIN}/`}>
{env.LINKEDIN}
<TypographyLink icon={Facebook} href={`https://facebook.com/${env.FACEBOOK}/`}>
@{env.FACEBOOK}
</TypographyLink>
<TypographyLink icon={Instagram} href={`https://www.instagram.com/${env.INSTAGRAM}/`}>
@{env.INSTAGRAM}
</TypographyLink>
</Stack>
</BusinessCard>
@@ -17,22 +17,22 @@ describe('ContactPage', () => {
expect(screen.getAllByText('Contacts')).toHaveLength(2) // Page title and the Appbar drawer link
expect(screen.getByLabelText('Email link')).toBeInTheDocument()
expect(screen.getByLabelText('LinkedIn link')).toBeInTheDocument()
expect(screen.getByLabelText('GitHub link')).toBeInTheDocument()
expect(screen.getByLabelText('Facebook Link')).toBeInTheDocument()
expect(screen.getByLabelText('Instagram link')).toBeInTheDocument()
})
test.each([
{
label: 'Email link',
href: 'mailto:info@m-tartari.eu',
href: 'mailto:compagniasantoluca@gmail.com',
},
// {
// label: 'LinkedIn link',
// href: 'https://www.linkedin.com/in/m-tartari/',
// label: 'Facebook Link',
// href: 'https://facebook.com/compagniadarmedelsantoluca/',
// },
// {
// label: 'GitHub link',
// href: 'https://www.github.com/m-tartari/',
// label: 'Instagram link',
// href: 'https://www.instagram.com/compagnia_darme_santo_luca/',
// },
])('leads to the right place when the $label is clicked', ({ label, href }) => {
render(<ContactPage />)
@@ -1,7 +1,7 @@
import { Link, List, ListItem, Stack, Typography } from '@mui/material'
import DraftsIcon from '@mui/icons-material/Drafts'
import LinkedInIcon from '@mui/icons-material/LinkedIn'
import GitHubIcon from '@mui/icons-material/GitHub'
import FacebookIcon from '@mui/icons-material/Facebook'
import Instagram from '@mui/icons-material/Instagram'
import { Page } from 'components/templates/index.js'
@@ -39,29 +39,29 @@ const ListItemLink: React.FC<ListItemProps> = ({ children, ...props }) => (
const ContactPage = () => {
return (
<Page title="Contacts">
<Page title="Contatti">
<Typography align="left" variant="h6">
Feel free to contact me using any of the following:
Sentiti libero di contattatarci con uno qualsiasi dei seguenti:
</Typography>
<List>
<ListItemLink href="mailto:info@m-tartari.eu" aria-label="Email link">
<ListItemLink href="mailto:compagniasantoluca@gmail.com" aria-label="Email link">
<DraftsIcon fontSize="large" />
<Typography variant="h6" ml={2}>
info
compagniasantoluca
<wbr />
@m-tartari.eu
@gmail.com
</Typography>
</ListItemLink>
<ListItemLink aria-label="LinkedIn link" href="https://www.linkedin.com/in/m-tartari/">
<LinkedInIcon fontSize="large" />
<ListItemLink aria-label="Facebook Link" href="https://facebook.com/compagniadarmedelsantoluca">
<FacebookIcon fontSize="large" />
<Typography variant="h6" ml={2}>
m-tartari
@compagniadarmedelsantoluca
</Typography>
</ListItemLink>
<ListItemLink aria-label="GitHub link" href="https://www.github.com/m-tartari/">
<GitHubIcon fontSize="large" />
<ListItemLink aria-label="Instagram link" href="https://www.instagram.com/compagnia_darme_santo_luca/">
<Instagram fontSize="large" />
<Typography variant="h6" ml={2}>
m-tartari
@compagnia_darme_santo_luca
</Typography>
</ListItemLink>
</List>
@@ -1,100 +0,0 @@
import { screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { useAnalytics } from 'use-analytics'
import { renderWithRouter as render } from 'components/utils/tests'
import CurriculumPage from './index.js'
vi.stubGlobal('open', vi.fn())
vi.mock('use-analytics', () => ({
useAnalytics: () => ({ plugins: { enable: vi.fn(), disable: vi.fn() } }),
}))
describe('Curriculum component', () => {
const open = vi.spyOn(window, 'open')
test('renders without crashing', () => {
render(<CurriculumPage />)
expect(screen.getAllByText('Curriculum')).toHaveLength(3) // title, appbar button and appbar drawer button
})
test('displays the correct work experience', () => {
render(<CurriculumPage />)
expect(screen.getByText('Work Experience')).toBeInTheDocument()
// check some of the positions
expect(screen.getAllByText('Software Engineer')).toHaveLength(2) // large and smallscreen versions
expect(screen.getAllByText('Embedded Engineer')).toHaveLength(2) // large and smallscreen versions
})
test('displays the correct education', async () => {
render(<CurriculumPage />)
// Education
expect(screen.getByText('Education')).toBeInTheDocument()
// check the subsections links
let link = screen.getByText('EMARO+ Program - Master Studies')
expect(link).toHaveAttribute('href', 'https://master-emaro.ec-nantes.fr/')
expect(link).toHaveAttribute('rel', 'noopener noreferrer')
expect(link).toHaveAttribute('target', '_blank')
link = screen.getByText('Almatong Project - Bachelor Studies')
expect(link).toHaveAttribute('href', 'https://corsi.unibo.it/2cycle/AutomationEngineering/almatong-bachelor-programme')
expect(link).toHaveAttribute('rel', 'noopener noreferrer')
expect(link).toHaveAttribute('target', '_blank')
// check some of the entries
expect(screen.getAllByText('M.Eng. in Robotics and Control')).toHaveLength(2) // large and smallscreen versions
expect(screen.getAllByText('M.S. in Robotics and Control Engineering')).toHaveLength(2) // large and smallscreen versions
expect(screen.getAllByText('B.S. in Control Theory and Control Engineering')).toHaveLength(2) // large and smallscreen versions
})
test('displays the correct skills', () => {
render(<CurriculumPage />)
expect(screen.getByText('Skills')).toBeInTheDocument()
// check the subsection titles
expect(screen.getByText('Languages')).toBeInTheDocument()
expect(screen.getByText('Digital')).toBeInTheDocument()
expect(screen.getByText('Softskills')).toBeInTheDocument()
})
test('displays the correct accomplishments', async () => {
render(<CurriculumPage />)
expect(screen.getByText('Accomplishments')).toBeInTheDocument()
// check some of the awards
expect(screen.getByText('Awards')).toBeInTheDocument()
expect(screen.getByText('Premio Innovazione Robotica ed Automazione - Horizon')).toBeInTheDocument()
// check some of the press releases
expect(screen.getByText('Press Releases')).toBeInTheDocument()
await userEvent.click(screen.getByText("Covid-19: L'impatto sui giovani talenti"))
expect(open).toHaveBeenCalledWith('https://www.youtube.com/watch?v=Blat-e2Vyzk&feature=youtu.be', '_blank')
// check some of the certifications
expect(screen.getByText('Publications')).toBeInTheDocument()
expect(screen.getByText('Control System Design for Human Assisting Robot')).toBeInTheDocument()
})
test('displays the correct extracurricular activites', () => {
render(<CurriculumPage />)
expect(screen.getByText('Extracurricular')).toBeInTheDocument()
// check some of the activities
expect(screen.getByText('Volunteering')).toBeInTheDocument()
expect(screen.getByText('Blood Donor, Bone Marrow Donor at AVIS & ADMO')).toBeInTheDocument()
// check some of the hobbies
expect(screen.getByText('Interests')).toBeInTheDocument()
expect(screen.getByText('Ju-jitsu')).toBeInTheDocument()
})
})
@@ -1,435 +0,0 @@
import { Box, Divider, Link, Stack, Table, TableBody, TableCell, TableRow, Typography } from '@mui/material'
import { Award, ExternalIconLink, Extracurricular, Publication, SectionHeader, SectionSubheader } from 'components/atoms/index.js'
import { CurriculumItem } from 'components/molecules/index.js'
import { Page } from 'components/templates/index.js'
const Curriculum = () => {
return (
<Page title="Curriculum">
<Box component="section" id="work">
<SectionHeader>Work Experience</SectionHeader>
{/* id="selfemployed-software" */}
<CurriculumItem title="Software Engineering Consultant" dates="04/24 - Today" company="Self-Employed" location="Remote">
<Typography component="ul" sx={{ paddingLeft: '1em', marginTop: 0 }}>
<li>
Design and development of customized graphical interfaces and software components to facilitate the use of robots and industrial
machines.
</li>
<li>Production and maintenance of revisions of the documentation.</li>
<li>Providing technical assistance for R&D activities.</li>
</Typography>
</CurriculumItem>
{/* id="MinHub-lead" */}
<CurriculumItem title="Business Partner & Technical Lead" dates="03/23 - 12/24" company="MindHub Ferrara" location="Ferrara, Italy">
<Typography component="div">
Co-founded{' '}
<Link
target="_blank"
rel="noopener noreferrer"
// href="https://www.facebook.com/profile.php?id=61550278936416"
// href="https://mind-hub.it/contact-hall/mindhub-ferrara/"
href="https://www.linkedin.com/company/mindhub-ferrara/">
MindHub Ferrara
</Link>
, the first programming school for children in Ferrara, under the{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://mind-hub.it/">
MindHub Academy franchise
</Link>
, dedicated to teaching programming fundamentals and enhancing logical and analytical skills. My duties include:
<ul style={{ paddingLeft: '1em', marginTop: 0 }}>
<li>Selecting and validating the hardware, the software, and the curriculum taught at our hall.</li>
<li>Supporting the hiring process and training of instructors and teachers.</li>
<li>Providing technical assistance for educational activities.</li>
</ul>
</Typography>
</CurriculumItem>
{/* id="IIT-software" */}
<CurriculumItem title="Software Engineer" dates="06/21 - 04/24" company="Istituto Italiano di Tecnologia" location="Remote">
<Typography component="div">
Worked in{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://web.archive.org/web/20220706131402/https://alberobotics.it/">
Alberobotics
</Link>
: a technology transfer project within the{' '}
<Link
target="_blank"
rel="noopener noreferrer"
href="assets/archive/iit-hhcm/www.iit.it/it/web/humanoids-human-centered-mechatronics.html">
Humanoid and Human Centred Mechatronics (HHCM) Research Line
</Link>{' '}
of the Italian Institute of Technology (IIT). My duties included:
<ul style={{ paddingLeft: '1em', marginTop: 0 }}>
<li>developing customized graphical interfaces and front-end/back-end software components to facilitate the use of robots.</li>
<li>evaluating, integrating, and maintaining perception systems for the development of new use cases and demonstrators.</li>
<li>
participating in the company stands at trade fairs and interacting with potential investors for the promotion of our project and
robot.
</li>
<li>producing and maintaining revisions of documentation.</li>
<li>providing technical assistance for research activities.</li>
</ul>
</Typography>
</CurriculumItem>
{/* id="IIT-embedded" */}
<CurriculumItem title="Embedded Engineer" dates="04/20 - 06/21" company="Istituto Italiano di Tecnologia" location="Genoa, Italy">
<Typography component="div">
Worked in{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://web.archive.org/web/20220706131402/https://alberobotics.it/">
Alberobotics
</Link>
: a technology transfer project within the{' '}
<Link
target="_blank"
rel="noopener noreferrer"
href="assets/archive/iit-hhcm/www.iit.it/it/web/humanoids-human-centered-mechatronics.html">
Humanoid and Human Centred Mechatronics (HHCM) Research Line
</Link>{' '}
of the Italian Institute of Technology (IIT). My duties included:
<ul style={{ paddingLeft: '1em', marginTop: 0 }}>
<li>developing tests and procedures for the automatic calibration of EtherCAT actuators and robotic modules.</li>
<li>developing a suite of tests for the evaluation of prototypes' hardware and firmware.</li>
<li>developing firmware for electronic boards associated with customized sensing.</li>
<li>producing and maintaining revisions of documentation.</li>
<li>providing technical assistance for research activities.</li>
</ul>
</Typography>
</CurriculumItem>
{/* id="WUT-intern" */}
<CurriculumItem
title="Researcher - Internship"
dates="01/19 - 06/19"
company="Warsaw University of Technology - Division of Theory of Machines and Robots"
location="Warsaw, Poland">
<Typography component="div">
My main duties included:
<ul style={{ paddingLeft: '1em', marginTop: 0 }}>
<li>Developing a voice interface and some user detection strategies for low-power robotic systems using ROS.</li>
<li>Developing a robotic setup for educational purposes.</li>
<li>Updating older robotics equipment.</li>
</ul>
</Typography>
</CurriculumItem>
{/* id="WUT-intern" */}
<CurriculumItem title="Researcher - Internship" dates="01/17 - 02/17" company="LAR - University of Bologna" location="Bologna, Italy">
<Typography component="div">
My main duties included:
<ul style={{ paddingLeft: '1em', marginTop: 0 }}>
<li>Developing a setup to control a shape memory alloy material using an embedded PC (a Beagle Bone Black).</li>
<li>Developing two X20 PLC systems to control synchronous motors connected to flexible joints.</li>
<li>Implementating the control logic using Matlab and Automation Studio.</li>
</ul>
</Typography>
</CurriculumItem>
<Divider sx={{ mt: 4, mb: 4 }} />
<SectionHeader>Education</SectionHeader>
<SectionSubheader fontWeight={300}>Certifications</SectionSubheader>
{/* id="WUT" */}
<CurriculumItem title="IBM Full Stack Software Developer Professional Certificate" dates="03/24">
<Stack direction="row" alignItems="center" gap={0.5}>
<Typography>Credential ID: EZ34GWQLRHEG</Typography>
<ExternalIconLink fontSize="inherit" href="https://www.coursera.org/account/accomplishments/professional-cert/EZ34GWQLRHEG" />
</Stack>
</CurriculumItem>
<SectionSubheader fontWeight={300} mt={2}>
<Link
rel="noopener noreferrer"
target="_blank"
underline="hover"
href="https://master-emaro.ec-nantes.fr/"
sx={{
color: 'inherit',
cursor: 'pointer',
}}>
EMARO+ Program - Master Studies
</Link>
</SectionSubheader>
{/* id="WUT" */}
<CurriculumItem
title="M.Eng. in Robotics and Control"
company="Warsaw University of Technology"
// (grade: 5/5,summa cum laude)
location="Warsaw, Poland"
dates="09/18 - 06/19">
<Typography component="ul" sx={{ paddingLeft: '1em', marginTop: 0 }}>
<li>Consortium scholarship issued for EMARO+ students based on academic merits and offered to top applicants only.</li>
<li>Relevant courses: Research Methodology, Bio-Robotics, Dynamics of Multi-Body Systems, Advanced Mechanical Design.</li>
<li>Other relevant courses: 2 exams of Polish language and 1 of Polish culture.</li>
<li>
Thesis:{' '}
<Link
target="_blank"
rel="noopener noreferrer"
href="https://drive.google.com/drive/folders/1Y7TJJN8z1llCkSTnpVHMELD3PqsX8VF9?usp=sharing">
Voice Controlled Mobile Robot for Indoor Applications
</Link>{' '}
(research publication available{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://doi.org/10.1007/978-3-030-58380-4_7">
<em>here</em>
</Link>
).
</li>
</Typography>
</CurriculumItem>
{/* id="ECN" */}
<CurriculumItem
title="M.S. in Robotics and Control Engineering"
company="Ecole Centrale de Nantes"
location="Nantes, France"
dates="09/17 - 06/18">
<Typography component="ul" sx={{ paddingLeft: '1em', marginTop: 0 }}>
<li>Consortium scholarship issued for EMARO+ students based on academic merits and offered to top applicants only.</li>
<li>
Relevant courses: Mobile Robotics, Non-linear Control Theory, Software Architecture for Robotics, Artificial Intelligence, Computer
Vision, Real Time Systems, Mechanical Design Methods in Robotics, Optimization Techniques.
</li>
<li>Other relevant courses: 2 exams of French language.</li>
<li>
Project:{' '}
<Link
target="_blank"
rel="noopener noreferrer"
href="https://drive.google.com/file/d/1wBfvAzy9N8uChNxNj9Kd_hcvI0Qq3uQj/view?usp=sharing">
Recharging electric cars with a mobile robot
</Link>
.
</li>
</Typography>
</CurriculumItem>
<SectionSubheader fontWeight={300} mt={2}>
<Link
rel="noopener noreferrer"
target="_blank"
underline="hover"
href="https://corsi.unibo.it/2cycle/AutomationEngineering/almatong-bachelor-programme"
sx={{
color: 'inherit',
cursor: 'pointer',
}}>
Almatong Project - Bachelor Studies
</Link>
</SectionSubheader>
{/* id="TJ" */}
<CurriculumItem
title="B.S. in Control Theory and Control Engineering"
company="Tongji Univeristy"
// (grade: 5/5)
location="Shanghai, China"
dates="09/14 - 06/17">
<Typography component="ul" sx={{ paddingLeft: '1em', marginTop: 0 }}>
<li>Relevant courses: Automation Controls, Electrical Circuit, Logical Design of Digital Systems.</li>
<li>Other relevant courses: 2 Exams about Chinese Language and 3 Exams about Chinese Culture.</li>
<li>
Thesis:{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://drive.google.com/file/d/0B1z42QMR-0UtYzBYSVhRV3ZPWk0/view?usp=sharing">
Solar Panel Fault Detection Method Based on Infrared Image Processing
</Link>
.
</li>
</Typography>
</CurriculumItem>
{/* id="UniBo" */}
<CurriculumItem
title="B.S. in Automation Engineering"
company="Alma Mater Studiorum - University of Bologna"
location="Bologna, Italy"
//(grade: 102/110)
dates="09/13 - 12/16">
<Typography component="ul" sx={{ paddingLeft: '1em', marginTop: 0 }}>
<li>Scholarship issued for Almatong Project student based on academic merits and offered to top applicants only.</li>
<li>Relevant courses: Foundation of Industrial Robotics, Automatic Machines, Computer Architectures.</li>
<li>Other relevant courses: 2 exams of French language.</li>
<li>
Thesis:{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://drive.google.com/file/d/0B1z42QMR-0UtSkxRVzJPTk1IX0k/view?usp=sharing">
Design of a Testing Machine for Flexure Hinges
</Link>
.
</li>
</Typography>
</CurriculumItem>
<SectionSubheader fontWeight={300} mt={2}>
High School Studies
</SectionSubheader>
{/* id="Roiti" */}
<CurriculumItem
title="Scientific High School Diploma"
company="Liceo scientifico “Antonio Roiti”"
location="Ferrara, Italy"
// (grade: 92/100)
dates="09/08 - 06/13">
<Typography>
Liceo scientifico “Antonio Roiti” is a public high school in Ferrara, Italy. There I followed a P.N.I. specialism (“National Plan of
Computer studies”). This curriculum is devised by the Ministry of Education, and emphasises the link between the humanistic tradition and
scientific culture. It covers a complete and widespread range of disciplines, including Italian language and literature, mathematics,
physics, chemistry, biology, history, philosophy, Latin language and culture, English language and culture, art history and technical
drawing. At the end of the fifth year all students sit for the esame di Stato, a final examination which leads to the maturità
scientifica.
<br />
The school website can be found{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://www.liceoroiti.edu.it">
here
</Link>
.
</Typography>
</CurriculumItem>
{/* id="EMHS" */}
<CurriculumItem title="Foreign Exchange Student Program" company="El Modena High School" dates="09/11 - 06/12" location="California, US">
<Typography>
El Modena High School is a traditional 4 year public high school located in the El Modena neighborhood in the eastern portion of the city
of Orange in Orange County, California. I studied there as a senior year stundent through a foreign exchange student program. <br />
The school website can be found{' '}
<Link target="_blank" rel="noopener noreferrer" href="https://www.elmodenahs.org/">
here
</Link>
.
</Typography>
</CurriculumItem>
<Divider sx={{ mt: 4, mb: 4 }} />
<SectionHeader>Skills</SectionHeader>
<Table>
<TableBody>
<TableRow>
<TableCell width="15%">
<Typography variant="h6" component="b" fontWeight={600}>
Languages
</Typography>
</TableCell>
<TableCell width="85%">Italian (Native Speaker), English (Proficient, IELTS 7.5), French (Good), Chinese (Basic, HSK3)</TableCell>
</TableRow>
<TableRow>
<TableCell rowSpan={4} width="15%" id="digital_skills">
<Typography variant="h6" component="b" fontWeight={600}>
Digital
</Typography>
</TableCell>
<TableCell width="85%">
<b>Languages:</b> TypeScript/Javascript (Proficient), Python (Proficient), Bash (Good), C++ (Good), C (Fair)
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<b>Softwares:</b> git (Proficient), Matlab (Good), LaTeX (Good), CATIA (Fair)
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<b>Middleware:</b> Robotic Operative System (ROS, Good)
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<b>OS Used:</b> Linux, Microsoft
</TableCell>
</TableRow>
<TableRow sx={{ '&:last-child td': { borderBottom: 0 } }}>
<TableCell width="15%">
<Typography variant="h6" component="b" fontWeight={600}>
Softskills
</Typography>
</TableCell>
<TableCell width="85%">
Adaptability, Communication, Creativity, Critical Thinking, Problem-Solving, Self-Organization, Teamworking
</TableCell>
</TableRow>
</TableBody>
</Table>
{/* Accomplishments */}
<Divider sx={{ mt: 4, mb: 4 }} />
<SectionHeader>Accomplishments</SectionHeader>
<Box pb={1}>
<SectionSubheader fontWeight={300}>Awards</SectionSubheader>
<Award
year="2021"
title="Premio Innovazione Robotica ed Automazione - Horizon"
organization={
<>
21
<sup>
<small>st</small>
</sup>{' '}
MECSPE fair
</>
}
location="Bologna, Italy"
/>
{/* https://twitter.com/IITalk/status/1466745516851617796 */}
{/* https://www.linkedin.com/feed/update/urn:li:activity:6869549011855032321/ */}
<Award year="2018" title="Consortium schoolarship" organization="EMARO+ Consortium" location="Warsaw, Poland" />
<Award year="2017" title="Consortium schoolarship" organization="EMARO+ Consortium" location="Nantes, France" />
<Award year="2014" title="Study Grant" organization="Università di Bologna" location="Bologna, Italy" />
</Box>
<Box pb={1}>
<SectionSubheader fontWeight={300}>Press Releases</SectionSubheader>
<Award
year="2020"
title="Covid-19: L'impatto sui giovani talenti"
titleProps={{
onClick: () => window.open('https://www.youtube.com/watch?v=Blat-e2Vyzk&feature=youtu.be', '_blank'),
sx: {
cursor: 'pointer',
':hover': {
backgroundColor: 'transparent',
color: 'primary.main',
},
},
}}
organization="Talents in Motion"
location="Rome, Italy"
/>
</Box>
<Box py={1}>
<SectionSubheader fontWeight={300}>Publications</SectionSubheader>
<Publication
year="2020"
title="Control System Design for Human Assisting Robot"
authors={
<>
Zielinska T.,{' '}
<Typography component="span" color="text.primary">
Tartari M.
</Typography>
</>
}
location="ROMANSY 23 - Robot Design, Dynamics and Control. CISM International Centre for Mechanical Sciences (Courses and Lectures), vol
601. Springer, Cham."
href="https://doi.org/10.1007/978-3-030-58380-4_7"
/>
</Box>
{/* Extacurricoular */}
<Divider sx={{ mt: 4, mb: 4 }} />
<SectionHeader>Extracurricular</SectionHeader>
{/* Volunteering */}
<SectionSubheader fontWeight={300}>Volunteering</SectionSubheader>
<Box component="ul" pl={4} mt={0}>
<Extracurricular Component="li" year="2013 - Today" title="Blood Donor, Bone Marrow Donor at AVIS & ADMO" />
<Extracurricular Component="li" year="2008 - 2014" title="Scoutism and associated volunteering activities in Agesci" />
<Extracurricular Component="li" year="2011 - 2012" title="Boy Scout of America (BSA)" />
</Box>
{/* Other */}
{/* Interests */}
<SectionSubheader fontWeight={300}>Interests</SectionSubheader>
<Box component="ul" pl={4} mt={0}>
<Extracurricular Component="li" title="Historical Handcrafting & Reenactment" />
<Extracurricular Component="li" title="Hiking/Travelling" />
<Extracurricular Component="li" title="Ju-jitsu" />
</Box>
</Box>
</Page>
)
}
export default Curriculum
@@ -1 +0,0 @@
export { default } from './CurriculumPage'
+23 -84
View File
@@ -1,106 +1,45 @@
import React from 'react'
import { Box, Stack, Typography } from '@mui/material'
import { Box } from '@mui/material'
import { ViewportProvider } from 'components/utils/viewport'
import { AcademyIconLink, DescriptionIconLink, ExternalAppIconLink, GitHubIconLink, VideoIconLink } from 'components/atoms/index.js'
import { Footer, Hero, Toolbar, ProjectSpotlight } from 'components/molecules/index.js'
const MainPage = () => {
React.useEffect(() => {
document.title = 'Michele Tartari'
document.title = "Compagnia d'Arme del Santo Luca"
}, [])
const refIITLinfa = React.useRef<HTMLSelectElement>(null)
const refIITModular = React.useRef<HTMLSelectElement>(null)
const refIITCalibration = React.useRef<HTMLSelectElement>(null)
const refWUTThesis = React.useRef<HTMLSelectElement>(null)
const refAboutUs = React.useRef<HTMLSelectElement>(null)
const refTeaching = React.useRef<HTMLSelectElement>(null)
const refTraining = React.useRef<HTMLSelectElement>(null)
return (
<ViewportProvider>
<Box aria-label="page" sx={{ flexGrow: 1 }}>
<Toolbar />
<Hero scrollTarget={refIITLinfa} />
{/* 1 IIT - Linfa */}
<Hero scrollTarget={refAboutUs} />
{/* 1 Chi Siamo */}
<ProjectSpotlight
ref={refIITLinfa}
scrollTarget={refIITModular}
anchor="bottom"
image="images/IIT_Linfa.webp"
title="LINFA: An Intuitive Block-Programming Interface for Reconfigurable Robots"
caption={
<Stack direction="row" gap={1} alignItems="center">
<VideoIconLink fontSize="small" pt={0.5} href="https://www.linkedin.com/feed/update/urn:li:activity:7034480841569284096/" />
<Typography color="text.secondary">Software Engineer @ IIT</Typography>
</Stack>
}>
This project aims to simplify the control, monitoring, and programming of reconfigurable robots through an intuitive block-programming
interface. It includes a front-end web app, built with TypeScript and React, allowing users to effortlessly change robot operating modes and
settings, monitor the robot's state, and assemble programs by dragging and dropping code blocks representing various robot capabilities.
Additionally, back-end services, developed with TypeScript and Python, translate these programs into formats compatible with the underlying
systems and manage mission execution. The project emphasizes extensibility, enabling users with Python experience to integrate custom blocks
and capabilities. Automated CI/CD pipelines further streamline integration and deployment processes.
</ProjectSpotlight>
{/* 2 IIT - Modular */}
<ProjectSpotlight
ref={refIITModular}
scrollTarget={refIITCalibration}
ref={refAboutUs}
scrollTarget={refTeaching}
anchor="right"
// anchor="left"
image="images/IIT_Modular.png"
mobileImage="images/IIT_Modular_Mobile.webp"
title="Revamping HHCM's Modular: Swift Generation of Modular Robot Models"
caption={
<Stack direction="row" gap={1} alignItems="center">
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/ADVRHumanoids/modular_hhcm" />
<ExternalAppIconLink pt={0.5} fontSize="small" href="https://modular.alberobotics.it" />
<Typography color="text.secondary">Software Engineer @ IIT</Typography>
</Stack>
}>
This project focused on overhauling HHCM's Modular, enhancing its graphical interface, API, and deployment pipeline. Modular serves as a web
application for the swift generation of modular robot models, with an offline approach (Building Mode) enabling users to set up robots in a
virtual environment by selecting and assembling reconfigurable modules, immediately visualized in 3D. Additionally, an online approach
(Discovery Mode) allows users to query the EtherCAT master for network topology, recognizing and displaying robots built from physical
modules in 3D. The system seamlessly produces URDF, SRDF, and a full ROS package that can then be utilized for simulating and controlling
the robot.
image="images/about-us.png"
mobileImage="images/about-us.png"
title="Chi Siamo">
La Compagnia d'Arme del Santo Luca è un gruppo di rievocazione storica di Ferrara affiliato al C.E.R.S. (Consorzio Europeo Rievocazioni
Storiche). Il periodo rievocato dalla Compagnia è il tardo XIV secolo (1380-1410).
</ProjectSpotlight>
{/* 3 IIT - Motor Calibration */}
<ProjectSpotlight
ref={refIITCalibration}
scrollTarget={refWUTThesis}
anchor="left"
image="images/IIT_Modules.webp"
title="Automated Actuators and Robotic Modules Calibration"
caption={
<Stack direction="row" gap={1} alignItems="center">
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/ADVRHumanoids/motor_calibration" />
<Typography color="text.secondary">Embedded Engineer @ IIT</Typography>
</Stack>
}>
This project focused on automating the calibration of EtherCAT actuators and robotic modules, aiming for a fully automated procedure for
newly assembled actuators. The process involved testing the PDO, conducting phase angle calibration, torque sensor calibration, ripple and
position-dependent torque offset calibration, inertia and friction identification, and frequency response calibration. The goal was to
optimize motor performance and collect necessary data for accurate characterization, with results stored centrally and presented in a
comprehensive PDF report.
{/* 2. Attività didattiche */}
<ProjectSpotlight ref={refTeaching} scrollTarget={refTraining} anchor="left" image="images/didattica.png" title="Attività didattiche">
La Compagnia d'Arme del Santo Luca propone percorsi didattici sulla vita nel Medioevo attraverso la spiegazione delle attività che venivano
svolte all'interno del campo armato e che erano parte integrante della vita dell'uomo d'arme dell'epoca.
</ProjectSpotlight>
{/* 4 WUT - Master Thesis */}
<ProjectSpotlight
ref={refWUTThesis}
anchor="bottom"
image="images/thesis.jpg"
mobileImage="images/thesis.webp"
title="Voice Controlled Mobile Robot for Indoor Applications"
caption={
<Stack direction="row" gap={1} alignItems="center">
<AcademyIconLink pt={0.5} fontSize="small" href="https://doi.org/10.1007/978-3-030-58380-4_7" />
<DescriptionIconLink pt={0.5} href="https://drive.google.com/drive/folders/1Y7TJJN8z1llCkSTnpVHMELD3PqsX8VF9?usp=sharing" />
<Typography color="text.secondary">Master Thesis @ WUT</Typography>
</Stack>
}>
This thesis proposes a design for a small mobile robot controlled by voice. Firstly a preliminary analysis of the state of art of
human-robot interaction has been conducted. Then, an analysis of the equipment selected took place, and, later, appropriate methodologies
for voice recognition and user detection have been evaluated for this specific case. Finally, an overview of the complete software
architecture of the system was given with three possible structures and their comparison. The results obtained show both the feasibility of
using low power boards and some of their limitations.
{/* 3. Scuola d'arme */}
<ProjectSpotlight ref={refTraining} anchor="bottom" image="images/battle.png" mobileImage="images/battle.png" title="Scuola d'arme">
Altra attività di rilevante importanza è la scherma medievale. Il gruppo in arme si allena settimanalmente per studiare e riproporre i
trattati di scherma più importanti, dedicandosi allo studio e la messa in pratica delle tecniche di combattimento con differenti tipologie
di armi.
</ProjectSpotlight>
<Footer />
</Box>
@@ -1,38 +0,0 @@
import { screen } from '@testing-library/react'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { useAnalytics } from 'use-analytics'
import { renderWithRouter as render } from 'components/utils/tests/index.js'
import ProjectsPage from '.'
// Mock the analytics module
vi.mock('use-analytics', () => ({
useAnalytics: () => ({ plugins: { enable: vi.fn(), disable: vi.fn() } }),
}))
vi.stubGlobal('open', vi.fn())
describe('ProjectsPage component', () => {
test('renders without crashing and displays the correct project titles', () => {
render(<ProjectsPage />)
// check the section titles
expect(screen.getByText('Robotics')).toBeInTheDocument()
expect(screen.getByText('Engineering')).toBeInTheDocument()
expect(screen.getByText('Hobbies')).toBeInTheDocument()
// check some of the projects
expect(screen.getByText('LINFA: An Intuitive Block-Programming Interface for Reconfigurable Robots')).toBeInTheDocument()
expect(screen.getByText("Revamping HHCM's Modular: Swift Generation and Control of Modular Robot Models")).toBeInTheDocument()
expect(screen.getByText('Voice Controlled Mobile Robot for Indoor Applications')).toBeInTheDocument()
})
test('opens the correct links when the link buttons are clicked', async () => {
render(<ProjectsPage />)
// inspect one of the many links
const link = screen.getByLabelText('Video-button')
expect(link).toHaveAttribute('href', 'https://www.linkedin.com/feed/update/urn:li:activity:7034480841569284096/')
expect(link).toHaveAttribute('target', '_blank')
expect(link).toHaveAttribute('rel', 'noopener noreferrer')
})
})
@@ -1,422 +0,0 @@
import { Box, Divider, Link, Typography } from '@mui/material'
import { GitHubIconLink, DescriptionIconLink, VideoIconLink, AcademyIconLink, ExternalAppIconLink } from 'components/atoms/index.js'
import { Project } from 'components/molecules/index.js'
import { Page } from 'components/templates/index.js'
const ProjectsPage = () => {
return (
<Page title="Projects">
<Box component="section" id="robotics">
<Typography variant="h4" color="primary.main" gutterBottom>
Robotics
</Typography>
<Typography gutterBottom>
Here is a collection of all the projects that are strictly related to the design, development and functioning of robots:
</Typography>
<Project
title="Behavior Tree Web Editor and Runtime for Robotics Applications"
subtitle={<Typography color="text.secondary">Software Engineering Consultant @ IIT</Typography>}>
<Typography>
This project aims to simplify the remote control, monitoring, programming of behavior trees through an intuitive web interface. It
includes a frontend web app, built with TypeScript and React, allowing users to effortlessly add, remove, replace nodes by dragging and
dropping them on the a behavior trees canvas. It also allows to start, stop, pause, and resume tree execution. Additionally, backend
services, developed with C++ and Python, translate these programs into formats compatible with the underlying libraries, stream them to
target systems, and manage the behavior-trees lifecycle. Automated CI/CD pipelines further streamline integration and deployment
processes.
</Typography>
</Project>
<Project
title="Digital Twin Interface for Reconfigurable Robots"
subtitle={<Typography color="text.secondary">Software Engineering Consultant @ IIT</Typography>}>
<Typography>
This project focuses on the development of a user interface for the control and monitoring of the digital twin of modular reconfigurable
robots. It includes a frontend web app, built with TypeScript and React, allowing users to effortlessly monitor and control the digital
twin of their robots. The backend is powered by Python, and provides robust APIs for seamless communication between the frontend and the
digital twin simulation. Automated CI/CD pipelines further streamline integration and deployment processes.
</Typography>
</Project>
<Project
title="LINFA: An Intuitive Block-Programming Interface for Reconfigurable Robots"
subtitle={
<>
<Typography color="text.secondary" display={{ sm: 'none' }}>
Software Engineer @ IIT
</Typography>
<VideoIconLink
pt={0.5}
fontSize="small"
href="https://www.linkedin.com/feed/update/urn:li:activity:7034480841569284096/"
sx={{ color: 'text.secondary' }}
/>
{/* <Typography color="text.secondary" display="inline-block"> */}
<Typography color="text.secondary" display={{ xs: 'none', sm: 'inline' }}>
Software Engineer @ IIT
</Typography>
</>
}>
<Typography>
This project aims to simplify the control, monitoring, and programming of reconfigurable robots through an intuitive block-programming
interface. It includes a frontend web app, built with TypeScript and React, allowing users to effortlessly change robot operating modes
and settings, monitor the robot's state, and assemble programs by dragging and dropping code blocks representing various robot
capabilities. Additionally, backend services, developed with TypeScript and Python, translate these programs into formats compatible with
the underlying systems and manage mission execution. The project emphasizes extensibility, enabling users with Python experience to
integrate custom blocks and capabilities. Automated CI/CD pipelines further streamline integration and deployment processes.
</Typography>
</Project>
<Project
title="Revamping HHCM's Modular: Swift Generation and Control of Modular Robot Models"
subtitle={
<>
<Typography color="text.secondary" display={{ sm: 'none' }}>
Software Engineer @ IIT
</Typography>
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/ADVRHumanoids/modular_hhcm/" sx={{ color: 'text.secondary' }} />
<ExternalAppIconLink pt={0.5} fontSize="small" href="https://modular.alberobotics.it" sx={{ color: 'text.secondary' }} />
<Typography color="text.secondary" display={{ xs: 'none', sm: 'inline' }}>
Software Engineer @ IIT
</Typography>
</>
}>
<Typography>
This project centered on overhauling HHCM's Modular by redesigning its graphical interface, API, and deployment pipeline. Modular serves
as a web application for swiftly generating models of modular robots. Starting with a collection of fundamental robotic modules, the
system produces URDF, SRDF, and a full ROS package seamlessly and without coding. These can then be utilized for simulating and
controlling the robot.
</Typography>
</Project>
<Project
title="Voice Controlled Mobile Robot for Indoor Applications"
subtitle={
<>
<Typography color="text.secondary" display={{ sm: 'none' }}>
Master Thesis @ WUT
</Typography>
<AcademyIconLink pt={0.5} fontSize="small" href="https://doi.org/10.1007/978-3-030-58380-4_7" sx={{ color: 'text.secondary' }} />
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/drive/folders/1Y7TJJN8z1llCkSTnpVHMELD3PqsX8VF9?usp=sharing"
sx={{ color: 'text.secondary' }}
/>
<Typography color="text.secondary" display={{ xs: 'none', sm: 'inline' }}>
Master Thesis @ WUT
</Typography>
</>
}>
<Typography>
This thesis proposes a design for a small mobile robot controlled by voice. Firstly a preliminary analysis of the state of art of
human-robot interaction has been conducted. Then, an analysis of the equipment selected took place, and, later, appropriate methodologies
for voice recognition and user detection have been evaluated for this specific case. Finally, an overview of the complete software
architecture of the system was given with three possible structures and their comparison. The results obtained show both the feasibility
of using low power boards and some of their limitations.
</Typography>
</Project>
<Project
title="Recharging Electric Cars with a Mobile Robot"
subtitle={
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/file/d/1wBfvAzy9N8uChNxNj9Kd_hcvI0Qq3uQj/view?usp=sharing"
sx={{ color: 'text.secondary' }}
/>
}>
<Typography>
The aim of this project was to prove the possibility to design an autonomous mobile robot whose task was to recharge electric cars in a
parking lot. This was done in simulation, using the Gazebo and ROS.
</Typography>
</Project>
<Project
title="Mobile Robot Self-Localization"
subtitle={
<>
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/ekf_matlab" sx={{ color: 'text.secondary' }} />
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/file/d/1BgPj-fgtYDDEsFHmDk2fGVm7DCPFWEeN/view?usp=sharing"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>
For this project we worked using Matlab on data retrieved from a differential drive robot for its localization in a certain area by the
means of the Extended Kalman filter (EKF).
</Typography>
</Project>
<Project
title="Onychophora-Inspired Firefighting Robot"
subtitle={
<>
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/firebot" sx={{ color: 'text.secondary' }} />
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/open?id=1a_ZvgaQjzvedeo296zrDpdvNL_VJDWTX"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>
This project proposes a conceptual design for a firefighting robot suitable for indoor environments by taking inspiration from the
biological world.
</Typography>
</Project>
<Project
title="Point-to-Point Trajectory Optimization"
subtitle={
<>
{/* */}
<GitHubIconLink
pt={0.5}
fontSize="small"
href="https://github.com/m-tartari/simple_trajectory_optimization"
sx={{ color: 'text.secondary' }}
/>
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/open?id=11m7r7fLda_jpDEZ-9qAWvnfRN2kLkhlA"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>
For this project we worked to find the optimal trajectory for a simple model of a robot performing point-to-point navigation in a room
with some obstacles using MATLAB.
</Typography>
</Project>
<Project
title="3RRR Planar Parallel Manipulator"
subtitle={
<>
<GitHubIconLink
pt={0.5}
fontSize="small"
href="https://github.com/m-tartari/3RRR_planar_parallel_manipulator"
sx={{ color: 'text.secondary' }}
/>
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/open?id=11lCJM3EjVsua379BKD5NcEDHQLL4jdQn"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>This project concerns the design and optimization of a 3RRR planar parallel manipulator using MATLAB and CATIA</Typography>
</Project>
<Project
title="Simple Swarm"
subtitle={
<>
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/simple_swarm" sx={{ color: 'text.secondary' }} />
</>
}>
<Typography>
Simple simulation and visualization of swarms of differential drive robots following a leader. Developed using C++ and ROS.
</Typography>
</Project>
<Project
title="Industrial Robot Programming"
subtitle={
<>
<GitHubIconLink
pt={0.5}
fontSize="small"
href="https://github.com/m-tartari/industrial_robot_programming"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>Industrial Robot Programming using VAL II and V+ tested on a PUMA and a RX90 robots.</Typography>
</Project>
<Project
title="Modelling and Control of Manipulators"
subtitle={
<>
<GitHubIconLink
pt={0.5}
fontSize="small"
href="https://github.com/m-tartari/modelling_and_control_of_manipulators"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>
This contains several projects regarding modelling and control of various manipulators using MATLAB, Simulink and ADAMS.
</Typography>
</Project>
</Box>
<Divider sx={{ mt: 4, mb: 4 }} />
<Box component="section" id="engineering">
<Typography variant="h4" color="primary.main" gutterBottom sx={{ mt: 4 }}>
Engineering
</Typography>
<Typography gutterBottom>Here there is a collection of all the projects that are related to all the other fields of engineering:</Typography>
<Project
title="Replacing Legacy CNC Software with a Rust-based G-code Converter"
subtitle={<Typography color="text.secondary">Software Engineering Consultant</Typography>}>
<Typography>
This project focuses on the replacement of mission-critical software which was previously handled by a prioritary solution on an unsecure
legacy machine. The converter developed here is a standalone, cross-platform command-line tool written in Rust that transforms ISO-style
G-code programs into explicit Fanuc CNC format. Scripts and guides were provided to facilitate adoption for non-technical users, and
automation workflows were setup to enable seamless compilation and distribution of the converter across Windows, Linux, and macOS
platforms.
</Typography>
</Project>
<Project
title="Automated Actuators and Robotic Modules Calibration"
subtitle={
<>
<Typography color="text.secondary" display={{ sm: 'none' }}>
Embedded Engineer @ IIT
</Typography>
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/ADVRHumanoids/motor_calibration" sx={{ color: 'text.secondary' }} />
<Typography color="text.secondary" display={{ xs: 'none', sm: 'inline' }}>
Embedded Engineer @ IIT
</Typography>
</>
}>
<Typography>
This project focused on automating the calibration of EtherCAT actuators and robotic modules, aiming for a fully automated procedure for
newly assembled actuators. The process involved testing the PDO, conducting phase angle calibration, torque sensor calibration, ripple and
position-dependent torque offset calibration, inertia and friction identification, and frequency response calibration. The goal was to
optimize motor performance and collect necessary data for accurate characterization, with results stored centrally and presented in a
comprehensive PDF report.
</Typography>
</Project>
<Project
title="Solar Panel Fault Detection Method Based on Infrared Image
Processing"
subtitle={
<>
<Typography color="text.secondary" display={{ sm: 'none' }}>
Bachelor Thesis @ TONGJI
</Typography>
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/file/d/0B1z42QMR-0UtYzBYSVhRV3ZPWk0/view?resourcekey=0-3O0frJlyho7TRKwNcy8f4g"
sx={{ color: 'text.secondary' }}
/>
<Typography color="text.secondary" display={{ xs: 'none', sm: 'inline' }}>
Bachelor Thesis @ TONGJI
</Typography>
</>
}>
<Typography>
My Chinese bachelor thesis that proposes a method to detect malfunctioning solar panels by processing thermal images using MATLAB.
</Typography>
</Project>
<Project
title="Design of a Testing Machine for Flexure Hinges"
subtitle={
<>
<Typography color="text.secondary" display={{ sm: 'none' }}>
Bachelor Thesis @ UNIBO
</Typography>
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/file/d/0B1z42QMR-0UtSkxRVzJPTk1IX0k/view?resourcekey=0-LN4KALZlLWc_lKekqqQbIw"
sx={{ color: 'text.secondary' }}
/>
<Typography color="text.secondary" display={{ xs: 'none', sm: 'inline' }}>
Bachelor Thesis @ UNIBO
</Typography>
</>
}>
<Typography>
My Italian bachelor thesis that proposes a design from scratch of a machine for the empirical characterization of flexure hinges.
</Typography>
</Project>
<Project
title="Control of a Nonlinear System"
subtitle={
<>
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/nonlinear_control" sx={{ color: 'text.secondary' }} />
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/file/d/1TE3TWkXZjVq8OuBkLl497c_MQSs3MiLQ/view?usp=sharing"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>
The aim of this project was to implement control laws for a nonlinear system (based on the model of a PVTOL aircraft).
</Typography>
</Project>
<Project
title="Multi-Body System's Kinematic Analysis"
subtitle={
<>
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/multi-body-kinematics" sx={{ color: 'text.secondary' }} />
<DescriptionIconLink
pt={0.5}
fontSize="small"
href="https://drive.google.com/file/d/15yrDU2blkb34Jy2GXkCIe4qNmDRmp31w/view?usp=sharing"
sx={{ color: 'text.secondary' }}
/>
</>
}>
<Typography>
For this project the kinematic analysis has been performed upon agiven mechanism using MATLAB. It has been then validated by comparing it
to the ADAMS model of the same mechanism.
</Typography>
</Project>
<Project
title="Signal Processing"
subtitle={
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/signal_processing" sx={{ color: 'text.secondary' }} />
}>
<Typography>Several Signal processing projects developed using MATLAB.</Typography>
</Project>
<Project
title="Real Time Systems"
subtitle={
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/real_time_systems" sx={{ color: 'text.secondary' }} />
}>
<Typography>Several real-time systems' projects developed using C++ and OIL, and run using Trampoline RTOS on a Teensy board.</Typography>
</Project>
</Box>
<Divider sx={{ mt: 4, mb: 4 }} />
<Box component="section" id="hobbies">
<Typography variant="h4" color="primary.main" gutterBottom sx={{ mt: 4 }}>
Hobbies
</Typography>
<Typography gutterBottom>Here there is a collection of projects related to things I do for fun:</Typography>
<Project
title="Medieval Furniture"
subtitle={
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/medieval_furniture" sx={{ color: 'text.secondary' }} />
}>
<Typography>
A collection of pdf and CAD models to create late XIV century furniture and medieval camp equipment. These objects are being realized by{' '}
<Link target="_blank" rel="noopener noreferrer" href="http://www.compagniadarmedelsantoluca.it/">
Compagnia d'Arme del Santo Luca
</Link>
.
</Typography>
</Project>
<Project
title="Pinterest Pinner"
subtitle={
<GitHubIconLink pt={0.5} fontSize="small" href="https://github.com/m-tartari/pinterest_pinner" sx={{ color: 'text.secondary' }} />
}>
<Typography>
Publishes all photos from a{' '}
<Link target="_blank" rel="noopener noreferrer" href="http://www.compagniadarmedelsantoluca.it/">
selected website
</Link>{' '}
into a target Pinterest board using Python3 and the Pinterest API
</Typography>
</Project>
</Box>
</Page>
)
}
export default ProjectsPage
@@ -1 +0,0 @@
export { default } from './ProjectsPage'
-2
View File
@@ -1,7 +1,5 @@
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'
+1 -1
View File
@@ -27,7 +27,7 @@ describe('Page component', () => {
expect(screen.getByText('Test Content')).toBeInTheDocument()
// sets the document title correctly
expect(document.title).toBe(`Michele Tartari - ${defaultProps.title}`)
expect(document.title).toBe(`Compagnia d'Arme del Santo Luca - ${defaultProps.title}`)
})
it('does not render the title and divider when title is not provided', () => {
+1 -1
View File
@@ -14,7 +14,7 @@ interface PageProps extends BoxProps {
const Page: React.FC<PageProps> = ({ title, children, showCookieConsent, ...props }) => {
React.useEffect(() => {
if (title) {
document.title = `Michele Tartari - ${title}`
document.title = `Compagnia d'Arme del Santo Luca - ${title}`
}
}, [title])
+10 -2
View File
@@ -1,10 +1,18 @@
@font-face {
font-family: 'Cloister Black';
src: url('/fonts/cloister-black/CloisterBlack.ttf') format('truetype');
font-weight: 400; /* the TTF you have is regular weight */
font-style: normal;
font-display: swap; /* avoids FOIT */
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
+3 -8
View File
@@ -1,12 +1,7 @@
/* istanbul ignore file */
import '@fontsource/oswald/700.css'
import '@fontsource/oswald/500.css'
import '@fontsource/oswald/400.css'
import '@fontsource/oswald/300.css'
import '@fontsource/inter/700.css'
import '@fontsource/inter/500.css'
import '@fontsource/inter/400.css'
import '@fontsource/inter/300.css'
import '@fontsource/eb-garamond' // Regular 400, SemiBold 600
import '@fontsource/unifrakturcook' // Bold 700
import '@fontsource/medievalsharp' // Regular
import React from 'react'
import ReactDOM from 'react-dom/client'
+4 -4
View File
@@ -3,7 +3,7 @@ import { PaletteOptions } from '@mui/material'
export const dark: PaletteOptions = {
mode: 'dark',
primary: {
main: '#e44c65', // Rouge Red (similar)
main: '#20b540', // Rouge Red (similar)
// main:'#df4661', // Pantone PMS 198 C
},
secondary: {
@@ -11,13 +11,13 @@ export const dark: PaletteOptions = {
// main: '#3a5dae', // Pantone 7455 C Color
},
background: {
default: '#101018',
paper: '#1b1d27',
default: '#101810',
paper: '#1b271d',
},
}
export const light: PaletteOptions = {
primary: {
main: '#AC1D1B', // Casual Red
main: '#20b540', // Casual Red
// main: '#AF231C' // Pantone 2350 C
// main: '#AB2328' // Pantone 7621 C
},
+15 -9
View File
@@ -1,25 +1,31 @@
import { TypographyVariantsOptions } from '@mui/material'
const typography: TypographyVariantsOptions = {
fontFamily: 'Inter, sans-serif', // Base font for headings
// ---------- Global defaults ----------
fontFamily: '"EB Garamond", serif',
// ---------- Headings ----------
h1: {
fontFamily: 'Oswald, sans-serif',
textTransform: 'uppercase',
fontFamily: '"Cloister Black", cursive',
fontWeight: 700,
},
h2: {
fontFamily: 'Oswald, sans-serif',
textTransform: 'uppercase',
fontFamily: '"Cloister Black", cursive',
fontWeight: 700,
},
h3: {
fontFamily: 'Oswald, sans-serif',
fontFamily: '"Cloister Black", cursive',
fontWeight: 700,
},
h4: {
fontFamily: 'Oswald, sans-serif',
fontWeight: 700,
// ---------- Buttons ----------
button: {
fontFamily: '"MedievalSharp", cursive',
textTransform: 'none', // keep original caps
fontWeight: 400,
},
// ---------- Caption / Overline ----------
overline: {
textTransform: 'uppercase',
},
}
+1 -1
View File
@@ -7,7 +7,7 @@ interface ImportMetaEnv {
readonly VITE_BC_VAT: string
readonly VITE_BC_PHONE: string
readonly VITE_BC_EMAIL: string
readonly VITE_BC_LINKEDIN: string
readonly VITE_BC_FACEBOOK: string
}
interface ImportMeta {