Merge pull request #23 from Compagnia-d-Arme-del-Santo-Luca/feat/pages/activities

✨ feat: add activities page
This commit is contained in:
2026-04-11 16:39:35 +02:00
committed by GitHub
20 changed files with 314 additions and 28 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 2.5 MiB

+9
View File
@@ -7,6 +7,7 @@ import Loading from 'components/molecules/LoadingScreen/index.js'
const MainPage = React.lazy(() => import('components/pages/MainPage/index.js'))
const PeoplePage = React.lazy(() => import('components/pages/PeoplePage/index.js'))
const ActivitiesPage = React.lazy(() => import('components/pages/ActivitiesPage/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'))
@@ -33,6 +34,14 @@ const router = createBrowserRouter([
</React.Suspense>
),
},
{
path: 'activities',
element: (
<React.Suspense fallback={<Loading />}>
<ActivitiesPage />
</React.Suspense>
),
},
{
path: 'contacts',
element: (
+1 -1
View File
@@ -1,6 +1,6 @@
import { Typography, TypographyProps } from '@mui/material'
import { FC } from 'react'
const Header: FC<TypographyProps> = props => <Typography variant="h4" color="primary.main" component="h2" gutterBottom {...props} />
const Header: FC<TypographyProps> = props => <Typography variant="h4" component="h2" gutterBottom {...props} />
export default Header
@@ -39,13 +39,13 @@ const Description = (props: Props) => {
borderTopColor: theme.palette.primary.main,
p: `${theme.spacing(7)} ${theme.spacing(5)} ${theme.spacing(5.5)} ${theme.spacing(5)}`,
})}>
<Grid container spacing={2} maxWidth="xl">
<Grid size={4}>
<Typography variant="h4">{props.title}</Typography>
{props.caption}
</Grid>
<Grid size={8}>{props.children}</Grid>
</Grid>
<Box maxWidth="xl">
<Typography variant="h4" mb={3}>
{props.title}
</Typography>
{props.caption}
<Box mt={3}>{props.children}</Box>
</Box>
</Box>
)
case 'top':
+140
View File
@@ -0,0 +1,140 @@
import React from 'react'
import { Box, BoxProps, Typography } from '@mui/material'
import SectionHeader from 'components/atoms/SectionHeader/index.js'
interface SectionProps extends BoxProps {
variant?: 'primary' | 'secondary'
title?: string
headline?: string
imageUrl?: string
imageAlt?: string
imageCaption?: React.ReactNode
children?: React.ReactNode
}
const Section: React.FC<SectionProps> = ({ variant = 'primary', imageUrl, imageAlt, imageCaption, children, ...props }) => {
return (
<Box
component="section"
sx={{
margin: 0,
px: { xs: 1, sm: 2, md: 0 },
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: variant === 'primary' ? 'background.default' : 'background.paper',
}}>
<Box
{...props}
sx={{
py: 5,
width: theme => theme.breakpoints.values.lg,
...props.sx,
}}>
{props.title && (
<SectionHeader
sx={[
theme => ({
paddingBottom: 3,
[theme.breakpoints.only('md')]: {
width: theme.breakpoints.values.md,
maxWidth: 'calc(100% - 2em)',
},
[theme.breakpoints.up('lg')]: {
width: theme.breakpoints.values.lg,
},
}),
theme =>
theme.applyStyles('dark', {
paddingBottom: 3,
[theme.breakpoints.only('md')]: {
width: theme.breakpoints.values.md,
maxWidth: 'calc(100% - 2em)',
},
[theme.breakpoints.up('lg')]: {
width: theme.breakpoints.values.lg,
},
}),
]}>
{props.title}
</SectionHeader>
)}
{props.headline && (
<Typography
variant="body1"
color="text.secondary"
sx={theme => ({
paddingBottom: 3,
[theme.breakpoints.only('md')]: {
width: theme.breakpoints.values.md,
maxWidth: 'calc(100% - 4em)',
},
[theme.breakpoints.up('lg')]: {
width: theme.breakpoints.values.lg,
},
})}>
{props.headline}
</Typography>
)}
<Box
sx={theme => ({
display: 'flex',
justifyContent: 'center',
[theme.breakpoints.down('md')]: {
// minHeight: imageUrl && '60vh',
flexDirection: props.title || props.headline ? 'column' : 'column-reverse',
alignItems: 'center',
gap: 3,
},
[theme.breakpoints.only('md')]: {
mx: 'auto',
width: theme.breakpoints.values.md,
maxWidth: 'calc(100% - 4em)',
flexDirection: variant === 'primary' ? 'row-reverse' : 'row',
alignItems: 'center',
gap: 5,
},
[theme.breakpoints.up('lg')]: {
mx: 'auto',
width: theme.breakpoints.values.lg,
flexDirection: variant === 'primary' ? 'row-reverse' : 'row',
alignItems: 'center',
gap: 5,
},
})}>
{imageUrl &&
(imageCaption ? (
<Box sx={{ flex: 4, flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
<Box component="img" src={imageUrl} alt={imageAlt} width="100%" />
{imageCaption}
</Box>
) : (
<Box
component="img"
src={imageUrl}
alt={imageAlt}
sx={{ width: { xs: '100%', md: '40%' }, flex: 4, flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}
/>
))}
<Box
sx={{
flex: 6,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignContent: 'center',
gap: 1,
...props.sx,
}}>
{children}
</Box>
</Box>
</Box>
</Box>
)
}
export default Section
@@ -91,6 +91,11 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
<ListItemText primary="Home" />
</DrawerButton>
</ListItem>
<ListItem key="Attività" disablePadding>
<DrawerButton component={RouterLink} to="/activities">
<ListItemText primary="Attività" />
</DrawerButton>
</ListItem>
<ListItem key="Personaggi" disablePadding>
<DrawerButton component={RouterLink} to="/people">
<ListItemText primary="Personaggi" />
@@ -159,6 +164,7 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
</AppBarLink>
<Stack component="div" direction="row" spacing={2} sx={{ display: { xs: 'none', md: 'flex', alignItems: 'center' } }}>
<AppBarLink to="/">Home</AppBarLink>
<AppBarLink to="/activities">Attività</AppBarLink>
<AppBarLink to="/people">Personaggi</AppBarLink>
<Button component={RouterLink} to="/contacts" color="primary" variant="contained" sx={{ textTransform: 'none' }}>
<Typography variant="h6">Contattaci</Typography>
@@ -0,0 +1,33 @@
import { screen } from '@testing-library/react'
// import userEvent from '@testing-library/user-event'
import { renderWithRouter as render } from 'components/utils/tests'
import ActivitiesPage from '.'
// vi.stubGlobal('open', vi.fn())
describe('Activities Page', () => {
// const open = vi.spyOn(window, 'open')
it('Should render the page correctly on desktop', async () => {
await render(<ActivitiesPage />)
expect(screen.getAllByText('Attività')).toHaveLength(3) // title, appbar button and appbar drawer button
expect(screen.getByText('Percorsi didattici')).toBeInTheDocument()
expect(screen.getByText('Sartoria')).toBeInTheDocument()
expect(screen.getByText('Organizzazione eventi')).toBeInTheDocument()
})
it('Should render the page correctly on mobile', async () => {
// Set the window size to mobile (Galaxy Note 20 Android 11)
window.innerWidth = 412
window.innerHeight = 915
await render(<ActivitiesPage />)
expect(screen.getAllByText('Attività')).toHaveLength(3) // title, appbar button and appbar drawer button
expect(screen.getByText('Percorsi didattici')).toBeInTheDocument()
expect(screen.getByText('Sartoria')).toBeInTheDocument()
expect(screen.getByText('Organizzazione eventi')).toBeInTheDocument()
})
})
@@ -0,0 +1,90 @@
import { Typography } from '@mui/material'
import Section from 'components/molecules/Section/index.js'
import { Page } from 'components/templates/index.js'
const ActivitiesPage = () => {
return (
<Page title="Attività">
<Section title="Percorsi didattici" sx={{ pb: 0 }}>
<Typography variant="body1" color="text.secondary">
La Compagnia propone percorsi didattici dedicati alla scoperta della vita nel Basso Medioevo, illustrando le attività svolte all'interno del
campo armato e il loro ruolo nella quotidianità dei soldati. Attraverso dimostrazioni pratiche e spiegazioni storiche, vengono presentati
armamenti, addestramento, medicina medievale e aspetti della vita civile, offrendo un'esperienza educativa coinvolgente.
</Typography>
</Section>
<Section imageUrl="images/activities/2021_06_15-sartoria.jpg" imageAlt="Sartoria">
<Typography variant="h5">Sartoria</Typography>
<Typography variant="body1" color="text.secondary">
Nel Medioevo l'abbigliamento aveva un valore profondo: i vestiti non servivano solo a coprire il corpo, ma raccontavano chi eravamo, da dove
venivamo e quale ruolo si aveva nella società. La Compagnia d'Arme del Santo Luca realizza abiti ispirati alle forme e alle tecniche
dell'epoca, impiegando tagli, colori e materiali che riflettono le pratiche storiche. Dalle tuniche e vesti di uso quotidiano alle fogge più
ricercate per dame e cavalieri, ogni capo è scelto per mostrare come tessuti come lana, lino e seta erano trasformati in elementi di
abbigliamento che rispecchiavano funzioni, status e gusti del tempo. L'abbigliamento diventa così una finestra sul mondo medievale, fatta di
forme, significati e dettagli che accompagnavano la vita di tutti i giorni e le occasioni speciali.
</Typography>
</Section>
<Section variant="secondary" imageUrl="images/activities/cucina.png" imageAlt="Cucina">
<Typography variant="h5">Cucina</Typography>
<Typography variant="body1" color="text.secondary">
La cucina medievale è un mondo a parte, fatto di sapori, profumi e tecniche di cottura che oggi ci sembrano lontani ma che all'epoca erano
all'ordine del giorno. La compagnia ha una cucina attrezzata e funzionale, con la quale è in grado di preparare e spiegare piatti tipici
dell'epoca, utilizzando ingredienti e metodi di cottura autentici all'inteno di eventi, manifestazioni e rievocazioni storiche.
</Typography>
<Typography variant="body1" color="text.secondary">
Su rirchiesta la compagnia può organizzare lezioni di cucina medievale, dove i partecipanti possono imparare a conoscere e preparare piatti
tipici dell'epoca.
</Typography>
</Section>
<Section imageUrl="images/activities/2021_05_30-cerusico.jpg" imageAlt="Cucina">
<Typography variant="h5">Cerusico</Typography>
<Typography variant="body1" color="text.secondary">
Nell'accampamento medievale la figura del cerusico rivestiva un ruolo fondamentale: era colui che interveniva sulle ferite, conosceva gli
strumenti e sapeva riconoscere le erbe utili a curare i piccoli mali della vita quotidiana. La Compagnia d'Arme del Santo Luca porta in vita
questa figura storica attraverso l'allestimento di postazioni didattiche in cui vengono illustrati strumenti, rimedi e pratiche mediche del
periodo, offrendo uno sguardo autentico su come si affrontavano salute e guarigione nel Medioevo, con attenzione alle conoscenze e alle
tecniche del tempo.
</Typography>
</Section>
<Section variant="secondary" imageUrl="images/activities/2021_05_30-pilgrimage.jpg" imageAlt="Cucina">
<Typography variant="h5">Pellegrinaggio</Typography>
<Typography variant="body1" color="text.secondary">
Il pellegrinaggio nel Medioevo era molto più di un viaggio: era un'esperienza di spiritualità, cultura e incontro. All'interno delle nostre
rievocazioni la Compagnia d'Arme del Santo Luca ricrea gli aspetti di questi cammini antichi, raccontando come si muovevano i pellegrini,
quali mete raggiungevano e quali usanze accompagnavano il loro percorso. Tra storie di santi, architetture sacre e tappe di sosta, il
pellegrinaggio diventa un modo coinvolgente per comprendere le motivazioni profonde che spingevano uomini e donne a intraprendere grandi
traversate a piedi nel cuore dell'Europa medievale.
</Typography>
</Section>
<Section imageUrl="images/activities/2019_02_24-Armi.jpg" imageAlt="Cucina">
<Typography variant="h5">Armi e armature</Typography>
<Typography variant="body1" color="text.secondary">
Alla base della vita militare medievale c'erano le armi e le armature: oggetti di straordinaria ingegneria e simboli di uno stile di
combattimento e di vita che hanno dominato i campi di battaglia per secoli. La Compagnia d'Arme del Santo Luca possiede e utilizza repliche
storicamente documentate di spade, lance, elmi e corazze, e propone dimostrazioni che illustrano l'evoluzione e l'uso di questi elementi,
spiegando materiali, funzione e peculiarità. Lo studio delle armi e delle armature è affiancato da approfondimenti sul contesto bellico e
sociale del tempo, per restituire un quadro completo delle tecniche e delle strategie che contraddistinsero l'arte della guerra medievale.
</Typography>
</Section>
<Section
variant="secondary"
title="Organizzazione eventi"
headline="La compagnia unisce professionalità e creatività per nell'ideare ed organizzare eventi di stampo medievale. Offre la possibilità di curare singoli spettacoli o intere manifestazioni in base alle esigenze dei singoli organizzatori."
imageUrl="images/activities/2018_04_21_gorizia.jpg"
imageAlt="Gorizia 2018">
<Typography variant="body1" color="text.secondary">
La Compagnia d'Arme del Santo Luca partecipa a una varietà di manifestazioni e rievocazioni storiche, collaborando con enti pubblici,
associazioni culturali e festival dedicati alla storia medievale e rinascimentale. Ogni evento è per noi l'occasione di portare il passato
nel presente attraverso cortei, scene di vita, dimostrazioni e spettacoli che raccontano con rigore e passione usi, costumi e valori di
secoli trascorsi. La nostra esperienza nella progettazione e gestione di eventi storici ci permette di trasformare ogni appuntamento in un
momento coinvolgente, capace di affascinare il pubblico, valorizzare i contesti storici e offrire ai visitatori un'immersione autentica
nella cultura medievale. Partecipiamo con entusiasmo a rievocazioni, mercati storici, celebrazioni di battaglie, e altre iniziative in cui
storia e spettacolo si intrecciano, contribuendo a creare un'esperienza viva, educativa e memorabile per tutti i presenti.
</Typography>
</Section>
</Page>
)
}
export default ActivitiesPage
@@ -39,7 +39,13 @@ const ListItemLink: React.FC<ListItemProps> = ({ children, ...props }) => (
const ContactPage = () => {
return (
<Page title="Contatti">
<Page
title="Contatti"
sx={{
width: theme => theme.breakpoints.values.lg,
px: 'auto',
mx: 'auto',
}}>
<Typography align="left" variant="h6">
Sentiti libero di contattatarci con uno qualsiasi dei seguenti:
</Typography>
@@ -14,7 +14,6 @@ describe('Main page', () => {
// Make sure the project spotlights are present for both desktop and mobile
expect(screen.getAllByText('Chi Siamo')).toHaveLength(2)
expect(screen.getAllByText('Vita Civile')).toHaveLength(2)
expect(screen.getAllByText('Attività Didattiche')).toHaveLength(2)
expect(screen.getAllByText('Vita Militare')).toHaveLength(2)
})
})
+5 -9
View File
@@ -39,21 +39,17 @@ const MainPage = () => {
</ProjectSpotlight>
{/* 2. Attività didattiche */}
<ProjectSpotlight ref={refTeaching} scrollTarget={refTraining} anchor="left" image="images/didattica.png" title="Vita Civile">
<Typography>
<Typography pt={1}>
La ricostruzione della vita civile rappresenta un elemento fondamentale delle attività della Compagnia. Non rappresetiamo solo soldati, ma
anche tutte le altre figure che vivevano e operavano al seguito di una compagnie d'arme: cuochi, artigiani, religiosi, pellegrini e
personale di supporto, tutti riproposti attraverso abiti, strumenti e gesti quotidiani ricostruiti su base storica. Particolare attenzione
è dedicata agli aspetti della vita materiale: la preparazione dei cibi, l'organizzazione del banchetto, la sartoria storica, le pratiche
mediche e devozionali ed il viaggio.
</Typography>
<Typography variant="h4" pt={3}>
Attività Didattiche
</Typography>
<Typography pt={2}>
La Compagnia propone percorsi didattici dedicati alla scoperta della vita nel Basso Medioevo, illustrando le attività svolte all'interno
del campo armato e il loro ruolo nella quotidianità dei soldati. Attraverso dimostrazioni pratiche e spiegazioni storiche, vengono
presentati armamenti, addestramento, medicina medievale e aspetti della vita civile, offrendo un'esperienza educativa coinvolgente.
<Typography pt={1}>
La Compagnia propone percorsi didattici dedicati alla scoperta della vita nel Basso Medioevo, attraverso dimostrazioni pratiche e
spiegazioni storiche, vengono presentati armamenti, addestramento, medicina medievale e aspetti della vita civile, offrendo un'esperienza
educativa coinvolgente.
</Typography>
</ProjectSpotlight>
{/* 3. Scuola d'arme */}
+8 -2
View File
@@ -210,8 +210,14 @@ const ProjectsPage = () => {
setDescription(null)
}
return (
<Page title="Personaggi">
<Typography pb={2}>
<Page
title="Personaggi"
sx={{
width: theme => theme.breakpoints.values.lg,
px: 'auto',
mx: 'auto',
}}>
<Typography px={{ xs: undefined, md: 2 }} pb={2}>
Tutti i Personaggi storici della Compagnia sono realmente vissuti ed esistono attendibili fonti bibliografiche. Il gruppo è suddiviso per
classi sociali: Uomini d'arme, Artigiani, Nobili Cavalieri, Nobildonne, uomini e donne del popolo; Ogni Personaggio, il suo ruolo e il suo
comportamento sono fondamentali alla ricostruzione di uno spaccato della vita di un campo d'arme del tardo XIV Secolo.
+8 -7
View File
@@ -34,8 +34,9 @@ const Page: React.FC<PageProps> = ({ title, children, showCookieConsent, ...prop
aria-label="page-title"
textAlign="center"
sx={{
mt: 6,
py: 6,
mx: 'auto',
pt: 10,
pb: 6,
}}>
{title}
</Typography>
@@ -61,13 +62,13 @@ const Page: React.FC<PageProps> = ({ title, children, showCookieConsent, ...prop
<Container
id="page-content"
component="main"
maxWidth={false}
sx={{
mt: { xs: 8, md: 12 },
mb: 4,
mt: { xs: 4, md: 12 },
px: '0 !important',
minHeight: '80vh',
mx: 'auto',
maxWidth: { xs: '100%', md: 'calc(100% - 4em)' },
width: theme => theme.breakpoints.values.lg,
maxWidth: '100%',
width: '100%',
...props.sx,
}}>
{children}