|
|
@ -1,6 +1,7 @@
|
|
|
|
import _ from 'lodash'
|
|
|
|
import _ from 'lodash'
|
|
|
|
import { render } from 'preact'
|
|
|
|
import { render } from 'preact'
|
|
|
|
import { useEffect, useState } from 'preact/hooks'
|
|
|
|
import { useEffect, useState } from 'preact/hooks'
|
|
|
|
|
|
|
|
import { differenceInMinutes, startOfDay } from 'date-fns'
|
|
|
|
|
|
|
|
|
|
|
|
// import { ToolOverlay } from './components/ToolOverlay.jsx'
|
|
|
|
// import { ToolOverlay } from './components/ToolOverlay.jsx'
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -18,12 +19,7 @@ import { Icon } from './components/Icon.jsx'
|
|
|
|
import { Popup } from './components/Popup.jsx'
|
|
|
|
import { Popup } from './components/Popup.jsx'
|
|
|
|
import { Toolbar } from './components/Toolbar.jsx'
|
|
|
|
import { Toolbar } from './components/Toolbar.jsx'
|
|
|
|
import { OptionBar } from './components/OptionBar.jsx'
|
|
|
|
import { OptionBar } from './components/OptionBar.jsx'
|
|
|
|
import {
|
|
|
|
import { prettyAulaName, prettyProfName, usePersistentState } from './utils.jsx'
|
|
|
|
prettyAulaName,
|
|
|
|
|
|
|
|
prettyProfName,
|
|
|
|
|
|
|
|
clearOldPersistentStates,
|
|
|
|
|
|
|
|
usePersistentState,
|
|
|
|
|
|
|
|
} from './utils.jsx'
|
|
|
|
|
|
|
|
import { SettingsBar } from './components/SettingsBar.jsx'
|
|
|
|
import { SettingsBar } from './components/SettingsBar.jsx'
|
|
|
|
|
|
|
|
|
|
|
|
// Che fanno queste due righe?
|
|
|
|
// Che fanno queste due righe?
|
|
|
@ -31,10 +27,10 @@ window._ = _
|
|
|
|
window.dataBuffer = {}
|
|
|
|
window.dataBuffer = {}
|
|
|
|
|
|
|
|
|
|
|
|
const TIMETABLE_IDS = {
|
|
|
|
const TIMETABLE_IDS = {
|
|
|
|
'anno-1': '667e88275e9623041f0e43d4',
|
|
|
|
'anno-1': '64a7c1c651f079001d52e9c8',
|
|
|
|
'anno-2': '667e89055e9623041f0e43d6',
|
|
|
|
'anno-2': '6308e2dc09352a0208fefdd9',
|
|
|
|
'anno-3': '667e89fcf748ed0415a11dcc',
|
|
|
|
'anno-3': '6308e42a1df5cb026699ced4',
|
|
|
|
'magistrale': '667ebae63379a3046517ffd4',
|
|
|
|
'magistrale': '64a7c7091ab813002c5d9ede',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// const DEFAULT_DATE_RANGE = {
|
|
|
|
// const DEFAULT_DATE_RANGE = {
|
|
|
@ -50,17 +46,15 @@ const TIMETABLE_IDS = {
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
function specialEventPatches(eventi) {
|
|
|
|
function specialEventPatches(eventi) {
|
|
|
|
// Il laboratorio del primo anno in realtà è in due gruppi separati
|
|
|
|
// Il laboratorio del primo anno in realtà è in due canali separati
|
|
|
|
|
|
|
|
let i = 1
|
|
|
|
eventi.forEach(evento => {
|
|
|
|
eventi.forEach(evento => {
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
evento.nome === 'LABORATORIO DI INTRODUZIONE ALLA MATEMATICA COMPUTAZIONALE'
|
|
|
|
evento.nome ===
|
|
|
|
|
|
|
|
'LABORATORIO DI INTRODUZIONE ALLA MATEMATICA COMPUTAZIONALE'
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
if (evento.docenti[0].nome === 'GIOVANNI') {
|
|
|
|
evento.nome += ` (${i})`
|
|
|
|
evento.nome += ' (A)'
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
|
|
|
|
if (evento.docenti[0].nome === 'PAOLO') {
|
|
|
|
|
|
|
|
evento.nome += ' (B)'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
@ -69,12 +63,17 @@ function specialEventPatches(eventi) {
|
|
|
|
|
|
|
|
|
|
|
|
function formatEvents(timetable) {
|
|
|
|
function formatEvents(timetable) {
|
|
|
|
return timetable.map(({ nome, dataInizio, dataFine, docenti, aule }) => {
|
|
|
|
return timetable.map(({ nome, dataInizio, dataFine, docenti, aule }) => {
|
|
|
|
|
|
|
|
const start = new Date(dataInizio)
|
|
|
|
|
|
|
|
const end = new Date(dataFine)
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
id: nome,
|
|
|
|
id: nome,
|
|
|
|
name: _.split(nome, '-', 1)[0].trim(),
|
|
|
|
name: _.split(nome, '-', 1)[0].trim(),
|
|
|
|
start: new Date(dataInizio),
|
|
|
|
day: start.getDay(),
|
|
|
|
end: new Date(dataFine),
|
|
|
|
start: differenceInMinutes(start, startOfDay(start)),
|
|
|
|
docenti: docenti.map(({ nome, cognome }) => prettyProfName(nome, cognome)),
|
|
|
|
end: differenceInMinutes(end, startOfDay(start)),
|
|
|
|
|
|
|
|
docenti: docenti.map(({ nome, cognome }) =>
|
|
|
|
|
|
|
|
prettyProfName(nome, cognome)
|
|
|
|
|
|
|
|
),
|
|
|
|
aule: aule.map(aula => prettyAulaName(aula.codice)),
|
|
|
|
aule: aule.map(aula => prettyAulaName(aula.codice)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
@ -131,7 +130,7 @@ async function loadCalendari(date) {
|
|
|
|
const timetablesRaw = results.map(timetable =>
|
|
|
|
const timetablesRaw = results.map(timetable =>
|
|
|
|
specialEventPatches(_.uniqBy(timetable, 'id'))
|
|
|
|
specialEventPatches(_.uniqBy(timetable, 'id'))
|
|
|
|
)
|
|
|
|
)
|
|
|
|
const allRaw = specialEventPatches(_.concat(...results), 'id')
|
|
|
|
const allRaw = specialEventPatches(_.uniqBy(_.concat(...results), 'id'))
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
'anno-1': formatEvents(timetablesRaw[0]),
|
|
|
|
'anno-1': formatEvents(timetablesRaw[0]),
|
|
|
@ -142,18 +141,49 @@ async function loadCalendari(date) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const View = ({ view, selection, setSelection, timetables }) => {
|
|
|
|
const View = ({
|
|
|
|
|
|
|
|
view,
|
|
|
|
|
|
|
|
selection,
|
|
|
|
|
|
|
|
setSelection,
|
|
|
|
|
|
|
|
timetables,
|
|
|
|
|
|
|
|
custom,
|
|
|
|
|
|
|
|
setCustom,
|
|
|
|
|
|
|
|
}) => {
|
|
|
|
if (view === 'orario') {
|
|
|
|
if (view === 'orario') {
|
|
|
|
return <Schedule selection={selection} timetables={timetables} />
|
|
|
|
return (
|
|
|
|
|
|
|
|
<Schedule
|
|
|
|
|
|
|
|
selection={selection}
|
|
|
|
|
|
|
|
timetables={timetables}
|
|
|
|
|
|
|
|
custom={custom}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)
|
|
|
|
} else if (view === 'lista') {
|
|
|
|
} else if (view === 'lista') {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<Courses
|
|
|
|
<Courses
|
|
|
|
selection={selection}
|
|
|
|
selection={selection}
|
|
|
|
setSelection={setSelection}
|
|
|
|
setSelection={setSelection}
|
|
|
|
source={'tutti'}
|
|
|
|
|
|
|
|
timetables={timetables}
|
|
|
|
timetables={timetables}
|
|
|
|
hideOtherCourses={true}
|
|
|
|
custom={custom}
|
|
|
|
|
|
|
|
isRestrictedList={true}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
} else if (view === 'custom') {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div class="custom-events-view">
|
|
|
|
|
|
|
|
<textarea
|
|
|
|
|
|
|
|
value={custom}
|
|
|
|
|
|
|
|
onChange={e => setCustom(e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
<p>Esempio di evento personalizzato</p>
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
|
|
|
Nome evento [label globale]:
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
- Lun 9-11
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
- Mar 9:00-11:00
|
|
|
|
|
|
|
|
<br />- Gio 8:00-12:00 [label locale]
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
@ -162,7 +192,7 @@ const View = ({ view, selection, setSelection, timetables }) => {
|
|
|
|
setSelection={setSelection}
|
|
|
|
setSelection={setSelection}
|
|
|
|
source={view}
|
|
|
|
source={view}
|
|
|
|
timetables={timetables}
|
|
|
|
timetables={timetables}
|
|
|
|
hideOtherCourses={false}
|
|
|
|
isRestrictedList={false}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -184,11 +214,14 @@ const App = ({}) => {
|
|
|
|
setTimetables(await loadCalendari(new Date(date)))
|
|
|
|
setTimetables(await loadCalendari(new Date(date)))
|
|
|
|
}, [date])
|
|
|
|
}, [date])
|
|
|
|
|
|
|
|
|
|
|
|
// View Modes
|
|
|
|
|
|
|
|
// const [mode, setMode] = usePersistentState('orario.mode', MODE_COURSES)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Selection
|
|
|
|
// Selection
|
|
|
|
const [selectedCourses, setSelectedCourses] = usePersistentState('selection', [])
|
|
|
|
const [selectedCourses, setSelectedCourses] = usePersistentState(
|
|
|
|
|
|
|
|
'selection',
|
|
|
|
|
|
|
|
[]
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Custom Events
|
|
|
|
|
|
|
|
const [custom, setCustom] = usePersistentState('custom', [])
|
|
|
|
|
|
|
|
|
|
|
|
// Menus
|
|
|
|
// Menus
|
|
|
|
const [helpVisible, setHelpVisible] = useState(false)
|
|
|
|
const [helpVisible, setHelpVisible] = useState(false)
|
|
|
@ -259,15 +292,16 @@ const App = ({}) => {
|
|
|
|
) : timetables['tutti'].length === 0 ? (
|
|
|
|
) : timetables['tutti'].length === 0 ? (
|
|
|
|
<div class="warning">
|
|
|
|
<div class="warning">
|
|
|
|
<p>
|
|
|
|
<p>
|
|
|
|
Non esistono corsi per la settimana selezionata: buone
|
|
|
|
Non esistono corsi per la settimana selezionata:
|
|
|
|
vacanze! 🎉
|
|
|
|
buone vacanze! 🎉
|
|
|
|
</p>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
<p>
|
|
|
|
Per cambiare settimana puoi usare il widget Calendario (
|
|
|
|
Per cambiare settimana puoi usare il widget
|
|
|
|
|
|
|
|
Calendario (
|
|
|
|
<Icon name="calendar_month" />) in alto a destra
|
|
|
|
<Icon name="calendar_month" />) in alto a destra
|
|
|
|
<br />
|
|
|
|
<br />
|
|
|
|
In versione mobile, il widget Calendario è situato dentro
|
|
|
|
In versione mobile, il widget Calendario è
|
|
|
|
il Menu (
|
|
|
|
situato dentro il Menu (
|
|
|
|
<Icon name="menu" />)
|
|
|
|
<Icon name="menu" />)
|
|
|
|
</p>
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@ -277,6 +311,8 @@ const App = ({}) => {
|
|
|
|
setSelection={setSelectedCourses}
|
|
|
|
setSelection={setSelectedCourses}
|
|
|
|
view={view}
|
|
|
|
view={view}
|
|
|
|
timetables={timetables}
|
|
|
|
timetables={timetables}
|
|
|
|
|
|
|
|
custom={custom}
|
|
|
|
|
|
|
|
setCustom={setCustom}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|