Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timetable Room Availability #381

Closed
6 changes: 2 additions & 4 deletions rogue-thi-app/components/RoomMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faLinux } from '@fortawesome/free-brands-svg-icons'

import { NoSessionError, UnavailableSessionError } from '../lib/backend/thi-session-handler'
import { TUX_ROOMS, addSearchDuration, filterRooms, getNextValidDate, getRoomAvailability, getRoomCapacity, getRoomWithCapacity, getTranslatedRoomFunction } from '../lib/backend-utils/rooms-utils'
import { TUX_ROOMS, filterRooms, getNextValidDate, getRoomAvailability, getRoomCapacity, getRoomWithCapacity, getTranslatedRoomFunction } from '../lib/backend-utils/rooms-utils'

import { USER_GUEST, useUserKind } from '../lib/hooks/user-kind'
import { formatFriendlyTime, formatISODate, formatISOTime } from '../lib/date-utils'
Expand Down Expand Up @@ -111,12 +111,10 @@ export default function RoomMap ({ highlight, roomData }) {

async function loadRoomAvailability () {
const roomAvailabilityData = await getRoomAvailability()

const roomAvailabilityList = Object.fromEntries(Object.entries(roomAvailabilityData).map(([room, openings]) => {
const availability = openings
.filter(opening =>
new Date(opening.until) > new Date() &&
new Date(opening.from) > addSearchDuration(new Date())
new Date(opening.until) > new Date()
)
return [room, availability]
}))
Expand Down
39 changes: 39 additions & 0 deletions rogue-thi-app/pages/timetable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Button from 'react-bootstrap/Button'
import ListGroup from 'react-bootstrap/ListGroup'
import Modal from 'react-bootstrap/Modal'
import ReactPlaceholder from 'react-placeholder'
import { getRoomAvailability } from '../lib/backend-utils/rooms-utils'

import { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
Expand Down Expand Up @@ -112,6 +113,7 @@ export default function Timetable () {
const [isDetailedData, setIsDetailedData] = useState(false)
const [showTimetableExplanation, setShowTimetableExplanation] = useState(false)
const [showICalExplanation, setShowICalExplanation] = useState(false)
const [roomAvailabilityList, setRoomAvailabilityList] = useState({})

// page (0 = current week)
const [page, setPage] = useState(0)
Expand Down Expand Up @@ -175,6 +177,42 @@ export default function Timetable () {
load(week[0])
}, [router, timetable, focusedEntry, isDetailedData, week, fetchedWeek])

if (Object.keys(roomAvailabilityList).length === 0) {
loadRoomAvailability()
}

async function loadRoomAvailability () {
const roomAvailabilityData = await getRoomAvailability()

const roomAvailabilityList = Object.fromEntries(Object.entries(roomAvailabilityData).map(([room, openings]) => {
const availability = openings
.filter(opening =>
new Date(opening.until) > new Date()
)
return [room, availability]
}))

setRoomAvailabilityList(roomAvailabilityList)
}

function roomAvailabilityText (room, lessonStart, lessonEnd) {
const availForm = roomAvailabilityList?.[room]?.[0]?.['from']
const availUntil = roomAvailabilityList?.[room]?.[0]?.['until']
if (availForm && availUntil) {
if (availForm > new Date()) {
const date = new Date(availForm)
return ` ${t('timetable.availableFrom')} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`
} else if (new Date(availUntil) - -10 * 60 * 1000 === lessonStart - 0) { // 10min offset bug
return ` ${t('timetable.availableUntil')} ${lessonStart.getHours()}:${String(lessonStart.getMinutes()).padStart(2, '0')}`
} else {
const date = new Date(availUntil)
return ` ${t('timetable.availableUntil')} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`
}
} else {
return ''
}
}

/**
* Renderer for `react-swipeable-views` that displays the timetable for a particular week
* @see {@link https://react-swipeable-views.com/api/api/#virtualize}
Expand Down Expand Up @@ -215,6 +253,7 @@ export default function Timetable () {
: (
<span key={i}>{room}</span>
)}
{isToday(group.date) && roomAvailabilityText(room, item.startDate, item.endDate)}
{i < array.length - 1 && ' '}
</>
))}
Expand Down
4 changes: 3 additions & 1 deletion rogue-thi-app/public/locales/de/timetable.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"close": "Schließen"
}
}
}
},
"availableFrom": "Verfügbar ab",
"availableUntil": "Verfügbar bis"
}
}
4 changes: 3 additions & 1 deletion rogue-thi-app/public/locales/en/timetable.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"close": "Close"
}
}
}
},
"availableFrom": "available from",
"availableUntil": "available until"
}
}