♻️ 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
+1 -1
View File
@@ -1,7 +1,7 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the // For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose // README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose
{ {
"name": "m-tartari.github.io", "name": "website",
// Update the 'dockerComposeFile' list if you have more compose files or use different names. // Update the 'dockerComposeFile' list if you have more compose files or use different names.
// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
"dockerComposeFile": [ "dockerComposeFile": [
+4 -4
View File
@@ -1,18 +1,18 @@
services: services:
devcontainer: devcontainer:
image: m-tartari.github.io-dev image: website-dev
build: build:
context: .. context: ..
dockerfile: Dockerfile dockerfile: Dockerfile
target: development target: development
container_name: devcontainer-m-tartari.github.io container_name: devcontainer-website
hostname: m-tartari.github.io-dev hostname: website-dev
command: sleep infinity command: sleep infinity
# ports: # ports:
# - '5173:5173' # - '5173:5173'
# - '4173:4173' # - '4173:4173'
volumes: volumes:
- ..:/workspaces/m-tartari.github.io:cached - ..:/workspaces/website:cached
# Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust. # Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust.
# cap_add: # cap_add:
# - SYS_PTRACE # - SYS_PTRACE
+1 -1
View File
@@ -4,4 +4,4 @@ VITE_BC_POSITION=XXXXXXXXXX
VITE_BC_VAT=ITXXXXXXXXXX VITE_BC_VAT=ITXXXXXXXXXX
VITE_BC_PHONE=+39XXXXXXXXXX VITE_BC_PHONE=+39XXXXXXXXXX
VITE_BC_EMAIL=XXXX@XXXX.XX VITE_BC_EMAIL=XXXX@XXXX.XX
VITE_BC_LINKEDIN=XXXXXXXXXX VITE_BC_FACEBOOK=XXXXXXXXXX
+2 -2
View File
@@ -49,8 +49,8 @@ jobs:
if [[ -n "${{ vars.VITE_BC_VAT }}" ]]; then if [[ -n "${{ vars.VITE_BC_VAT }}" ]]; then
echo "VITE_BC_VAT=${{ vars.VITE_BC_VAT }}" >> .env echo "VITE_BC_VAT=${{ vars.VITE_BC_VAT }}" >> .env
fi fi
if [[ -n "${{ vars.VITE_BC_LINKEDIN }}" ]]; then if [[ -n "${{ vars.VITE_BC_FACEBOOK }}" ]]; then
echo "VITE_BC_LINKEDIN=${{ vars.VITE_BC_LINKEDIN }}" >> .env echo "VITE_BC_FACEBOOK=${{ vars.VITE_BC_FACEBOOK }}" >> .env
fi fi
if [[ -n "${{ secrets.VITE_BC_PHONE }}" ]]; then if [[ -n "${{ secrets.VITE_BC_PHONE }}" ]]; then
echo "VITE_BC_PHONE=${{ secrets.VITE_BC_PHONE }}" >> .env echo "VITE_BC_PHONE=${{ secrets.VITE_BC_PHONE }}" >> .env
-1
View File
@@ -1 +0,0 @@
www.m-tartari.eu
+2 -2
View File
@@ -5,8 +5,8 @@ ARG BASE_IMAGE=node:lts
FROM $BASE_IMAGE AS development FROM $BASE_IMAGE AS development
ENV NODE_ENV=development ENV NODE_ENV=development
COPY --chown=1000:1000 . /workspaces/m-tartari.github.io COPY --chown=1000:1000 . /workspaces/website
WORKDIR /workspaces/m-tartari.github.io WORKDIR /workspaces/website
USER 1000:1000 USER 1000:1000
CMD [ "sleep", "infinity" ] CMD [ "sleep", "infinity" ]
+4 -4
View File
@@ -1,13 +1,13 @@
version: '3.8' version: "3.8"
services: services:
app: app:
image: git.m-tartari.eu/m-tartari.github.io image: git.m-tartari.eu/website
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
target: production target: production
container_name: m-tartari.github.io container_name: website
restart: unless-stopped restart: unless-stopped
ports: ports:
- '8080:8080' - "8080:8080"
+39 -34
View File
@@ -1,44 +1,49 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff" /> <head>
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#101018" /> <meta charset="UTF-8" />
<link rel="apple-touch-icon" href="/logo_light.png" media="(prefers-color-scheme: light)" /> <meta name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff" />
<link rel="apple-touch-icon" href="/logo_dark.png" media="(prefers-color-scheme: dark)" /> <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#101018" />
<link rel="icon" rel="icon" href="/fav-icon.svg" type="image/svg+xml" />
<link rel="manifest" href="/manifest.json" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- <link rel="apple-touch-icon" href="/logo_light.png" media="(prefers-color-scheme: light)" /> -->
<!-- <link rel="apple-touch-icon" href="/logo_dark.png" media="(prefers-color-scheme: dark)" /> -->
<link rel="icon" rel="icon" href="/fav-icon.png" type="image/svg+xml" />
<link rel="manifest" href="/manifest.json" />
<meta property="og:type" content="profile" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="profile:first_name" content="Michele" />
<meta property="profile:last_name" content="Tartari" />
<meta property="profile:username" content="m-tartari" />
<meta property="og:url" content="https://m-tartari.eu" /> <meta property="og:locale" content="it_IT">
<meta property="og:image" content="/logo.png" /> <meta property="og:type" content="website" />
<meta property="og:image:width" content="512" />
<meta property="og:image:height" content="512" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:alt" content="m-tartari.eu logo" />
<meta property="og:logo" content="/logo.png" />
<meta property="twitter:image" content="/logo.png" />
<meta property="twitter:card" content="summary" />
<meta name="description" property="og:description" content="Robotics/Full Stack Software Engineer" /> <meta property="og:url" content="https://www.compagniadarmedelsantoluca.it" />
<meta property="twitter:description" content="Robotics/Full Stack Software Engineer" /> <meta property="og:image" content="/logo.png" />
<meta property="og:image:width" content="192" />
<meta property="og:image:height" content="192" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:alt" content="Compagnia d'Arme del Santo Luca logo" />
<meta property="og:logo" content="/logo.png" />
<meta property="twitter:image" content="/logo.png" />
<meta property="twitter:card" content="summary" />
<meta name="description" property="og:description" content="Gruppo di rievocazione storica XIV-XV secolo" />
<meta property="twitter:description" content="Gruppo di rievocazione storica XIV-XV secolo" />
<meta property="article:publisher" content="https://www.facebook.com/compagniadarmedelsantoluca">
<meta name='title' property="og:title" content="Compagnia d'Arme del Santo Luca" />
<meta property="twitter:title" content="Compagnia d'Arme del Santo Luca" />
<meta property="og:site_name" content="Compagnia d'Arme del Santo Luca" />
<title>Compagnia d'Arme del Santo Luca</title>
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1">
</head>
<body>
<noscript>You need to enable JavaScript for this website to work.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.js"></script>
</body>
<meta name='title' property="og:title" content="Michele Tartari" />
<meta property="twitter:title" content="Michele Tartari" />
<meta property="og:site_name" content="Michele Tartari" />
<title>Michele Tartari</title>
</head>
<body>
<noscript>You need to enable JavaScript for this website to work.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html> </html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,31 @@
1001Fonts Free For Commercial Use License (FFC)
Preamble
In this license, 'Cloister Black' refers to the given .zip file, which may contain one or numerous fonts. These fonts can be of any type (.ttf, .otf, ...) and together they form a 'font family' or in short a 'typeface'.
1. Copyright
Cloister Black is the intellectual property of its respective author, provided it is original, and is protected by copyright laws in many parts of the world.
2. Usage
Cloister Black may be downloaded and used free of charge for both personal and commercial use, as long as the usage is not racist or illegal. Personal use refers to all usage that does not generate financial income in a business manner, for instance:
- personal scrapbooking for yourself
- recreational websites and blogs for friends and family
- prints such as flyers, posters, t-shirts for churches, charities, and non-profit organizations
Commercial use refers to usage in a business environment, including:
- business cards, logos, advertising, websites for companies
- t-shirts, books, apparel that will be sold for money
- flyers, posters for events that charge admission
- freelance graphic design work
- anything that will generate direct or indirect income
3. Modification
Cloister Black may not be modified, altered, adapted or built upon without written permission by its respective author. This pertains all files within the downloadable font zip-file.
4. Distribution
While Cloister Black may freely be copied and passed along to other individuals for private use as its original downloadable zip-file, it may not be sold or published without written permission by its respective author.
5. Disclaimer
Cloister Black is offered 'as is' without any warranty. 1001fonts.com and the respective author of Cloister Black shall not be liable for any damage derived from using this typeface. By using Cloister Black you agree to the terms of this license.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

-1
View File
@@ -1 +0,0 @@
banner.jpg - Photo by Lawrence Hookham on Unsplash
Binary file not shown.

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+4 -4
View File
@@ -1,7 +1,7 @@
{ {
"short_name": "m-tartari", "short_name": "m-tartari",
"name": "Michele Tartari", "name": "Compagnia d'Arme del Santo Luca",
"version": "1.3.0", "version": "1.0.0",
"description": "Robotics/Full Stack Software Engineer", "description": "Robotics/Full Stack Software Engineer",
"icons": [ "icons": [
{ {
@@ -19,6 +19,6 @@
], ],
"start_url": ".", "start_url": ".",
"display": "standalone", "display": "standalone",
"theme_color": "#1b1d27", "theme_color": "#1b271d",
"background_color": "#1b1d27" "background_color": "#1b271d"
} }
-18
View File
@@ -6,8 +6,6 @@ import RootLayout from 'components/templates/RouteTracker/index.js'
import Loading from 'components/molecules/LoadingScreen/index.js' import Loading from 'components/molecules/LoadingScreen/index.js'
const MainPage = React.lazy(() => import('components/pages/MainPage/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 ContactPage = React.lazy(() => import('components/pages/ContactPage/index.js'))
const PrivacyPage = React.lazy(() => import('components/pages/PrivacyPage/index.js')) const PrivacyPage = React.lazy(() => import('components/pages/PrivacyPage/index.js'))
const BusinessCardPage = React.lazy(() => import('components/pages/BusinessCardPage/index.js')) const BusinessCardPage = React.lazy(() => import('components/pages/BusinessCardPage/index.js'))
@@ -26,22 +24,6 @@ const router = createBrowserRouter([
</React.Suspense> </React.Suspense>
), ),
}, },
{
path: 'projects',
element: (
<React.Suspense fallback={<Loading />}>
<ProjectsPage />
</React.Suspense>
),
},
{
path: 'curriculum',
element: (
<React.Suspense fallback={<Loading />}>
<CurriculumPage />
</React.Suspense>
),
},
{ {
path: 'contacts', path: 'contacts',
element: ( 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 PolicyIcon from '@mui/icons-material/Policy'
import CookieIcon from '@mui/icons-material/Cookie' 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' import CookieConsent from 'components/molecules/CookieConsent/index.js'
type FooterProps = { type FooterProps = {
@@ -26,13 +26,13 @@ const Footer: React.FC<FooterProps> = ({ showCookieConsent = true }) => {
'@media print': { py: 3 }, '@media print': { py: 3 },
}}> }}>
<Stack direction="row" gap={2}> <Stack direction="row" gap={2}>
<LinkedInIconLink fontSize="large" href="https://www.linkedin.com/in/m-tartari/" /> <EmailIconLink fontSize="large" href="mailto:compagniasantoluca@gmail.com" />
<GitHubIconLink fontSize="large" href="https://www.github.com/m-tartari/" /> <FacebookIconLink fontSize="large" href="https://facebook.com/compagniadarmedelsantoluca/" />
<EmailIconLink fontSize="large" href="mailto:info@m-tartari.eu" /> <InstagramIconLink fontSize="large" href="https://www.instagram.com/compagnia_darme_santo_luca/" />
</Stack> </Stack>
<Typography variant="subtitle2" align="center" color="text.secondary" component="em" mt={3}> <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> </Typography>
<Stack mt={1}> <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 { Avatar, Box, IconButton, Stack, Typography } from '@mui/material'
import ExpandMore from '@mui/icons-material/ExpandMore' 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> }) => { const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) => {
return ( return (
@@ -13,7 +13,7 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
minHeight: '100vh', minHeight: '100vh',
boxShadow: '0 0.25em 0.5em 0 rgba(0, 0, 0, 0.25)', 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', backgroundPosition: 'center center',
backgroundAttachment: { xs: 'scroll !important', md: 'fixed' }, backgroundAttachment: { xs: 'scroll !important', md: 'fixed' },
backgroundSize: 'cover', backgroundSize: 'cover',
@@ -23,10 +23,10 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
wrap: 'wrap', wrap: 'wrap',
...(theme.palette.mode === 'dark' && { ...(theme.palette.mode === 'dark' && {
backgroundImage: 'url("images/banner-blur.webp")', backgroundImage: 'url("images/banner2.png")',
}), }),
...(theme.palette.mode === 'light' && { ...(theme.palette.mode === 'light' && {
backgroundImage: 'url("images/banner.webp")', backgroundImage: 'url("images/banner2.png")',
'&::before': { '&::before': {
content: '""', content: '""',
position: 'absolute', position: 'absolute',
@@ -66,35 +66,33 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
}, },
})}> })}>
<Box> <Box>
<Typography variant="h1"> <Typography component="h1" variant="h1" maxWidth="md">
Robotics Compagnia d'Arme{' '}
<br /> Engineer <Typography component="small" variant="h2">
</Typography> del
<Typography </Typography>{' '}
variant="h6" Santo Luca
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> </Typography>
<Typography variant="h3">Ferrara</Typography>
<Stack <Stack
direction="row" direction="row"
gap={2} gap={2}
mt={2} mt={2}
justifyContent={{ xs: 'center', md: 'end' }} justifyContent={{ xs: 'center', md: 'end' }}
color={t => (t.palette.mode === 'light' ? 'inherit' : 'text.secondary')}> color={t => (t.palette.mode === 'light' ? 'inherit' : 'text.secondary')}>
<LinkedInIconLink fontSize="large" href="https://www.linkedin.com/in/m-tartari/" /> <EmailIconLink fontSize="large" sx={{ ':hover': { color: 'text.primary' } }} href="mailto:compagniasantoluca@gmail.com" />
<GitHubIconLink fontSize="large" href="https://www.github.com/m-tartari/" /> <FacebookIconLink fontSize="large" sx={{ ':hover': { color: 'text.primary' } }} href="https://facebook.com/compagniadarmedelsantoluca/" />
<EmailIconLink fontSize="large" href="mailto:info@m-tartari.eu" /> <InstagramIconLink
fontSize="large"
sx={{ ':hover': { color: 'text.primary' } }}
href="https://www.instagram.com/compagnia_darme_santo_luca/"
/>
</Stack> </Stack>
</Box> </Box>
<Avatar <Avatar
alt="Avatar" alt="Avatar"
src="images/me.jpg" src="logo.png"
variant="square"
sx={{ sx={{
display: 'inline-block', display: 'inline-block',
verticalAlign: 'middle', verticalAlign: 'middle',
@@ -24,8 +24,9 @@ const PrivacyPolicy: React.FC = () => {
<SectionSubheader>Introduction</SectionSubheader> <SectionSubheader>Introduction</SectionSubheader>
<Typography component="p" color="textSecondary"> <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 Compagnia d'Arme del Santo Luca ("we", "our", or "us") respects your privacy and is committed to protecting your personal data. This privacy
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. 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> </Typography>
<SectionSubheader sx={{ mt: 4 }}>The Data We Collect About You</SectionSubheader> <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> <SectionSubheader sx={{ mt: 4 }}>Contact Us</SectionSubheader>
<Typography component="p" color="textSecondary"> <Typography component="p" color="textSecondary">
If you have any questions about this privacy policy or our privacy practices, please contact us at{' '} 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"> <Link color="textPrimary" href="mailto:compagniasantoluca@gmail.com" target="_blank" rel="noopener noreferrer">
privacy@m-tartari.eu compagniasantoluca@gmail.com
</Link> </Link>
. .
</Typography> </Typography>
@@ -10,7 +10,7 @@ type AnchorType = 'left' | 'top' | 'right' | 'bottom'
type Props = { type Props = {
image: string image: string
title: string title: string
caption: React.ReactNode caption?: React.ReactNode
children: React.ReactNode children: React.ReactNode
mobileImage?: string mobileImage?: string
ref?: React.ForwardedRef<HTMLSelectElement> ref?: React.ForwardedRef<HTMLSelectElement>
@@ -30,7 +30,7 @@ const Description = (props: Props) => {
justifyContent: 'center', justifyContent: 'center',
position: 'absolute', 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)', backdropFilter: 'blur(8px)',
bottom: '0', bottom: '0',
@@ -57,7 +57,7 @@ const Description = (props: Props) => {
display: 'flex', display: 'flex',
position: 'absolute', 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)', backdropFilter: 'blur(8px)',
top: '0', top: '0',
ml: 'auto', ml: 'auto',
@@ -86,7 +86,7 @@ const Description = (props: Props) => {
height: '102%', height: '102%',
width: '28em', width: '28em',
position: 'absolute', 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)', backdropFilter: 'blur(8px)',
right: '0', right: '0',
borderLeftWidth: theme.spacing(0.5), borderLeftWidth: theme.spacing(0.5),
@@ -108,7 +108,7 @@ const Description = (props: Props) => {
height: '102%', height: '102%',
width: '28em', width: '28em',
position: 'absolute', 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)', backdropFilter: 'blur(8px)',
left: '0', left: '0',
borderRightWidth: theme.spacing(0.5), borderRightWidth: theme.spacing(0.5),
+26 -21
View File
@@ -74,8 +74,15 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
textAlign: 'center', textAlign: 'center',
...(theme.palette.mode === 'light' && { backgroundColor: 'background.default' }), ...(theme.palette.mode === 'light' && { backgroundColor: 'background.default' }),
})}> })}>
<Typography variant="h6" sx={{ my: 2 }}> <Typography
Michele Tartari variant="h6"
sx={{
// fontFamily: '"Cloister Black", cursive',
textAlign: 'left',
m: 2,
}}>
Compagnia d'Arme <small>del</small>
<br /> Santo Luca
</Typography> </Typography>
<Divider /> <Divider />
<List> <List>
@@ -84,19 +91,14 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
<ListItemText primary="Home" /> <ListItemText primary="Home" />
</DrawerButton> </DrawerButton>
</ListItem> </ListItem>
<ListItem key="Projects" disablePadding> <ListItem key="Personaggi" disablePadding>
<DrawerButton component={RouterLink} to="/projects"> <DrawerButton component={RouterLink} to="/people">
<ListItemText primary="Projects" /> <ListItemText primary="Personaggi" />
</DrawerButton> </DrawerButton>
</ListItem> </ListItem>
<ListItem key="Curriculum" disablePadding> <ListItem key="Contatti" disablePadding>
<DrawerButton component={RouterLink} to="/curriculum">
<ListItemText primary="Curriculum" />
</DrawerButton>
</ListItem>
<ListItem key="Contacts" disablePadding>
<DrawerButton component={RouterLink} to="/contacts"> <DrawerButton component={RouterLink} to="/contacts">
<ListItemText primary="Contacts" /> <ListItemText primary="Contatti" />
</DrawerButton> </DrawerButton>
</ListItem> </ListItem>
</List> </List>
@@ -112,7 +114,7 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
backgroundColor: 'transparent', backgroundColor: 'transparent',
'@media print': { backgroundColor: 'background.default' }, '@media print': { backgroundColor: 'background.default' },
...(trigger && { ...(trigger && {
backgroundColor: 'hsla(230, 18%, 13%, 0.75)', backgroundColor: 'hsla(155, 18%, 13%, 0.75)',
backdropFilter: 'blur(8px)', backdropFilter: 'blur(8px)',
boxShadow: theme.shadows[4], 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' }, // [theme.breakpoints.up('md')]: { width: theme => theme.breakpoints.values.lg, mx: 'auto' },
}}> }}>
<IconButton <IconButton
color="primary"
aria-label="open drawer" aria-label="open drawer"
edge="start" edge="start"
onClick={handleDrawerToggle} onClick={handleDrawerToggle}
@@ -154,14 +155,13 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
[theme.breakpoints.down('md')]: { mx: 'auto' }, [theme.breakpoints.down('md')]: { mx: 'auto' },
[theme.breakpoints.up('md')]: { mr: 'auto' }, [theme.breakpoints.up('md')]: { mr: 'auto' },
})}> })}>
Michele Tartari Compagnia d'Arme del Santo Luca
</AppBarLink> </AppBarLink>
<Stack component="div" direction="row" spacing={2} sx={{ display: { xs: 'none', md: 'flex', alignItems: 'center' } }}> <Stack component="div" direction="row" spacing={2} sx={{ display: { xs: 'none', md: 'flex', alignItems: 'center' } }}>
<AppBarLink to="/">Home</AppBarLink> <AppBarLink to="/">Home</AppBarLink>
<AppBarLink to="/projects">Projects</AppBarLink> <AppBarLink to="/people">Personaggi</AppBarLink>
<AppBarLink to="/curriculum">Curriculum</AppBarLink>
<Button component={RouterLink} to="/contacts" color="primary" variant="contained" sx={{ textTransform: 'none' }}> <Button component={RouterLink} to="/contacts" color="primary" variant="contained" sx={{ textTransform: 'none' }}>
<Typography variant="h6">Hire me</Typography> <Typography variant="h6">Contattaci</Typography>
</Button> </Button>
</Stack> </Stack>
</Toolbar> </Toolbar>
@@ -173,10 +173,15 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
ModalProps={{ ModalProps={{
keepMounted: true, // Better open performance on mobile. keepMounted: true, // Better open performance on mobile.
}} }}
sx={{ sx={theme => ({
display: { xs: 'block', md: 'none' }, 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}
</Drawer> </Drawer>
</> </>
@@ -12,7 +12,7 @@ vi.mock('./envVars.js', () => ({
VAT: 'Test VAT', VAT: 'Test VAT',
PHONE: '+123456789', PHONE: '+123456789',
EMAIL: 'test@example.com', EMAIL: 'test@example.com',
LINKEDIN: 'testlinkedin', FACEBOOK: 'testfacebook',
})) }))
// Mock window.print // Mock window.print
@@ -59,7 +59,7 @@ describe('BusinessCardPage', () => {
const websiteLink = screen.getByText('www.m-tartari.eu').closest('a') const websiteLink = screen.getByText('www.m-tartari.eu').closest('a')
expect(websiteLink).toHaveAttribute('href', 'https://www.m-tartari.eu') expect(websiteLink).toHaveAttribute('href', 'https://www.m-tartari.eu')
// Check LinkedIn link // Check Facebook Link
const linkedinLink = screen.getByText('testlinkedin').closest('a') const linkedinLink = screen.getByText('testlinkedin').closest('a')
expect(linkedinLink).toHaveAttribute('href', 'https://www.linkedin.com/in/testlinkedin/') expect(linkedinLink).toHaveAttribute('href', 'https://www.linkedin.com/in/testlinkedin/')
}) })
@@ -1,7 +1,7 @@
/* istanbul ignore file */ /* istanbul ignore file */
export const NAME = import.meta.env.VITE_BC_NAME || '[FULL NAME]' export const NAME = import.meta.env.VITE_BC_NAME || '[FULL NAME]'
export const POSITION = import.meta.env.VITE_BC_POSITION || '[POSITION]' export const POSITION = import.meta.env.VITE_BC_POSITION || 'Ass. di rievocazione storica affiliata C.E.R.S. (XIV-XV secolo)'
export const VAT = import.meta.env.VITE_BC_VAT || '[VAT NUMBER]' export const PHONE = import.meta.env.VITE_BC_PHONE || null
export const PHONE = import.meta.env.VITE_BC_PHONE || '[Redacted for privacy]'
export const EMAIL = import.meta.env.VITE_BC_EMAIL || '[Redacted for privacy]' 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 {
import { Email, LinkedIn, Print, PhoneInTalk, Public } from '@mui/icons-material' 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 { Page } from 'components/templates/index.js'
import typography from 'style/typography/index.js' import typography from 'style/typography/index.js'
@@ -43,8 +57,9 @@ type BusinessCardProps = {
mode?: 'light' | 'dark' mode?: 'light' | 'dark'
src: string src: string
alt?: string alt?: string
srcSx?: SxProps<Theme>
} & PaperProps } & PaperProps
const BusinessCard = ({ mode = 'dark', src, alt, sx, ...props }: BusinessCardProps) => ( const BusinessCard = ({ mode = 'dark', src, srcSx, alt, sx, ...props }: BusinessCardProps) => (
<ThemeProvider theme={theme[mode]}> <ThemeProvider theme={theme[mode]}>
<Paper <Paper
className="print-business-card" className="print-business-card"
@@ -85,6 +100,7 @@ const BusinessCard = ({ mode = 'dark', src, alt, sx, ...props }: BusinessCardPro
height: 'fit-content', height: 'fit-content',
objectFit: 'cover', objectFit: 'cover',
// borderRadius: '50%', // borderRadius: '50%',
...srcSx,
}} }}
/> />
@@ -119,14 +135,7 @@ const BusinessCardPage = () => {
gap: 0, gap: 0,
}, },
}}> }}>
<BusinessCard src="/fav-icon.svg" alt="logo"> <BusinessCard src="/logo_text.png" alt="logo" srcSx={{ width: '100%' }} />
<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="/images/qr.svg" alt="Qr Code" mode="light"> <BusinessCard src="/images/qr.svg" alt="Qr Code" mode="light">
<Stack <Stack
@@ -146,19 +155,24 @@ const BusinessCardPage = () => {
{env.NAME} {env.NAME}
</Typography> </Typography>
<Typography variant="caption" color="text.secondary" fontSize="0.55rem" mb={0.5}> <Typography variant="caption" color="text.secondary" fontSize="0.55rem" mb={0.5}>
{env.VAT} {env.POSITION}
</Typography> </Typography>
<TypographyLink icon={PhoneInTalk} href={`tel:${env.PHONE.replace(/[^\d+]/g, '').replace(/^\+?/, '+')}`}> {env.PHONE != null && (
{env.PHONE} <TypographyLink icon={PhoneInTalk} href={`tel:${env.PHONE.replace(/[^\d+]/g, '').replace(/^\+?/, '+')}`}>
</TypographyLink> {env.PHONE}
</TypographyLink>
)}
<TypographyLink icon={Email} href={`mailto:${env.EMAIL}`}> <TypographyLink icon={Email} href={`mailto:${env.EMAIL}`}>
{env.EMAIL} {env.EMAIL}
</TypographyLink> </TypographyLink>
<TypographyLink icon={Public} href="https://www.m-tartari.eu"> <TypographyLink icon={Public} href="https://www.compagniadarmedelsantoluca.it/">
www.m-tartari.eu www.compagniadarmedelsantoluca.it
</TypographyLink> </TypographyLink>
<TypographyLink icon={LinkedIn} href={`https://www.linkedin.com/in/${env.LINKEDIN}/`}> <TypographyLink icon={Facebook} href={`https://facebook.com/${env.FACEBOOK}/`}>
{env.LINKEDIN} @{env.FACEBOOK}
</TypographyLink>
<TypographyLink icon={Instagram} href={`https://www.instagram.com/${env.INSTAGRAM}/`}>
@{env.INSTAGRAM}
</TypographyLink> </TypographyLink>
</Stack> </Stack>
</BusinessCard> </BusinessCard>
@@ -17,22 +17,22 @@ describe('ContactPage', () => {
expect(screen.getAllByText('Contacts')).toHaveLength(2) // Page title and the Appbar drawer link expect(screen.getAllByText('Contacts')).toHaveLength(2) // Page title and the Appbar drawer link
expect(screen.getByLabelText('Email link')).toBeInTheDocument() expect(screen.getByLabelText('Email link')).toBeInTheDocument()
expect(screen.getByLabelText('LinkedIn link')).toBeInTheDocument() expect(screen.getByLabelText('Facebook Link')).toBeInTheDocument()
expect(screen.getByLabelText('GitHub link')).toBeInTheDocument() expect(screen.getByLabelText('Instagram link')).toBeInTheDocument()
}) })
test.each([ test.each([
{ {
label: 'Email link', label: 'Email link',
href: 'mailto:info@m-tartari.eu', href: 'mailto:compagniasantoluca@gmail.com',
}, },
// { // {
// label: 'LinkedIn link', // label: 'Facebook Link',
// href: 'https://www.linkedin.com/in/m-tartari/', // href: 'https://facebook.com/compagniadarmedelsantoluca/',
// }, // },
// { // {
// label: 'GitHub link', // label: 'Instagram link',
// href: 'https://www.github.com/m-tartari/', // href: 'https://www.instagram.com/compagnia_darme_santo_luca/',
// }, // },
])('leads to the right place when the $label is clicked', ({ label, href }) => { ])('leads to the right place when the $label is clicked', ({ label, href }) => {
render(<ContactPage />) render(<ContactPage />)
@@ -1,7 +1,7 @@
import { Link, List, ListItem, Stack, Typography } from '@mui/material' import { Link, List, ListItem, Stack, Typography } from '@mui/material'
import DraftsIcon from '@mui/icons-material/Drafts' import DraftsIcon from '@mui/icons-material/Drafts'
import LinkedInIcon from '@mui/icons-material/LinkedIn' import FacebookIcon from '@mui/icons-material/Facebook'
import GitHubIcon from '@mui/icons-material/GitHub' import Instagram from '@mui/icons-material/Instagram'
import { Page } from 'components/templates/index.js' import { Page } from 'components/templates/index.js'
@@ -39,29 +39,29 @@ const ListItemLink: React.FC<ListItemProps> = ({ children, ...props }) => (
const ContactPage = () => { const ContactPage = () => {
return ( return (
<Page title="Contacts"> <Page title="Contatti">
<Typography align="left" variant="h6"> <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> </Typography>
<List> <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" /> <DraftsIcon fontSize="large" />
<Typography variant="h6" ml={2}> <Typography variant="h6" ml={2}>
info compagniasantoluca
<wbr /> <wbr />
@m-tartari.eu @gmail.com
</Typography> </Typography>
</ListItemLink> </ListItemLink>
<ListItemLink aria-label="LinkedIn link" href="https://www.linkedin.com/in/m-tartari/"> <ListItemLink aria-label="Facebook Link" href="https://facebook.com/compagniadarmedelsantoluca">
<LinkedInIcon fontSize="large" /> <FacebookIcon fontSize="large" />
<Typography variant="h6" ml={2}> <Typography variant="h6" ml={2}>
m-tartari @compagniadarmedelsantoluca
</Typography> </Typography>
</ListItemLink> </ListItemLink>
<ListItemLink aria-label="GitHub link" href="https://www.github.com/m-tartari/"> <ListItemLink aria-label="Instagram link" href="https://www.instagram.com/compagnia_darme_santo_luca/">
<GitHubIcon fontSize="large" /> <Instagram fontSize="large" />
<Typography variant="h6" ml={2}> <Typography variant="h6" ml={2}>
m-tartari @compagnia_darme_santo_luca
</Typography> </Typography>
</ListItemLink> </ListItemLink>
</List> </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 React from 'react'
import { Box, Stack, Typography } from '@mui/material' import { Box } from '@mui/material'
import { ViewportProvider } from 'components/utils/viewport' 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' import { Footer, Hero, Toolbar, ProjectSpotlight } from 'components/molecules/index.js'
const MainPage = () => { const MainPage = () => {
React.useEffect(() => { React.useEffect(() => {
document.title = 'Michele Tartari' document.title = "Compagnia d'Arme del Santo Luca"
}, []) }, [])
const refIITLinfa = React.useRef<HTMLSelectElement>(null) const refAboutUs = React.useRef<HTMLSelectElement>(null)
const refIITModular = React.useRef<HTMLSelectElement>(null) const refTeaching = React.useRef<HTMLSelectElement>(null)
const refIITCalibration = React.useRef<HTMLSelectElement>(null) const refTraining = React.useRef<HTMLSelectElement>(null)
const refWUTThesis = React.useRef<HTMLSelectElement>(null)
return ( return (
<ViewportProvider> <ViewportProvider>
<Box aria-label="page" sx={{ flexGrow: 1 }}> <Box aria-label="page" sx={{ flexGrow: 1 }}>
<Toolbar /> <Toolbar />
<Hero scrollTarget={refIITLinfa} /> <Hero scrollTarget={refAboutUs} />
{/* 1 IIT - Linfa */} {/* 1 Chi Siamo */}
<ProjectSpotlight <ProjectSpotlight
ref={refIITLinfa} ref={refAboutUs}
scrollTarget={refIITModular} scrollTarget={refTeaching}
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}
anchor="right" anchor="right"
// anchor="left" // anchor="left"
image="images/IIT_Modular.png" image="images/about-us.png"
mobileImage="images/IIT_Modular_Mobile.webp" mobileImage="images/about-us.png"
title="Revamping HHCM's Modular: Swift Generation of Modular Robot Models" title="Chi Siamo">
caption={ La Compagnia d'Arme del Santo Luca è un gruppo di rievocazione storica di Ferrara affiliato al C.E.R.S. (Consorzio Europeo Rievocazioni
<Stack direction="row" gap={1} alignItems="center"> Storiche). Il periodo rievocato dalla Compagnia è il tardo XIV secolo (1380-1410).
<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.
</ProjectSpotlight> </ProjectSpotlight>
{/* 3 IIT - Motor Calibration */} {/* 2. Attività didattiche */}
<ProjectSpotlight <ProjectSpotlight ref={refTeaching} scrollTarget={refTraining} anchor="left" image="images/didattica.png" title="Attività didattiche">
ref={refIITCalibration} La Compagnia d'Arme del Santo Luca propone percorsi didattici sulla vita nel Medioevo attraverso la spiegazione delle attività che venivano
scrollTarget={refWUTThesis} svolte all'interno del campo armato e che erano parte integrante della vita dell'uomo d'arme dell'epoca.
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.
</ProjectSpotlight> </ProjectSpotlight>
{/* 4 WUT - Master Thesis */} {/* 3. Scuola d'arme */}
<ProjectSpotlight <ProjectSpotlight ref={refTraining} anchor="bottom" image="images/battle.png" mobileImage="images/battle.png" title="Scuola d'arme">
ref={refWUTThesis} Altra attività di rilevante importanza è la scherma medievale. Il gruppo in arme si allena settimanalmente per studiare e riproporre i
anchor="bottom" trattati di scherma più importanti, dedicandosi allo studio e la messa in pratica delle tecniche di combattimento con differenti tipologie
image="images/thesis.jpg" di armi.
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.
</ProjectSpotlight> </ProjectSpotlight>
<Footer /> <Footer />
</Box> </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 MainPage } from './MainPage'
export { default as ContactPage } from './ContactPage' 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 BusinessCardPage } from './BusinessCardPage'
export { default as ErrorPage } from './ErrorPage' export { default as ErrorPage } from './ErrorPage'
+1 -1
View File
@@ -27,7 +27,7 @@ describe('Page component', () => {
expect(screen.getByText('Test Content')).toBeInTheDocument() expect(screen.getByText('Test Content')).toBeInTheDocument()
// sets the document title correctly // 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', () => { 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 }) => { const Page: React.FC<PageProps> = ({ title, children, showCookieConsent, ...props }) => {
React.useEffect(() => { React.useEffect(() => {
if (title) { if (title) {
document.title = `Michele Tartari - ${title}` document.title = `Compagnia d'Arme del Santo Luca - ${title}`
} }
}, [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 { html {
scroll-behavior: smooth; scroll-behavior: smooth;
} }
body { body {
margin: 0; margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', font-family:
sans-serif; -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
+3 -8
View File
@@ -1,12 +1,7 @@
/* istanbul ignore file */ /* istanbul ignore file */
import '@fontsource/oswald/700.css' import '@fontsource/eb-garamond' // Regular 400, SemiBold 600
import '@fontsource/oswald/500.css' import '@fontsource/unifrakturcook' // Bold 700
import '@fontsource/oswald/400.css' import '@fontsource/medievalsharp' // Regular
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 React from 'react' import React from 'react'
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client'
+4 -4
View File
@@ -3,7 +3,7 @@ import { PaletteOptions } from '@mui/material'
export const dark: PaletteOptions = { export const dark: PaletteOptions = {
mode: 'dark', mode: 'dark',
primary: { primary: {
main: '#e44c65', // Rouge Red (similar) main: '#20b540', // Rouge Red (similar)
// main:'#df4661', // Pantone PMS 198 C // main:'#df4661', // Pantone PMS 198 C
}, },
secondary: { secondary: {
@@ -11,13 +11,13 @@ export const dark: PaletteOptions = {
// main: '#3a5dae', // Pantone 7455 C Color // main: '#3a5dae', // Pantone 7455 C Color
}, },
background: { background: {
default: '#101018', default: '#101810',
paper: '#1b1d27', paper: '#1b271d',
}, },
} }
export const light: PaletteOptions = { export const light: PaletteOptions = {
primary: { primary: {
main: '#AC1D1B', // Casual Red main: '#20b540', // Casual Red
// main: '#AF231C' // Pantone 2350 C // main: '#AF231C' // Pantone 2350 C
// main: '#AB2328' // Pantone 7621 C // main: '#AB2328' // Pantone 7621 C
}, },
+15 -9
View File
@@ -1,25 +1,31 @@
import { TypographyVariantsOptions } from '@mui/material' import { TypographyVariantsOptions } from '@mui/material'
const typography: TypographyVariantsOptions = { const typography: TypographyVariantsOptions = {
fontFamily: 'Inter, sans-serif', // Base font for headings // ---------- Global defaults ----------
fontFamily: '"EB Garamond", serif',
// ---------- Headings ----------
h1: { h1: {
fontFamily: 'Oswald, sans-serif', fontFamily: '"Cloister Black", cursive',
textTransform: 'uppercase',
fontWeight: 700, fontWeight: 700,
}, },
h2: { h2: {
fontFamily: 'Oswald, sans-serif', fontFamily: '"Cloister Black", cursive',
textTransform: 'uppercase',
fontWeight: 700, fontWeight: 700,
}, },
h3: { h3: {
fontFamily: 'Oswald, sans-serif', fontFamily: '"Cloister Black", cursive',
fontWeight: 700, fontWeight: 700,
}, },
h4: { // ---------- Buttons ----------
fontFamily: 'Oswald, sans-serif', button: {
fontWeight: 700, 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_VAT: string
readonly VITE_BC_PHONE: string readonly VITE_BC_PHONE: string
readonly VITE_BC_EMAIL: string readonly VITE_BC_EMAIL: string
readonly VITE_BC_LINKEDIN: string readonly VITE_BC_FACEBOOK: string
} }
interface ImportMeta { interface ImportMeta {