reintrodotta visualizzazione lista rimossa nel commit precedente #7

Merged
Fran314 merged 1 commits from dev into main 1 year ago

@ -12,7 +12,8 @@ export const Help = ({}) => (
</p> </p>
<p> <p>
Una volta compiuta la selezione, è possibile vedere la tabella delle Una volta compiuta la selezione, è possibile vedere la tabella delle
lezioni andando nella visualizzazione Orario lezioni andando nella visualizzazione Orario (
<Icon name="calendar_month" />)
</p> </p>
<p> <p>
Per via di eventuali preferenze personali, è possibile cambiare Per via di eventuali preferenze personali, è possibile cambiare
@ -20,6 +21,11 @@ export const Help = ({}) => (
pulsante Trasponi ( pulsante Trasponi (
<Icon name="switch_left" style="transform: rotate(-45deg)" />) <Icon name="switch_left" style="transform: rotate(-45deg)" />)
</p> </p>
<p>
È anche possibile visualizzare in uno specchietto riassuntivo
soltanto i corsi selezionati, andando nella visualizzazione Lista (
<Icon name="list" />)
</p>
<h3>Stampa</h3> <h3>Stampa</h3>
<p> <p>
Da desktop puoi stampare l'orario attualmente visibile con il Da desktop puoi stampare l'orario attualmente visibile con il

@ -25,6 +25,11 @@ export const OptionBar = ({ source, setSource }) => {
label: <Icon name="calendar_month" />, label: <Icon name="calendar_month" />,
icon: true, icon: true,
}, },
{
value: 'lista',
label: <Icon name="list" />,
icon: true,
},
]} ]}
value={source} value={source}
setValue={setSource} setValue={setSource}

@ -38,6 +38,7 @@ export const Toolbar = ({
<CompoundButton <CompoundButton
options={[ options={[
{ value: 'orario', label: 'Orario' }, { value: 'orario', label: 'Orario' },
{ value: 'lista', label: 'Lista' },
]} ]}
value={source} value={source}
setValue={setSource} setValue={setSource}

@ -4,11 +4,21 @@ import _ from 'lodash'
import { useEffect, useRef, useState } from 'preact/hooks' import { useEffect, useRef, useState } from 'preact/hooks'
import { prettyCourseName, WEEK_DAYS } from '../../utils.jsx' import { prettyCourseName, WEEK_DAYS } from '../../utils.jsx'
export const Courses = ({ source, timetables, selection, setSelection }) => { export const Courses = ({
source,
timetables,
selection,
setSelection,
hideOtherCourses,
}) => {
const events = timetables[source] const events = timetables[source]
const selectionSet = new Set(selection) const selectionSet = new Set(selection)
const eventsByCourse = _.groupBy(_.sortBy(events, 'id'), 'id') const visibleEvents = hideOtherCourses
? events.filter(e => selectionSet.has(e.id))
: events
const eventsByCourse = _.groupBy(_.sortBy(visibleEvents, 'id'), 'id')
const profsPerCourse = _.mapValues(eventsByCourse, events => const profsPerCourse = _.mapValues(eventsByCourse, events =>
_.uniq(events.flatMap(event => event.docenti)) _.uniq(events.flatMap(event => event.docenti))
@ -42,6 +52,15 @@ export const Courses = ({ source, timetables, selection, setSelection }) => {
return ( return (
<div class="course-view" ref={element}> <div class="course-view" ref={element}>
{hideOtherCourses && selection.length === 0 && (
<div class="no-courses-warning">
<p>Non hai ancora selezionato nessun corso.</p>
<p>
Clicca sui corsi nelle altre visuali per selezionarli e
visualizzarli nella lista
</p>
</div>
)}
<div class="wrap-container"> <div class="wrap-container">
{Object.entries(eventsByCourse).map(([id, courseEvents]) => ( {Object.entries(eventsByCourse).map(([id, courseEvents]) => (
<div <div
@ -52,18 +71,27 @@ export const Courses = ({ source, timetables, selection, setSelection }) => {
} }
data-course-id={id} data-course-id={id}
onClick={() => { onClick={() => {
if (!selectionSet.has(id)) setSelection([...selection, id]) if (!selectionSet.has(id))
else setSelection(selection.filter(selId => selId !== id)) setSelection([...selection, id])
else
setSelection(
selection.filter(selId => selId !== id)
)
}} }}
> >
<div class="title">{prettyCourseName(courseEvents[0].name)}</div> <div class="title">
<div class="docenti">{profsPerCourse[id].join(', ')}</div> {prettyCourseName(courseEvents[0].name)}
</div>
<div class="docenti">
{profsPerCourse[id].join(', ')}
</div>
<div class="events"> <div class="events">
{courseEvents.map(course => ( {courseEvents.map(course => (
<div> <div>
{WEEK_DAYS[course.start.getDay()]}{' '} {WEEK_DAYS[course.start.getDay()]}{' '}
{format(course.start, 'H:mm')}&ndash; {format(course.start, 'H:mm')}&ndash;
{format(course.end, 'H:mm')} {course.aule.join(', ')} {format(course.end, 'H:mm')}{' '}
{course.aule.join(', ')}
</div> </div>
))} ))}
</div> </div>

@ -211,7 +211,7 @@ const ScheduleCard = ({
) )
} }
export const Schedule = ({ timetables, selection, setSelection }) => { export const Schedule = ({ timetables, selection }) => {
const [hasSeenTranspose, setHasSeenTranspose] = usePersistentState( const [hasSeenTranspose, setHasSeenTranspose] = usePersistentState(
'transpose_info', 'transpose_info',
'false' 'false'

@ -130,16 +130,41 @@ async function loadCalendari() {
} }
} }
const View = ({ view, selection, setSelection, timetables }) => {
if (view === 'orario') {
return <Schedule selection={selection} timetables={timetables} />
} else if (view === 'lista') {
return (
<Courses
selection={selection}
setSelection={setSelection}
source={'tutti'}
timetables={timetables}
hideOtherCourses={true}
/>
)
} else {
return (
<Courses
selection={selection}
setSelection={setSelection}
source={view}
timetables={timetables}
hideOtherCourses={false}
/>
)
}
}
const App = ({}) => { const App = ({}) => {
// Clear persistent states unless state_token corresponds to the one passed // Clear persistent states unless state_token corresponds to the one passed
// as the argument. Useful with breaking updates. Change this token if your // as the argument. Useful with breaking updates. Change this token if your
// (breaking) update needs a reset of persistent states to avoid crashes. // (breaking) update needs a reset of persistent states to avoid crashes.
// //
// Use any random string of your choice // Use any random string of your choice
clearOldPersistentStates('e73cba02') // clearOldPersistentStates('e73cba02')
// Data Sources // Data Sources
const [source, setSource] = usePersistentState('source', 'magistrale') const [view, setView] = usePersistentState('view', 'magistrale')
const [timetables, setTimetables] = useState(null) const [timetables, setTimetables] = useState(null)
useEffect(async () => { useEffect(async () => {
setTimetables(await loadCalendari()) setTimetables(await loadCalendari())
@ -175,8 +200,8 @@ const App = ({}) => {
<> <>
<Toolbar <Toolbar
{...{ {...{
source, source: view,
setSource, setSource: setView,
onShowMenu: () => setShowMobileMenu(true), onShowMenu: () => setShowMobileMenu(true),
onHelp: () => setHelpVisible(true), onHelp: () => setHelpVisible(true),
theme, theme,
@ -185,8 +210,8 @@ const App = ({}) => {
/> />
<OptionBar <OptionBar
{...{ {...{
source, source: view,
setSource, setSource: setView,
onHelp: () => setHelpVisible(true), onHelp: () => setHelpVisible(true),
}} }}
orizzontale orizzontale
@ -194,39 +219,15 @@ const App = ({}) => {
{timetables && ( {timetables && (
<div class="content"> <div class="content">
{source === 'orario' ? ( <View
<Schedule
selection={selectedCourses} selection={selectedCourses}
setSelection={setSelectedCourses} setSelection={setSelectedCourses}
start={new Date(2022, 10, 3)} view={view}
source={source}
timetables={timetables} timetables={timetables}
/> />
) : (
<Courses
selection={selectedCourses}
setSelection={setSelectedCourses}
start={new Date(2022, 10, 3)}
source={source}
timetables={timetables}
/>
)}
</div> </div>
)} )}
{/* toolOverlayVisible && (
<ToolOverlay
mode={mode}
toggleMode={() =>
setMode(
mode === MODE_COURSES ? MODE_SCHEDULE : MODE_COURSES
)
}
onClose={() => {
setSelectedCourses([])
setMode(MODE_COURSES)
}}
/>
) */}
{showMobileMenu && ( {showMobileMenu && (
<HamburgerMenu <HamburgerMenu
{...{ {...{

@ -494,6 +494,23 @@ body {
overflow-y: scroll; overflow-y: scroll;
text-align: center;
gap: 1rem;
.no-courses-warning {
width: 100%;
display: flex;
flex-direction: column;
gap: 1rem;
align-items: center;
p {
text-align: center;
}
}
.wrap-container { .wrap-container {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(30ch, 1fr)); grid-template-columns: repeat(auto-fill, minmax(30ch, 1fr));

Loading…
Cancel
Save