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() {
const [tipoStudente, setTipoStudente] = useState<TipoStudente>('triennale')
const [corsiSelezionati, setCorsiSelezionati] = useState<CorsoSelezionato[]>([])
// Funzioni per localStorage
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 [customCorso, setCustomCorso] = useState<CorsoCustom>({ nome: '', cfu: 0 })
const [sezioniAperte, setSezioniAperte] = useState<Record<string, boolean>>({})
const [mostraRisultati, setMostraRisultati] = useState(false)
const [sezioniAperte, setSezioniAperte] = useState<Record<string, boolean>>(initialData.sezioniAperte)
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) => {
setSezioniAperte(prev => ({
@ -237,6 +282,14 @@ function MediaPesataApp() {
setCorsiSelezionati([])
setCustomCorso({ nome: '', cfu: 0 })
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;
font-size: 1.1rem;
cursor: pointer;
padding: 0.75rem 1.5rem;
border: 3px solid var(--palette-black);
padding: 0.5rem 1rem;
border: 2px solid var(--palette-black);
border-radius: 6px;
background: #fff;
font-family: var(--font-secondary);
font-weight: 600;
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 {
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 {
background: var(--homepage-projects-bg);
.radio-group label:active {
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
}
.radio-group input[type='radio'] {
width: 18px;
height: 18px;
margin: 0;
accent-color: #007bff;
}
/* Counter CFU */
@ -174,12 +176,18 @@
transition: all 64ms linear;
text-align: left;
font-family: var(--font-secondary);
box-shadow: 2px 2px 0 0 var(--palette-black);
}
.course-button:hover:not(:disabled) {
background: var(--homepage-projects-bg);
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 {
@ -190,8 +198,8 @@
.course-button.selected {
background: var(--guide-base);
box-shadow: 2px 2px 0 0 var(--palette-black);
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 var(--palette-black);
}
.course-name {
@ -284,23 +292,35 @@
.confirm-btn {
background: #28a745;
color: white;
box-shadow: 2px 2px 0 0 var(--palette-black);
}
.confirm-btn:hover {
background: #218838;
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 {
background: #6c757d;
color: white;
box-shadow: 2px 2px 0 0 var(--palette-black);
}
.cancel-btn:hover {
background: #5a6268;
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 */
@ -424,12 +444,18 @@
justify-content: center;
transition: all 64ms linear;
flex-shrink: 0;
box-shadow: 2px 2px 0 0 var(--palette-black);
}
.remove-btn:hover {
background: #b71c1c;
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 */
@ -671,12 +697,18 @@
font-weight: 600;
cursor: pointer;
transition: all 64ms linear;
box-shadow: 2px 2px 0 0 var(--palette-black);
}
.reset-btn:hover {
background: #b71c1c;
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 {
@ -706,11 +738,17 @@
transition: all 64ms linear;
margin-bottom: 0.5rem;
min-height: 36px;
box-shadow: 1px 1px 0 0 var(--palette-black);
}
.category-header:hover {
background: #d9b3ff;
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);
}
@ -751,12 +789,18 @@
transition: all 64ms linear;
font-family: var(--font-primary);
display: inline-block;
box-shadow: 4px 4px 0 0 var(--palette-black);
}
.calculate-btn:hover {
background: #2b8b47;
transform: translate(-2px, -2px);
box-shadow: 4px 4px 0 0 var(--palette-black);
transform: translate(-1px, -1px);
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 */

Loading…
Cancel
Save