feat: implement localStorage functionality for MediaPesataApp and remove media.astro page

media-pesata
Luca Lombardo 11 months ago
parent 4780133019
commit 34597fe9f8

@ -120,12 +120,57 @@ const CORSI_DISPONIBILI: Corso[] = [
] ]
function MediaPesataApp() { function MediaPesataApp() {
const [tipoStudente, setTipoStudente] = useState<TipoStudente>('triennale') // Funzioni per localStorage
const [corsiSelezionati, setCorsiSelezionati] = useState<CorsoSelezionato[]>([]) const loadFromStorage = () => {
try {
const savedData = localStorage.getItem('media-pesata-data')
if (savedData) {
const parsed = JSON.parse(savedData)
return {
tipoStudente: parsed.tipoStudente || 'triennale',
corsiSelezionati: parsed.corsiSelezionati || [],
sezioniAperte: parsed.sezioniAperte || {},
mostraRisultati: parsed.mostraRisultati || false,
}
}
} catch (error) {
console.warn('Errore nel caricamento dei dati salvati:', error)
}
return {
tipoStudente: 'triennale' as TipoStudente,
corsiSelezionati: [],
sezioniAperte: {},
mostraRisultati: false,
}
}
const saveToStorage = (data: any) => {
try {
localStorage.setItem('media-pesata-data', JSON.stringify(data))
} catch (error) {
console.warn('Errore nel salvataggio dei dati:', error)
}
}
// Inizializzazione con dati salvati
const initialData = loadFromStorage()
const [tipoStudente, setTipoStudente] = useState<TipoStudente>(initialData.tipoStudente)
const [corsiSelezionati, setCorsiSelezionati] = useState<CorsoSelezionato[]>(initialData.corsiSelezionati)
const [showCustomForm, setShowCustomForm] = useState(false) const [showCustomForm, setShowCustomForm] = useState(false)
const [customCorso, setCustomCorso] = useState<CorsoCustom>({ nome: '', cfu: 0 }) const [customCorso, setCustomCorso] = useState<CorsoCustom>({ nome: '', cfu: 0 })
const [sezioniAperte, setSezioniAperte] = useState<Record<string, boolean>>({}) const [sezioniAperte, setSezioniAperte] = useState<Record<string, boolean>>(initialData.sezioniAperte)
const [mostraRisultati, setMostraRisultati] = useState(false) const [mostraRisultati, setMostraRisultati] = useState(initialData.mostraRisultati)
// Salva automaticamente quando cambiano i dati importanti
useEffect(() => {
const dataToSave = {
tipoStudente,
corsiSelezionati,
sezioniAperte,
mostraRisultati,
}
saveToStorage(dataToSave)
}, [tipoStudente, corsiSelezionati, sezioniAperte, mostraRisultati])
const toggleSezione = (nomeSezione: string) => { const toggleSezione = (nomeSezione: string) => {
setSezioniAperte(prev => ({ setSezioniAperte(prev => ({
@ -237,6 +282,14 @@ function MediaPesataApp() {
setCorsiSelezionati([]) setCorsiSelezionati([])
setCustomCorso({ nome: '', cfu: 0 }) setCustomCorso({ nome: '', cfu: 0 })
setShowCustomForm(false) setShowCustomForm(false)
setSezioniAperte({})
setMostraRisultati(false)
// Pulisce anche il localStorage
try {
localStorage.removeItem('media-pesata-data')
} catch (error) {
console.warn('Errore nella pulizia del localStorage:', error)
}
} }
} }
} }

@ -1,49 +0,0 @@
---
import '@/styles/pages/media-pesata.css'
import PageLayout from '../layouts/PageLayout.astro'
---
<PageLayout title="Voto Laurea" description="Calcola la tua media pesata e il voto di laurea seguendo le regole del dipartimento">
<div class="media-pesata-container">
<h1>Voto Laurea</h1>
<p>Calcola la tua media pesata e il voto con cui ti siederai alla discussione di laurea, seguendo le regole del dipartimento di Matematica.</p>
<div id="media-pesata-app"></div>
</div>
</PageLayout>
<script>
// Importiamo e inizializziamo l'applicazione
import('../client/MediaPesataApp')
.then(module => {
const { initMediaPesataApp } = module
initMediaPesataApp()
})
.catch(error => {
console.error('Errore nel caricamento dell\'applicazione:', error)
})
</script>
<style>
.media-pesata-container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.media-pesata-container h1 {
text-align: center;
color: var(--palette-black);
margin-bottom: 1rem;
font-family: var(--font-display);
font-weight: 700;
font-size: 2.5rem;
}
.media-pesata-container p {
text-align: center;
color: #666;
margin-bottom: 2rem;
font-size: 1.1rem;
}
</style>

@ -47,29 +47,31 @@
gap: 0.5rem; gap: 0.5rem;
font-size: 1.1rem; font-size: 1.1rem;
cursor: pointer; cursor: pointer;
padding: 0.75rem 1.5rem; padding: 0.5rem 1rem;
border: 3px solid var(--palette-black); border: 2px solid var(--palette-black);
border-radius: 6px; border-radius: 6px;
background: #fff; background: #fff;
font-family: var(--font-secondary); font-family: var(--font-secondary);
font-weight: 600; font-weight: 600;
transition: all 64ms linear; transition: all 64ms linear;
box-shadow: 4px 4px 0 0 var(--palette-black); box-shadow: 2px 2px 0 0 var(--palette-black);
} }
.radio-group label:hover { .radio-group label:hover {
transform: translate(-1px, -1px); transform: translate(-1px, -1px);
box-shadow: 5px 5px 0 0 var(--palette-black); box-shadow: 3px 3px 0 0 var(--palette-black);
} }
.radio-group input[type='radio']:checked + span { .radio-group label:active {
background: var(--homepage-projects-bg); transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
.radio-group input[type='radio'] { .radio-group input[type='radio'] {
width: 18px; width: 18px;
height: 18px; height: 18px;
margin: 0; margin: 0;
accent-color: #007bff;
} }
/* Counter CFU */ /* Counter CFU */
@ -174,12 +176,18 @@
transition: all 64ms linear; transition: all 64ms linear;
text-align: left; text-align: left;
font-family: var(--font-secondary); font-family: var(--font-secondary);
box-shadow: 2px 2px 0 0 var(--palette-black);
} }
.course-button:hover:not(:disabled) { .course-button:hover:not(:disabled) {
background: var(--homepage-projects-bg); background: var(--homepage-projects-bg);
transform: translate(-1px, -1px); transform: translate(-1px, -1px);
box-shadow: 2px 2px 0 0 var(--palette-black); box-shadow: 3px 3px 0 0 var(--palette-black);
}
.course-button:active:not(:disabled) {
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
.course-button:disabled { .course-button:disabled {
@ -190,8 +198,8 @@
.course-button.selected { .course-button.selected {
background: var(--guide-base); background: var(--guide-base);
box-shadow: 2px 2px 0 0 var(--palette-black);
transform: translate(1px, 1px); transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
.course-name { .course-name {
@ -284,23 +292,35 @@
.confirm-btn { .confirm-btn {
background: #28a745; background: #28a745;
color: white; color: white;
box-shadow: 2px 2px 0 0 var(--palette-black);
} }
.confirm-btn:hover { .confirm-btn:hover {
background: #218838; background: #218838;
transform: translate(-1px, -1px); transform: translate(-1px, -1px);
box-shadow: 2px 2px 0 0 var(--palette-black); box-shadow: 3px 3px 0 0 var(--palette-black);
}
.confirm-btn:active {
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
.cancel-btn { .cancel-btn {
background: #6c757d; background: #6c757d;
color: white; color: white;
box-shadow: 2px 2px 0 0 var(--palette-black);
} }
.cancel-btn:hover { .cancel-btn:hover {
background: #5a6268; background: #5a6268;
transform: translate(-1px, -1px); transform: translate(-1px, -1px);
box-shadow: 2px 2px 0 0 var(--palette-black); box-shadow: 3px 3px 0 0 var(--palette-black);
}
.cancel-btn:active {
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
/* Sezione corsi selezionati */ /* Sezione corsi selezionati */
@ -424,12 +444,18 @@
justify-content: center; justify-content: center;
transition: all 64ms linear; transition: all 64ms linear;
flex-shrink: 0; flex-shrink: 0;
box-shadow: 2px 2px 0 0 var(--palette-black);
} }
.remove-btn:hover { .remove-btn:hover {
background: #b71c1c; background: #b71c1c;
transform: translate(-1px, -1px); transform: translate(-1px, -1px);
box-shadow: 2px 2px 0 0 var(--palette-black); box-shadow: 3px 3px 0 0 var(--palette-black);
}
.remove-btn:active {
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
/* Calcolo e risultati */ /* Calcolo e risultati */
@ -671,12 +697,18 @@
font-weight: 600; font-weight: 600;
cursor: pointer; cursor: pointer;
transition: all 64ms linear; transition: all 64ms linear;
box-shadow: 2px 2px 0 0 var(--palette-black);
} }
.reset-btn:hover { .reset-btn:hover {
background: #b71c1c; background: #b71c1c;
transform: translate(-1px, -1px); transform: translate(-1px, -1px);
box-shadow: 2px 2px 0 0 var(--palette-black); box-shadow: 3px 3px 0 0 var(--palette-black);
}
.reset-btn:active {
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
.cfu-info { .cfu-info {
@ -706,11 +738,17 @@
transition: all 64ms linear; transition: all 64ms linear;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
min-height: 36px; min-height: 36px;
box-shadow: 1px 1px 0 0 var(--palette-black);
} }
.category-header:hover { .category-header:hover {
background: #d9b3ff; background: #d9b3ff;
transform: translate(-1px, -1px); transform: translate(-1px, -1px);
box-shadow: 2px 2px 0 0 var(--palette-black);
}
.category-header:active {
transform: translate(0px, 0px);
box-shadow: 1px 1px 0 0 var(--palette-black); box-shadow: 1px 1px 0 0 var(--palette-black);
} }
@ -751,12 +789,18 @@
transition: all 64ms linear; transition: all 64ms linear;
font-family: var(--font-primary); font-family: var(--font-primary);
display: inline-block; display: inline-block;
box-shadow: 4px 4px 0 0 var(--palette-black);
} }
.calculate-btn:hover { .calculate-btn:hover {
background: #2b8b47; background: #2b8b47;
transform: translate(-2px, -2px); transform: translate(-1px, -1px);
box-shadow: 4px 4px 0 0 var(--palette-black); box-shadow: 5px 5px 0 0 var(--palette-black);
}
.calculate-btn:active {
transform: translate(2px, 2px);
box-shadow: 2px 2px 0 0 var(--palette-black);
} }
/* Info section */ /* Info section */

Loading…
Cancel
Save