diff --git a/src/Mealz/MealBundle/Controller/EventController.php b/src/Mealz/MealBundle/Controller/EventController.php index 2ed320253..3462bcd4e 100644 --- a/src/Mealz/MealBundle/Controller/EventController.php +++ b/src/Mealz/MealBundle/Controller/EventController.php @@ -5,6 +5,7 @@ namespace App\Mealz\MealBundle\Controller; use App\Mealz\MealBundle\Entity\Event; +use App\Mealz\MealBundle\Entity\Participant; use App\Mealz\MealBundle\Event\EventParticipationUpdateEvent; use App\Mealz\MealBundle\Repository\DayRepositoryInterface; use App\Mealz\MealBundle\Repository\EventRepositoryInterface; @@ -149,4 +150,22 @@ public function leave(DateTime $date): JsonResponse return new JsonResponse($this->eventPartSrv->getEventParticipationData($day, $profile), 200); } + + public function getEventParticipants(DateTime $date): JsonResponse + { + $day = $this->dayRepo->getDayByDate($date); + + if (null === $day) { + return new JsonResponse(['message' => 'Could not find day'], 404); + } + + $participants = $day->getEvent()->getParticipants(); + + $participantsNames = array_map( + fn (Participant $participant) => $participant->getProfile()->getFullName(), + $participants->toArray() + ); + + return new JsonResponse($participantsNames, 200); + } } diff --git a/src/Mealz/MealBundle/Resources/config/routing.yml b/src/Mealz/MealBundle/Resources/config/routing.yml index 1d1c2be9c..a903e77c3 100644 --- a/src/Mealz/MealBundle/Resources/config/routing.yml +++ b/src/Mealz/MealBundle/Resources/config/routing.yml @@ -306,6 +306,11 @@ MealzMealBundle_api_participations: defaults: { _controller: App\Mealz\MealBundle\Controller\ParticipantController::getParticipationsForWeek } methods: [ GET ] +MealzMealBundle_api_event_participations: + path: /api/participations/event/{date} + defaults: { _controller: App\Mealz\MealBundle\Controller\EventController::getEventParticipants } + methods: [ GET ] + MealzMealBundle_api_non_participating: path: /api/participations/{week}/abstaining defaults: { _controller: App\Mealz\MealBundle\Controller\ParticipantController::getProfilesWithoutParticipation } diff --git a/src/Resources/src/api/getEventParticipants.ts b/src/Resources/src/api/getEventParticipants.ts new file mode 100644 index 000000000..9289a68a2 --- /dev/null +++ b/src/Resources/src/api/getEventParticipants.ts @@ -0,0 +1,13 @@ +import useApi from "./api"; +import { IMessage } from "@/interfaces/IMessage"; + +export default async function getEventParticipants(date: string) { + const { error, response, request } = useApi( + 'GET', + `api/participations/event/${date}` + ); + + await request(); + + return { error, response }; +} \ No newline at end of file diff --git a/src/Resources/src/components/dashboard/EventData.vue b/src/Resources/src/components/dashboard/EventData.vue index 286282afd..b9baf3097 100644 --- a/src/Resources/src/components/dashboard/EventData.vue +++ b/src/Resources/src/components/dashboard/EventData.vue @@ -23,8 +23,13 @@ {{ getEventById(day.event.eventId)?.title }} - + @@ -49,6 +54,7 @@ import CheckBox from '../misc/CheckBox.vue'; import EventIcon from '../misc/EventIcon.vue'; import BannerSpacer from '../misc/BannerSpacer.vue'; import { useI18n } from 'vue-i18n'; +import EventPopup from '@/components/eventParticipation/EventPopup.vue'; defineProps<{ day: Day diff --git a/src/Resources/src/components/eventParticipation/EventPopup.vue b/src/Resources/src/components/eventParticipation/EventPopup.vue new file mode 100644 index 000000000..2323ad067 --- /dev/null +++ b/src/Resources/src/components/eventParticipation/EventPopup.vue @@ -0,0 +1,82 @@ + + + \ No newline at end of file diff --git a/src/Resources/src/components/misc/PopupModal.vue b/src/Resources/src/components/misc/PopupModal.vue new file mode 100644 index 000000000..1501fa74a --- /dev/null +++ b/src/Resources/src/components/misc/PopupModal.vue @@ -0,0 +1,38 @@ + + + \ No newline at end of file diff --git a/src/Resources/src/locales/de.json b/src/Resources/src/locales/de.json index 457472674..021455437 100644 --- a/src/Resources/src/locales/de.json +++ b/src/Resources/src/locales/de.json @@ -79,6 +79,9 @@ "new": "neu", "print": "Heutige Teilnehmer", "show": "Zeige Teilnehmer", + "noParticipants": "Noch keine Teilnehmer für dieses Event", + "participations": "Teilnahmen \"%EventTitle%\"", + "participationCount": "Es gibt %count% Teilnehmer", "popover": "Jemand anderes kann jetzt dein Gericht nehmen.", "slot": { "timeslot": "Zeitfenster", diff --git a/src/Resources/src/locales/en.json b/src/Resources/src/locales/en.json index 5d0cdf4d9..54658cf1e 100644 --- a/src/Resources/src/locales/en.json +++ b/src/Resources/src/locales/en.json @@ -79,6 +79,9 @@ "new": "new", "print": "Today's Participations", "show": "Show Participants", + "noParticipants": "No participants for event yet", + "participations": "Participations \"%EventTitle%\"", + "participationCount": "Es gibt %count% Teilnehmer", "popover": "Someone else can take your meal now.", "slot": { "timeslot": "Timeslot", diff --git a/src/Resources/src/stores/eventsStore.ts b/src/Resources/src/stores/eventsStore.ts index 18119d50d..5a1946445 100644 --- a/src/Resources/src/stores/eventsStore.ts +++ b/src/Resources/src/stores/eventsStore.ts @@ -10,6 +10,7 @@ import deleteEvent from "@/api/deleteEvent"; import postJoinEvent from "@/api/postJoinEvent"; import useEventsBus from '@/tools/eventBus'; import { deleteLeaveEvent } from "@/api/deleteLeaveEvent"; +import getEventParticipants from "@/api/getEventParticipants"; export interface Event { id: number, @@ -85,6 +86,7 @@ export function useEvents() { setTimeout(fetchEvents, TIMEOUT_PERIOD); } + EventsState.error = ''; EventsState.isLoading = false; } @@ -101,6 +103,8 @@ export function useEvents() { return; } + EventsState.error = ''; + sendFlashMessage({ type: FlashMessageType.INFO, message: 'events.created' @@ -126,6 +130,7 @@ export function useEvents() { event.slug = (response.value as Event).slug; event.id = (response.value as Event).id; + EventsState.error = ''; sendFlashMessage({ type: FlashMessageType.INFO, message: 'events.edited' @@ -146,6 +151,7 @@ export function useEvents() { EventsState.error = response.value?.message; } else { EventsState.events.splice(EventsState.events.findIndex((event) => event.slug === slug), 1); + EventsState.error = ''; sendFlashMessage({ type: FlashMessageType.INFO, message: 'events.deleted' @@ -165,6 +171,7 @@ export function useEvents() { } else if (error.value === true) { EventsState.error = 'Unknown error occured on joining the event'; } else { + EventsState.error = ''; emit(EVENT_PARTICIPATION_UPDATE, response.value); } } @@ -181,10 +188,24 @@ export function useEvents() { } else if (error.value === true) { EventsState.error = 'Unknown error occured on leaving the event'; } else { + EventsState.error = ''; emit(EVENT_PARTICIPATION_UPDATE, response.value); } } + async function getParticipantsForEvent(date: string) { + const { error, response } = await getEventParticipants(date); + + if (error.value === true && isMessage(response.value) === true) { + EventsState.error = (response.value as IMessage)?.message; + } else if (error.value === true) { + EventsState.error = 'Unknown error occured on getting participants for the event'; + } else { + EventsState.error = ''; + return (response.value as string[]); + } + } + /** * Sets the filter string * @param newFilter The new filter string @@ -226,6 +247,7 @@ export function useEvents() { getEventById, setFilter, joinEvent, - leaveEvent + leaveEvent, + getParticipantsForEvent } } \ No newline at end of file