From d0f805356a9080a81388199c718cfba45d9ed3d3 Mon Sep 17 00:00:00 2001 From: Robert Eggl Date: Fri, 20 Dec 2024 11:56:11 +0100 Subject: [PATCH 1/2] refactor(library): remove library component and related localization files --- docs/thi-rest-api.md | 186 ---------- rogue-thi-app/components/allCards.jsx | 15 +- .../lib/backend-utils/library-utils.js | 26 -- .../lib/backend/authenticated-api.js | 102 ------ rogue-thi-app/pages/events.jsx | 102 ++++++ rogue-thi-app/pages/library.jsx | 324 ------------------ rogue-thi-app/public/locales/de/common.json | 1 - .../public/locales/de/dashboard.json | 3 - rogue-thi-app/public/locales/de/library.json | 39 --- rogue-thi-app/public/locales/en/common.json | 1 - .../public/locales/en/dashboard.json | 3 - rogue-thi-app/public/locales/en/library.json | 39 --- rogue-thi-app/styles/Library.module.css | 17 - 13 files changed, 103 insertions(+), 755 deletions(-) delete mode 100644 rogue-thi-app/lib/backend-utils/library-utils.js delete mode 100644 rogue-thi-app/pages/library.jsx delete mode 100644 rogue-thi-app/public/locales/de/library.json delete mode 100644 rogue-thi-app/public/locales/en/library.json delete mode 100644 rogue-thi-app/styles/Library.module.css diff --git a/docs/thi-rest-api.md b/docs/thi-rest-api.md index 262c2fd9..8f39c9db 100644 --- a/docs/thi-rest-api.md +++ b/docs/thi-rest-api.md @@ -598,189 +598,3 @@ to: c "status": 0 } ``` - -## Reservations (library) - -### getreservation - -```http -service: thiapp -method: reservations -format: json -session: -type: 1 -subtype: 1 -cmd: getreservation -data: -``` - -As of 2021-06 the API returns "Service not available" when no reservations are available - -```json -{ - "data": "Service not available", - "date": "10.06.2021", - "time": "14:23:27", - "status": -112 -} -``` - -Old response: - -```json -{ - "data": "No reservation data", - "date": "02.11.2020", - "status": -126, - "time": "20:36:31" -} -``` - -```json -{ - "data": [ - 0, - [ - { - "rcategory": "Lesesaal Galerie", - "reservation_begin": "2020-11-03 06:00:00", - "reservation_end": "2020-11-03 10:00:00", - "reservation_id": "6678", - "reserved_at": "2020-11-02 20:25:50", - "reserved_by": "", - "resource": "2", - "resource_id": "3", - "rsubtype": "1" - } - ] - ], - "date": "02.11.2020", - "status": 0, - "time": "20:34:29" -} -``` - -### addreservation - -```http -service: thiapp -method: reservations -format: json -session: -type: 1 -subtype: 1 -cmd: addreservation -data: {"resource":"3","from":"06:00","to":"10:00","at":"2020-11-03","place":"-1"} -``` - -```json -{ - "data": [0, [""]], - "date": "02.11.2020", - "status": 0, - "time": "21:29:51" -} -``` - -### delreservation - -```http -service: thiapp -method: reservations -format: json -session: -type: 1 -subtype: 1 -cmd: delreservation -data: 6678 -``` - -```json -{ - "data": "No reservation data", - "date": "02.11.2020", - "status": -126, - "time": "20:36:31" -} -``` - -### getavailabilities - -```http -service: thiapp -method: reservations -format: json -session: -type: 1 -subtype: 1 -cmd: getavailabilities -data: -``` - -parts redacted, see getavailabilities-full.json - -```json -{ - "date": "02.11.2020", - "time": "20:37:54", - "data": [ - 0, - [ - { - "date": "2020-11-02", - "hasReservation": false, - "resource": [ - { - "from": "18:00", - "to": "24:00", - "resources": { - "1": { - "room_name": "Lesesaal Nord (alte Bibliothek)", - "seats": [ - "1", - "4", - "5", - "8", - "9", - "12", - "14", - "16", - "18", - "20", - "21", - "24", - "25", - "28", - "29", - "32", - "33", - "36", - "37", - "40", - "41", - "44", - "45", - "48", - "49", - "50", - "51", - "52", - "53", - "54", - "56", - "57" - ], - "num_seats": 32, - "maxnum_seats": 32 - } - // more rooms ... - } - } - ] - } - // more days, more times ... - ] - ], - "status": 0 -} -``` diff --git a/rogue-thi-app/components/allCards.jsx b/rogue-thi-app/components/allCards.jsx index e74da00e..b4c129de 100644 --- a/rogue-thi-app/components/allCards.jsx +++ b/rogue-thi-app/components/allCards.jsx @@ -7,7 +7,7 @@ import InstallPrompt from './cards/InstallPrompt' import RoomCard from './cards/RoomCard' import TimetableCard from './cards/TimetableCard' -import { GraduationCap, Library, Map, Scroll, User } from 'lucide-react' +import { GraduationCap, Map, Scroll, User } from 'lucide-react' import { USER_EMPLOYEE, USER_GUEST, USER_STUDENT } from '../lib/hooks/user-kind' // import ElectionPrompt from './cards/ElectionPrompt' @@ -102,19 +102,6 @@ export const ALL_DASHBOARD_CARDS = [ /> ), }, - { - key: 'library', - removable: true, - default: [PLATFORM_DESKTOP, PLATFORM_MOBILE, USER_STUDENT, USER_EMPLOYEE], - card: () => ( - - ), - }, { key: 'grades', removable: true, diff --git a/rogue-thi-app/lib/backend-utils/library-utils.js b/rogue-thi-app/lib/backend-utils/library-utils.js deleted file mode 100644 index cd940eea..00000000 --- a/rogue-thi-app/lib/backend-utils/library-utils.js +++ /dev/null @@ -1,26 +0,0 @@ -import API from '../backend/authenticated-api' -import { combineDateTime } from '../date-utils' - -/** - * Converts the seat list for easier processing. - * @returns {object} - */ -export async function getFriendlyAvailableLibrarySeats() { - const available = await API.getAvailableLibrarySeats() - return available.map((day) => { - const date = day.date.substring(0, 10) - return { - date, - resource: day.resource.map((slot) => { - const from = combineDateTime(date, slot.from) - const to = combineDateTime(date, slot.to) - - return { - ...slot, - from, - to, - } - }), - } - }) -} diff --git a/rogue-thi-app/lib/backend/authenticated-api.js b/rogue-thi-app/lib/backend/authenticated-api.js index e0aa5040..4b64e354 100644 --- a/rogue-thi-app/lib/backend/authenticated-api.js +++ b/rogue-thi-app/lib/backend/authenticated-api.js @@ -271,108 +271,6 @@ export class AuthenticatedAPIClient extends AnonymousAPIClient { return res } - async getLibraryReservations() { - try { - const res = await this.requestAuthenticated({ - service: 'thiapp', - method: 'reservations', - type: 1, - cmd: 'getreservations', - format: 'json', - }) - - return res[1] - } catch (e) { - // as of 2021-06 the API returns "Service not available" when the user has no reservations - // thus we dont alert the error here, but just silently set the reservations to none - if ( - e.data === 'No reservation data' || - e.data === 'Service not available' - ) { - return [] - } else { - throw e - } - } - } - - async getAvailableLibrarySeats() { - try { - const res = await this.requestAuthenticated({ - service: 'thiapp', - method: 'reservations', - type: 1, - subtype: 1, - cmd: 'getavailabilities', - format: 'json', - }) - - return res[1] - } catch (e) { - // Unbekannter Fehler means the user has already reserved a spot - // and can not reserve additional ones - if (e.data === 'Unbekannter Fehler') { - return [] - } else { - throw e - } - } - } - - /** - * TODO documentation - */ - async addLibraryReservation(roomId, day, start, end, place) { - const res = await this.requestAuthenticated({ - service: 'thiapp', - method: 'reservations', - type: 1, - subtype: 1, - cmd: 'addreservation', - data: JSON.stringify({ - resource: roomId, - at: day, - from: start, - to: end, - place, - }), - dblslots: 0, - format: 'json', - }) - - return res[0] - } - - /** - * @param {string} reservationId Reservation ID returned by `getLibraryReservations` - */ - async removeLibraryReservation(reservationId) { - try { - await this.requestAuthenticated({ - service: 'thiapp', - method: 'reservations', - type: 1, - subtype: 1, - cmd: 'delreservation', - data: reservationId, - format: 'json', - }) - - return true - } catch (e) { - // as of 2021-06 the API returns "Service not available" when the user has no reservations - // thus we dont alert the error here, but just silently set the reservations to none - if ( - e.data === 'No reservation data' || - e.data === 'Service not available' - ) { - return true - } else { - throw e - } - } - } - async getImprint() { const res = await this.requestAuthenticated({ service: 'thiapp', diff --git a/rogue-thi-app/pages/events.jsx b/rogue-thi-app/pages/events.jsx index 0a0c328e..ff0717ac 100644 --- a/rogue-thi-app/pages/events.jsx +++ b/rogue-thi-app/pages/events.jsx @@ -227,6 +227,108 @@ export default function Events({ initialCampusEvents, sportsEvents }) { + {/* SPORTS DETAILS MODAL */} + setFocusedSport(null)} + > + + + {focusedSport && focusedSport.title[locale]} + + + + {t('events.sports.modal.details.weekday')} +

{focusedSport && getLocalizedWeekday(focusedSport.weekday)}

+ + {t('events.sports.modal.details.time')} +

+ {focusedSport && focusedSport.startTime} + {focusedSport && + focusedSport.endTime && + ` - ${focusedSport.endTime}`} +

+ + {t('events.sports.modal.details.location')} +

{focusedSport && focusedSport.location}

+ {focusedSport && focusedSport.description[locale] && ( + <> + {t('events.sports.modal.details.description')} +

+ {focusedSport.description[locale]} +

+ + )} + +

+ {t('events.sports.modal.registration.header')} +

+ {focusedSport && ( + + {focusedSport && focusedSport.requiresRegistration ? ( + <> + + {t('events.sports.modal.registration.required')} + + ) : ( + <> + + + {t('events.sports.modal.registration.notRequired')} + + + )} + + )} + + {focusedSport && focusedSport.eMail && ( + <> + {t('events.sports.modal.registration.email')} +

+ + {focusedSport.eMail.toLowerCase()} + +

+ + )} + + {focusedSport && focusedSport.invitationLink && ( + <> + + {t('events.sports.modal.registration.invitationLink')} + +

+ + {focusedSport.invitationLink} + +

+ + )} +
+ + + +
{ - x.start = new Date(x.reservation_begin.replace(' ', 'T')) - x.end = new Date(x.reservation_end.replace(' ', 'T')) - }) - setReservations(response) - } - - /** - * Closes the reservation popup. - */ - function hideReservationModal() { - setReservationDay(null) - setReservationTime(null) - } - - /** - * Cancels a reservation. - * @param {string} id Reservation ID - */ - async function deleteReservation(id) { - await API.removeLibraryReservation(id) - await refreshData() - } - - /** - * Creates a new reservation. - */ - async function addReservation() { - await API.addLibraryReservation( - reservationRoom, - reservationDay.date, - // this needs to be de-DE regardless of the users locale - reservationTime.from.toLocaleTimeString('de-DE', { timeStyle: 'short' }), - reservationTime.to.toLocaleTimeString('de-DE', { timeStyle: 'short' }), - reservationSeat - ) - await refreshData() - hideReservationModal() - } - - useEffect(() => { - async function load() { - try { - await refreshData() - } catch (e) { - if ( - e instanceof NoSessionError || - e instanceof UnavailableSessionError - ) { - router.replace('/login?redirect=library') - } else { - console.error(e) - alert(e) - } - } - } - load() - }, [router]) - - /** - * Returns a list of available rooms where are more than 0 seats available. - * @returns {Array} List of available rooms - **/ - function getAvailableRooms() { - return Object.entries(reservationTime.resources) - .map(([roomId, room], idx) => [roomId, room, idx]) - .filter(([, room]) => room.num_seats > 0) - } - - /** - * Returns the first available room. - * @returns {string} Room ID - * */ - function getFirstAvailableRoom() { - return getAvailableRooms()[0][0][0] - } - - return ( - - - - - setReservationRoom(getFirstAvailableRoom())} - > - - {t('library.modal.title')} - - - {t('library.modal.details.day')}:{' '} - {reservationDay && formatFriendlyDate(reservationDay.date)} -
- {t('library.modal.details.start')}:{' '} - {reservationTime && formatFriendlyTime(reservationTime.from)} -
- {t('library.modal.details.end')}:{' '} - {reservationTime && formatFriendlyTime(reservationTime.to)} -
-
- - {t('library.modal.details.location')}: - setReservationRoom(event.target.value)} - > - {reservationTime && - getAvailableRooms().map(([roomId, room, idx]) => ( - - ))} - - - - {t('library.modal.details.seat')}: - setReservationSeat(event.target.value)} - > - - {reservationTime && - reservationRoom && - Object.values( - reservationTime.resources[reservationRoom].seats - ).map((x, idx) => ( - - ))} - - -
- - - - -
- -

{t('library.yourReservations')}

- - - {reservations && reservations.length === 0 && ( - - {t('library.details.noReservations')} - - )} - {reservations && - reservations.map((x, i) => ( - -
- -
- , - }} - /> -
- {formatNearDate(x.start)}: {formatFriendlyTime(x.start)} -{' '} - {formatFriendlyTime(x.end)} -
- ))} -
-
- -

{t('library.availableSeats')}

- - - {available && - available.map((day, i) => - day.resource.map((time, j) => ( - - {Object.values(time.resources).reduce( - (acc, room) => acc + room.num_seats, - 0 - ) > 0 && ( - - )} - - {formatNearDate(time.from)} - {', '} - {formatFriendlyTime(time.from)} - {' - '} - {formatFriendlyTime(time.to)} -
-
- {t('library.details.seatsAvailable', { - available: Object.values(time.resources).reduce( - (acc, room) => acc + room.num_seats, - 0 - ), - total: Object.values(time.resources).reduce( - (acc, room) => acc + room.maxnum_seats, - 0 - ), - })} -
-
- )) - )} - {available && available.length === 0 && ( - - {t('library.details.noMoreReservations')} - - )} -
-
- - -
-
- ) -} - -export const getStaticProps = async ({ locale }) => ({ - props: { - ...(await serverSideTranslations(locale ?? 'en', ['library', 'common'])), - }, -}) diff --git a/rogue-thi-app/public/locales/de/common.json b/rogue-thi-app/public/locales/de/common.json index 404fe921..a15fb976 100644 --- a/rogue-thi-app/public/locales/de/common.json +++ b/rogue-thi-app/public/locales/de/common.json @@ -63,7 +63,6 @@ "events": "Campus Life", "rooms": "Raumvorschläge", "roomplan": "Raumkarte", - "library": "Bibliothek", "grades": "Noten & Fächer", "personal": "Profil", "lecturers": "Dozenten", diff --git a/rogue-thi-app/public/locales/de/dashboard.json b/rogue-thi-app/public/locales/de/dashboard.json index 26a3e3d7..a104b023 100644 --- a/rogue-thi-app/public/locales/de/dashboard.json +++ b/rogue-thi-app/public/locales/de/dashboard.json @@ -60,9 +60,6 @@ "roomplan": { "title": "Raumkarte" }, - "library": { - "title": "Bibliothek" - }, "grades": { "title": "Noten & Fächer" }, diff --git a/rogue-thi-app/public/locales/de/library.json b/rogue-thi-app/public/locales/de/library.json deleted file mode 100644 index 7b98b849..00000000 --- a/rogue-thi-app/public/locales/de/library.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "library": { - "title": "Bibliothek", - "yourReservations": "Deine Reservierungen", - "availableSeats": "Verfügbare Plätze", - "actions": { - "reserve": "Reservieren", - "delete": "Löschen" - }, - "details": { - "seatsAvailable": "{{available}} / {{total}} verfügbar", - "noReservations": "Du hast keine Reservierungen", - "noMoreReservations": "Du kannst keine weiteren Plätze reservieren", - "reservationDetails": "{{category}}, Platz {{seat}}, Reservierung {{reservation_id}}" - }, - "modal": { - "title": "Sitzplatz reservieren", - "details": { - "day": "Tag", - "start": "Start", - "end": "Ende", - "location": "Ort", - "seat": "Sitz" - }, - "seatSelection": { - "any": "Egal" - }, - "librarySelection": { - "libraryNorth": "Lesesaal Nord (alte Bibliothek)", - "librarySouth": "Lesesaal Süd (neue Bibliothek)", - "libraryGallery": "Lesesaal Galerie" - }, - "actions": { - "cancel": "Abbrechen", - "reserve": "Reservieren" - } - } - } -} diff --git a/rogue-thi-app/public/locales/en/common.json b/rogue-thi-app/public/locales/en/common.json index 95407bb2..2f24db75 100644 --- a/rogue-thi-app/public/locales/en/common.json +++ b/rogue-thi-app/public/locales/en/common.json @@ -63,7 +63,6 @@ "events": "Campus Life", "rooms": "Room Suggestions", "roomplan": "Room Map", - "library": "Library", "grades": "Grades & Subjects", "personal": "Profile", "lecturers": "Lecturers", diff --git a/rogue-thi-app/public/locales/en/dashboard.json b/rogue-thi-app/public/locales/en/dashboard.json index 4a551d18..0e30ba28 100644 --- a/rogue-thi-app/public/locales/en/dashboard.json +++ b/rogue-thi-app/public/locales/en/dashboard.json @@ -60,9 +60,6 @@ "roomplan": { "title": "Room Map" }, - "library": { - "title": "Library" - }, "grades": { "title": "Grades & Subjects" }, diff --git a/rogue-thi-app/public/locales/en/library.json b/rogue-thi-app/public/locales/en/library.json deleted file mode 100644 index 267110ad..00000000 --- a/rogue-thi-app/public/locales/en/library.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "library": { - "title": "Library", - "yourReservations": "Your reservations", - "availableSeats": "Available seats", - "actions": { - "reserve": "Reserve", - "delete": "Delete" - }, - "details": { - "seatsAvailable": "{{available}} / {{total}} available", - "noReservations": "You have no reservations", - "noMoreReservations": "You can not reserve any more seats", - "reservationDetails": "{{category}}, Seat {{seat}}, Reservation {{reservation_id}}" - }, - "modal": { - "title": "Reserve a seat", - "details": { - "day": "Day", - "start": "Start", - "end": "End", - "location": "Location", - "seat": "Seat" - }, - "seatSelection": { - "any": "Any" - }, - "librarySelection": { - "libraryNorth": "Lesesaal Nord (alte Bibliothek)", - "librarySouth": "Lesesaal Süd (neue Bibliothek)", - "libraryGallery": "Lesesaal Galerie" - }, - "actions": { - "cancel": "Cancel", - "reserve": "Reserve" - } - } - } -} diff --git a/rogue-thi-app/styles/Library.module.css b/rogue-thi-app/styles/Library.module.css deleted file mode 100644 index f7a8abe1..00000000 --- a/rogue-thi-app/styles/Library.module.css +++ /dev/null @@ -1,17 +0,0 @@ -.heading { - margin-top: 20px; -} - -.floatRight { - right: 20px; - top: 50%; - transform: translateY(-50%); - position: absolute; -} - -.cancelButton { - display: flex; - justify-content: center; - align-items: center; - padding: 10px; -} From 4c66a1b2a50e0262725d7f84b5fb4f3489731d79 Mon Sep 17 00:00:00 2001 From: Robert Eggl Date: Fri, 20 Dec 2024 12:21:25 +0100 Subject: [PATCH 2/2] refactor(events): remove unused sports details modal from Events page --- rogue-thi-app/pages/events.jsx | 102 --------------------------------- 1 file changed, 102 deletions(-) diff --git a/rogue-thi-app/pages/events.jsx b/rogue-thi-app/pages/events.jsx index ff0717ac..0a0c328e 100644 --- a/rogue-thi-app/pages/events.jsx +++ b/rogue-thi-app/pages/events.jsx @@ -227,108 +227,6 @@ export default function Events({ initialCampusEvents, sportsEvents }) { - {/* SPORTS DETAILS MODAL */} - setFocusedSport(null)} - > - - - {focusedSport && focusedSport.title[locale]} - - - - {t('events.sports.modal.details.weekday')} -

{focusedSport && getLocalizedWeekday(focusedSport.weekday)}

- - {t('events.sports.modal.details.time')} -

- {focusedSport && focusedSport.startTime} - {focusedSport && - focusedSport.endTime && - ` - ${focusedSport.endTime}`} -

- - {t('events.sports.modal.details.location')} -

{focusedSport && focusedSport.location}

- {focusedSport && focusedSport.description[locale] && ( - <> - {t('events.sports.modal.details.description')} -

- {focusedSport.description[locale]} -

- - )} - -

- {t('events.sports.modal.registration.header')} -

- {focusedSport && ( - - {focusedSport && focusedSport.requiresRegistration ? ( - <> - - {t('events.sports.modal.registration.required')} - - ) : ( - <> - - - {t('events.sports.modal.registration.notRequired')} - - - )} - - )} - - {focusedSport && focusedSport.eMail && ( - <> - {t('events.sports.modal.registration.email')} -

- - {focusedSport.eMail.toLowerCase()} - -

- - )} - - {focusedSport && focusedSport.invitationLink && ( - <> - - {t('events.sports.modal.registration.invitationLink')} - -

- - {focusedSport.invitationLink} - -

- - )} -
- - - -