Skip to content

Feature/reservationadmission page#91

Open
DankaMarci wants to merge 20 commits intomainfrom
feature/reservationadmission-page
Open

Feature/reservationadmission page#91
DankaMarci wants to merge 20 commits intomainfrom
feature/reservationadmission-page

Conversation

@DankaMarci
Copy link
Copy Markdown
Contributor

No description provided.

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mmmk-web-frontend Ready Ready Preview, Comment Mar 26, 2026 11:50am

Request Review

@DankaMarci DankaMarci requested a review from justnyx March 23, 2026 11:44
@justnyx
Copy link
Copy Markdown
Collaborator

justnyx commented Mar 23, 2026

Please run yarn lint:fix and yarn format to fix the static analysis issues

Danka Marcell added 2 commits March 23, 2026 21:09
…tions service, add MyGatekeeps page for gatekeeper-specific reservations, and implement admin panels for managing opened weeks, periods, and settings. Update UI components for consistent styling and improve accessibility features.
…All method in ReservationsController and ReservationsService, improve error messages for better user experience, and update UI components for improved visibility and accessibility in reservation details.
Danka Marcell added 3 commits March 24, 2026 12:22
… record entity and DTO, implement findAll method in SanctionRecordsService, and update sanction management in controllers and UI components for better user experience. Added RBAC for sanctions, periods and openWeeks so that only admins or authorized personel can execute CRUD operations on them.

Implemented the base structure for testing with Jest
@Query('page_size', ParseIntPipe) pageSize: number,
@Query('gateKeeperId') gateKeeperId?: string
) {
const parsedGateKeeperId = gateKeeperId ? parseInt(gateKeeperId, 10) : undefined;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this? if not, remove it.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a gatekeeper-based reservation admission flow and expands reservation governance (open weeks/periods, sanctions, settings), while also aligning the frontend UI to a monochromatic design system and adding route/page protection scaffolding.

Changes:

  • Add gatekeeper priority + “need to be let in” support across reservation UI and backend validation.
  • Add admin tooling for Settings / Periods / Opened Weeks, plus sanction record endpoints and user-facing sanction views.
  • Refresh UI theming to use primary/border tokens and add basic page protection (middleware + HOCs).

Reviewed changes

Copilot reviewed 103 out of 106 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
project_info/guidelines.md Documents the monochromatic design system guidance.
apps/frontend/src/utils/withAuth.tsx Adds client-side HOC for role-based page protection.
apps/frontend/src/types/settings.ts Introduces Settings type used by admin/settings and quota logic.
apps/frontend/src/types/sanction-record.ts Adds SanctionRecord type for sanction history UIs.
apps/frontend/src/types/reservation.ts Adds gatekeeper priority + needToBeLetIn to Reservation type.
apps/frontend/src/types/period.ts Adds Period type for period management UI.
apps/frontend/src/types/openedWeek.ts Adds OpenedWeek type for open-week gating.
apps/frontend/src/types/admin.ts Removes old admin config types (deprecated approach).
apps/frontend/src/middleware.ts Adds server-side JWT presence check for protected routes.
apps/frontend/src/lib/reservationSubmitter.ts Updates reservation submission for user-or-band, needToBeLetIn, better errors.
apps/frontend/src/lib/errorToast.ts Improves extraction of backend error messages for toast display.
apps/frontend/src/hooks/useWeekStatus.ts Adds hook to determine whether a week is open (period-based).
apps/frontend/src/hooks/useUser.tsx Adds loading state to the user fetch hook.
apps/frontend/src/hooks/useReservationDetails.ts Extends reservation details logic (gatekeeper priority, delete/edit handling).
apps/frontend/src/hooks/useQuotaCheck.ts Adds quota computation including settings + sanction penalties.
apps/frontend/src/hooks/useAdminConfig.ts Removes old admin config hook.
apps/frontend/src/hooks/collisionWithAdminRes.tsx Attempts to adjust collision logic for band reservations.
apps/frontend/src/components/ui/rules-card.tsx Updates link color tokens to text-primary.
apps/frontend/src/components/ui/card.tsx Aligns Card border styling to border-border.
apps/frontend/src/components/ui/button.tsx Replaces orange-based variants with primary token usage.
apps/frontend/src/components/ui/badge.tsx Aligns default badge variant to primary tokens.
apps/frontend/src/components/profile/profile-page.tsx Displays sanction history on user profile component.
apps/frontend/src/components/news/news-card.tsx Updates pinned styling from orange to primary.
apps/frontend/src/components/layout/theme-toggle.tsx Adds trigger id for testing/targeting.
apps/frontend/src/components/layout/sidebar.tsx Adds gatekeeper/admin nav + stats link.
apps/frontend/src/components/layout/player.tsx Updates player accent colors to primary tokens.
apps/frontend/src/components/layout/header.tsx Adds trigger id for user menu.
apps/frontend/src/components/layout/footer.tsx Aligns footer border color to border-border.
apps/frontend/src/components/calendar/week/daily-weekly-view.tsx Adds open-week gating for week navigation + UI refresh.
apps/frontend/src/components/calendar/validDate.tsx Tightens validation (duration + 15-min intervals).
apps/frontend/src/components/calendar/time-picker.tsx Introduces 15-minute interval time picker component.
apps/frontend/src/components/calendar/reservation-legend.tsx Adds legend UI for reservation types.
apps/frontend/src/components/calendar/reservation-details.tsx Updates reservation details UI (gatekeeper priority actions, TimePicker).
apps/frontend/src/components/calendar/isReservationOvertime.tsx Updates overtime calculations and day/week filtering signatures.
apps/frontend/src/components/calendar/interval-swithcer.tsx Updates interval switcher styling to primary tokens.
apps/frontend/src/components/calendar/day/day-reservation.tsx Improves day reservation rendering and labeling for user/band.
apps/frontend/src/components/calendar/day/day-comment.tsx Aligns day comment layout to updated grid sizing and pointer events.
apps/frontend/src/components/calendar/day/daily-view.tsx Updates day view layout + open-week gating for next-day navigation.
apps/frontend/src/components/calendar/day/daily-view-without-date.tsx Updates grid borders to new tokens.
apps/frontend/src/components/calendar/comment-details.tsx Uses TimePicker; limits edit/delete UI to admins.
apps/frontend/src/components/calendar/calendar.tsx Fetches opened weeks and passes into day/week views.
apps/frontend/src/components/calendar/add-reservation.tsx Adds exclusive user/band selection, TimePicker, week locking, needToBeLetIn.
apps/frontend/src/components/calendar/add-panel.tsx UI tweaks + “comment” renamed to “felhívás” in modal.
apps/frontend/src/components/calendar/add-comment.tsx Uses TimePicker and aligns styling to new tokens.
apps/frontend/src/components/calendar/Line.tsx Updates current-time line styling to primary token.
apps/frontend/src/components/admin/reservation-limits-form.tsx Removes old reservation limits admin UI.
apps/frontend/src/components/admin/SettingsPanel.tsx Adds admin UI for Settings singleton editing.
apps/frontend/src/components/admin/PeriodsPanel.tsx Adds admin UI for creating/toggling/deleting periods.
apps/frontend/src/components/admin/OpenedWeeksPanel.tsx Adds admin UI for opening/closing upcoming weeks.
apps/frontend/src/app/stats/page.tsx Restricts stats page to gatekeepers/admins via HOC.
apps/frontend/src/app/rules/page.tsx Updates rule page links to primary tokens.
apps/frontend/src/app/reservation/page.tsx Adds “Beengedéseim” navigation from reservation page header.
apps/frontend/src/app/profile/page.tsx Adds authenticated “My profile” page with sanction history table.
apps/frontend/src/app/my-gatekeeps/page.tsx Adds gatekeeper page for managing assigned reservations + sanctions.
apps/frontend/src/app/globals.css Updates CSS variables to zinc-style monochrome palette and simplifies scroll tweaks.
apps/frontend/src/app/admin/page.tsx Replaces old admin config section with OpenedWeeks/Periods/Settings panels.
apps/frontend/package.json Updates sonner dependency version.
apps/frontend/docs/PAGE_PROTECTION.md Documents middleware + HOC protection approach.
apps/frontend/declarations.d.ts Adds framer module declaration.
apps/backend/src/settings/settings.service.ts Implements singleton Settings retrieval + update.
apps/backend/src/settings/settings.module.ts Registers Settings module.
apps/backend/src/settings/settings.controller.ts Adds settings endpoints (get + patch).
apps/backend/src/settings/dto/update-settings.dto.ts Adds validation for Settings updates.
apps/backend/src/sanction-records/sanction-records.service.ts Adds sanction record CRUD + “me” aggregation logic.
apps/backend/src/sanction-records/sanction-records.module.ts Registers sanction records module.
apps/backend/src/sanction-records/sanction-records.controller.ts Adds sanction record endpoints (create/update/me/all/etc.).
apps/backend/src/sanction-records/entities/sanction-record.entity.ts Defines sanction record validation entity.
apps/backend/src/sanction-records/dto/update-sanction-record.dto.ts Adds update DTO validation.
apps/backend/src/sanction-records/dto/create-sanction-record.dto.ts Adds create DTO validation.
apps/backend/src/reservations/reservations.service.ts Adds reservation validation, open-week/period enforcement, quota/sanction-based status.
apps/backend/src/reservations/reservations.service.spec.ts Introduces initial ReservationsService test scaffold.
apps/backend/src/reservations/reservations.controller.ts Adds (currently unused) gateKeeperId query param parsing.
apps/backend/src/reservations/entities/reservation.entity.ts Adds gatekeeper priority + needToBeLetIn fields to reservation entity.
apps/backend/src/reservations/dto/update-reservation.dto.ts Simplifies UpdateReservationDto to PartialType of SimpleReservationDto.
apps/backend/src/reservations/dto/simple-reservation.dto.ts Updates DTO to include userId/bandId (not omitted).
apps/backend/src/periods/periods.service.ts Adds periods CRUD.
apps/backend/src/periods/periods.module.ts Registers periods module.
apps/backend/src/periods/periods.controller.ts Adds guarded periods CRUD endpoints.
apps/backend/src/periods/dto/update-period.dto.ts Adds update DTO validation for periods.
apps/backend/src/periods/dto/create-period.dto.ts Adds create DTO validation for periods.
apps/backend/src/opened-weeks/opened-weeks.service.ts Adds opened-week list + upsert logic.
apps/backend/src/opened-weeks/opened-weeks.module.ts Registers opened-weeks module.
apps/backend/src/opened-weeks/opened-weeks.controller.ts Adds opened-weeks list + admin upsert endpoint.
apps/backend/src/opened-weeks/dto/update-opened-week.dto.ts Adds opened-week DTO validation.
apps/backend/src/comments/comments.service.ts Adds auto-deletion of overlapping reservations for non-reservable comments.
apps/backend/src/bands/bands.service.ts Ensures band members are included in findOne response.
apps/backend/src/app.module.ts Removes AdminModule and registers new Settings/Periods/Sanctions/OpenedWeeks modules.
apps/backend/src/admin/entities/reservation-config.entity.ts Removes legacy reservation config entity.
apps/backend/src/admin/dto/update-config.dto.ts Removes legacy config DTO.
apps/backend/src/admin/dto/set-role.dto.ts Removes legacy set-role DTO.
apps/backend/src/admin/admin.service.ts Removes legacy admin service.
apps/backend/src/admin/admin.module.ts Removes legacy admin module.
apps/backend/src/admin/admin.controller.ts Removes legacy admin controller.
apps/backend/prisma/schema.prisma Adds Settings/OpenedWeek/SanctionRecord models; adds gatekeeper priority + needToBeLetIn.
apps/backend/prisma/migrations/20260326114226_init/migration.sql Adds reservationId FK on SanctionRecord.
apps/backend/prisma/migrations/20260323103330_removed_unnecessary_reservation_config_models/migration.sql Drops ReservationConfig/SanctionTier tables.
apps/backend/prisma/migrations/20260322155651_add_weeks_and_extra_settings_attributes/migration.sql Adds OpenedWeek + extra Settings columns.
apps/backend/prisma/migrations/20260322135731_remove_sanction_type/migration.sql Removes SANCTIONED from ReservationStatus enum.
apps/backend/prisma/migrations/20260320130812_add_gatekeeper_priority/migration.sql Adds GateKeeperPriority enum + column.
apps/backend/prisma/migrations/20260116170512_add_sanction_records/migration.sql Adds SanctionRecord table and removes User.sanctionPoints.
apps/backend/prisma/migrations/20260116023247_kolis_fogadas/migration.sql Adds needToBeLetIn column to Reservation.
apps/backend/prisma/migrations/20260109180915_reservation_enhancements/migration.sql Adds initial Settings + Period.isOpen + (legacy) SANCTIONED status.
apps/backend/package.json Adds backend test script and Jest dev deps.
apps/backend/jest.config.js Adds Jest config for backend tests.
Comments suppressed due to low confidence (1)

apps/frontend/src/hooks/collisionWithAdminRes.tsx:17

  • reservationsOfDay.filter(...) never returns a boolean because the predicate only triggers an async getUser(...).then(...) and returns undefined. As a result adminReservations will always be empty, so admin-collision detection is effectively disabled. Consider making this function synchronous (e.g., rely on Reservation.status === 'ADMINMADE' instead of fetching users) or refactor to async and await the role checks before filtering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 18 to 20
export default function ReservationDetails(props: EventDetailsProps) {
if (!props.clickedEvent) return null;
if (!props.clickedEvent) return;

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component returns undefined when clickedEvent is missing (if (!props.clickedEvent) return;). React components should return null to render nothing; returning undefined can trigger type/lint issues (and is easy to miss during refactors).

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +66
const isNextWeekOpen = () => {
const nextWeekMonday = new Date(firstDayOfWeek);
nextWeekMonday.setDate(nextWeekMonday.getDate() + 7);
nextWeekMonday.setHours(0, 0, 0, 0);

return props.openedWeeks.some((w) => {
const wDate = new Date(w.monday);
return wDate.getTime() === nextWeekMonday.getTime() && w.isOpen;
});
};

const handleNextWeek = () => {
if (!isNextWeekOpen()) return;

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isNextWeekOpen() strictly requires an openedWeeks entry for the next week. If you navigate to an older week (or openedWeeks is only populated around “now”), the "next" button can become permanently disabled even though the next week is still in the past and should be viewable. Consider allowing navigation to past/current weeks unconditionally (similar to DailyView’s isNextDayOpen logic) and only enforcing openedWeeks for future weeks.

Copilot uses AI. Check for mistakes.
Comment on lines 76 to +92
async update(id: number, updateCommentDto: UpdateCommentDto) {
try {
return await this.prisma.comment.update({
const updated = await this.prisma.comment.update({
where: {
id,
},
data: {
...updateCommentDto,
},
});

// If the updated comment now blocks reservations, purge any overlapping ones
if (updated.isReservable === false) {
await this.deleteOverlappingReservations(new Date(updated.startTime), new Date(updated.endTime));
}

return updated;
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly in update(), the comment update is committed before overlapping reservations are deleted. If the deletion fails, the API call errors but the updated comment remains saved. Consider using a $transaction to update the comment and perform the conditional reservation deletion atomically.

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +46
@Get('user/:userId')
async findByUserId(@Param('userId', ParseIntPipe) userId: number) {
return this.sanctionRecordsService.findByUserId(userId);
}

@Get('band/:bandId')
async findByBandId(@Param('bandId', ParseIntPipe) bandId: number) {
return this.sanctionRecordsService.findByBandId(bandId);
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user/:userId and band/:bandId sanction-record endpoints are missing any auth guard, so they’re publicly accessible while other sanction endpoints require JWT. These records (points + reasons) are typically sensitive. Add @UseGuards(AuthGuard('jwt')) and enforce authorization (e.g., only ADMIN can query arbitrary user/band sanctions; non-admins should be restricted to their own via /me).

Copilot uses AI. Check for mistakes.
Comment on lines +44 to +48
try {
const settingsRes = await axiosApi.get('/settings/1');
if (settingsRes.data) {
settings = settingsRes.data;
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hook fetches settings from /settings/1, but the backend provides a singleton settings record via GET /settings and the id may not be 1 in existing environments. Fetch from /settings (or first fetch /settings to discover the actual id) to avoid 404s and silently falling back to defaults.

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +87
<select
value={selectedHour}
onChange={handleHourChange}
className='w-20 bg-white hover:bg-slate-200 dark:bg-zinc-700 dark:hover:bg-zinc-600 text-black dark:text-zinc-200 rounded-md border border-zinc-600 px-2 py-2 focus:ring-2 focus:ring-orange-500 focus:border-transparent'
>
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hour <select> still uses focus:ring-orange-500, which conflicts with the new monochromatic --primary/ring design tokens used elsewhere in this PR. Use focus:ring-primary/focus:ring-ring for consistency with the rest of the inputs.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +12
import OpenedWeeksPanel from '../../components/admin/OpenedWeeksPanel';
import PeriodsPanel from '../../components/admin/PeriodsPanel';
import SettingsPanel from '../../components/admin/SettingsPanel';
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page mixes absolute alias imports (e.g. @/components/...) with new relative ../../components/... imports. For consistency with the rest of the codebase (and to avoid fragile paths when files move), import these panels via the existing @/components/... alias as well.

Copilot uses AI. Check for mistakes.
transform: {
'^.+\\.(t|j)s$': 'ts-jest',
},
collectCoverageFrom: ['**/*.(t|j)s'],
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collectCoverageFrom: ['**/*.(t|j)s'] is not a valid glob for Jest’s micromatch patterns, so coverage collection may silently skip files. Use a supported pattern such as ['**/*.{ts,js}'] (and optionally exclude .d.ts, main.ts, etc.).

Suggested change
collectCoverageFrom: ['**/*.(t|j)s'],
collectCoverageFrom: ['**/*.{ts,js}'],

Copilot uses AI. Check for mistakes.
Comment on lines 132 to 139
if (reservationTimes[2] && reservationTimes[3]) {
await axiosApi.post('http://localhost:3030/reservations', {
userId: submissionUserId,
bandId: band?.id,
...(band?.id ? { bandId: band.id } : { userId: submissionUserId }),
startTime: reservationTimes[2].toISOString(),
endTime: reservationTimes[3].toISOString(),
status: 'OVERTIME',
needToBeLetIn: needToBeLetIn,
});
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overtime reservation request still posts to a hard-coded http://localhost:3030/reservations URL. This will break outside local dev and also bypasses the configured axiosApi base URL/interceptors. Use the same relative /reservations endpoint (via axiosApi) as the other reservation creations.

Copilot uses AI. Check for mistakes.
Comment on lines +23 to 30
async findAll(
@Query('page', ParseIntPipe) page: number,
@Query('page_size', ParseIntPipe) pageSize: number,
@Query('gateKeeperId') gateKeeperId?: string
) {
const parsedGateKeeperId = gateKeeperId ? parseInt(gateKeeperId, 10) : undefined;
return this.reservationsService.findAll(page, pageSize);
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gateKeeperId is parsed (parsedGateKeeperId) but then ignored, and findAll always returns this.reservationsService.findAll(page, pageSize). Either remove this query param or pass it through and implement filtering in the service; otherwise callers will assume server-side filtering works when it doesn’t.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants