diff --git a/.ddev/commands/host/cf b/.ddev/commands/host/cf new file mode 100755 index 0000000..322ee28 --- /dev/null +++ b/.ddev/commands/host/cf @@ -0,0 +1,3 @@ +#!/bin/bash + +cloudflared tunnel --url "https://127.0.0.1/$DDEV_HOST_HTTPS_PORT" --http-host-header "$DDEV_SITENAME.$DDEV_TLD" diff --git a/src/Controller/SuccessController.php b/src/Controller/SuccessController.php index ebb7804..dc4d8b6 100644 --- a/src/Controller/SuccessController.php +++ b/src/Controller/SuccessController.php @@ -10,11 +10,32 @@ use Symfony\Component\Routing\Attribute\Route; class SuccessController extends AbstractController { - #[Route(path: '/success', name: 'app_success_page', methods: Request::METHOD_GET)] - public function __invoke(TicketService $service, Request $request): Response + #[Route(path: '/success', name: 'app_order_success', methods: Request::METHOD_GET)] + public function success(Request $request, TicketService $service): Response { - $service->completePayment((string)$request->query->get('session_id')); + $sessionId = $request->query->get('session_id'); + + if (!$sessionId) { + noty()->error('Etwas ist schiefgelaufen'); + + return $this->redirectToRoute('app_ticket'); + } + + if (!$service->completePayment($sessionId)) { + noty()->error('Etwas ist schiefgelaufen'); + + return $this->redirectToRoute('app_ticket'); + } return $this->render('ticket/success.html.twig'); } + + #[Route(path: '/cancelled', name: 'app_cancelled', methods: Request::METHOD_GET)] + public function cancel(): Response + { + noty()->error('Bezahlung abgebrochen'); + + return $this->redirectToRoute('app_ticket'); + } + } \ No newline at end of file diff --git a/src/Controller/TicketController.php b/src/Controller/TicketController.php index 50bf39e..e531cd5 100644 --- a/src/Controller/TicketController.php +++ b/src/Controller/TicketController.php @@ -3,8 +3,8 @@ namespace App\Controller; use App\DataObjects\TicketFormData; +use App\Service\EventService; use App\Service\TicketService; -use Stripe\Stripe; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -16,6 +16,7 @@ final class TicketController extends AbstractController public function __construct( private TicketService $service, private SerializerInterface $serializer, + private EventService $eventService, ) { } @@ -33,31 +34,14 @@ final class TicketController extends AbstractController return $this->json(['id' => $this->service->handleTicketData($ticketData)->id]); } - #[Route(path: '/success', name: 'app_order_success', methods: Request::METHOD_GET)] - public function success(Request $request): Response + #[Route(path: '/calendar', name: 'app_calendar')] + public function calendar(Request $request): Response { - $sessionId = $request->query->get('session_id'); + $userAgent = $request->headers->get('User-Agent'); + $isApple = str_contains($userAgent, 'Mac') || str_contains($userAgent, 'iPhone') || str_contains($userAgent, 'iPad'); - if (!$sessionId) { - noty()->error('Etwas ist schiefgelaufen'); - - return $this->redirectToRoute('app_ticket'); - } - - if (!$this->service->completePayment($sessionId)) { - noty()->error('Etwas ist schiefgelaufen'); - - return $this->redirectToRoute('app_ticket'); - } - - return $this->redirectToRoute('app_success_page'); - } - - #[Route(path: '/cancelled', name: 'app_cancelled', methods: Request::METHOD_GET)] - public function cancel(): Response - { - noty()->error('Bezahlung abgebrochen'); - - return $this->redirectToRoute('app_ticket'); + return $isApple + ? $this->eventService->generateIcs() + : $this->eventService->generateGoogleRedirect(); } } diff --git a/src/Service/EventService.php b/src/Service/EventService.php new file mode 100644 index 0000000..9ecf3ce --- /dev/null +++ b/src/Service/EventService.php @@ -0,0 +1,50 @@ + 'Abiball 2025', + 'description' => 'Der Abiball der Freien Waldorfschule Bremen Osterholz und Touler Straße', + 'location' => 'Graubündener Str. 4, 28325 Bremen', + 'start' => '20250628T173000', + 'end' => '20250629T030000', + ]; + + public function generateIcs(): Response + { + $data = [ + 'BEGIN:VCALENDAR', + 'VERSION:2.0', + 'BEGIN:VEVENT', + 'DTSTART:' . self::EVENT_DATA['start'], + 'DTEND:' . self::EVENT_DATA['end'], + 'SUMMARY:' . self::EVENT_DATA['title'], + 'DESCRIPTION:' . self::EVENT_DATA['description'], + 'LOCATION:' . self::EVENT_DATA['location'], + 'END:VEVENT', + 'END:VCALENDAR' + ]; + + return new Response(implode("\r\n", $data), headers: [ + 'Content-Type' => 'text/calendar; charset=utf-8', + 'Content-Disposition' => 'attachment; filename="event.ics"' + ]); + } + + public function generateGoogleRedirect(): Response + { + return new RedirectResponse('https://calendar.google.com/calendar/render?' . http_build_query([ + 'action' => 'TEMPLATE', + 'text' => self::EVENT_DATA['title'], + 'dates' => self::EVENT_DATA['start'] . '/' . self::EVENT_DATA['end'], + 'details' => self::EVENT_DATA['description'], + 'location' => self::EVENT_DATA['location'], + ])); + } +} \ No newline at end of file diff --git a/templates/ticket/success.html.twig b/templates/ticket/success.html.twig index eb38a9a..fb2ecbf 100644 --- a/templates/ticket/success.html.twig +++ b/templates/ticket/success.html.twig @@ -1,15 +1,93 @@ {% extends 'base.html.twig' %} {% block title %} -Success +Danke {% endblock %} {% block body %} -
-
-
-

Success

-

Your ticket has been successfully created.

+
+
+ +
+ +
+
+
+
+ +
+

Vielen Dank für deine Bestellung!

+

Wir freuen uns, dich beim Abiball zu sehen.

+
+ +
+
+

Veranstaltungsdetails

+
+
+
+ +

Sa. 28.06.2025

+
+
+ +

17:30 - Open End

+
+
+ +

Graubündener Str. 4, 28325 Bremen

+
+
+ +

Abendkleidung

+
+
+
+
+ +
+

Ablauf

+
+
+
+ + 17:30-19:30 + Einlass & Platznehmen +
+
+ + 19:30-22:00 + Dinner & Beisammensein +
+
+ + ab 22:00 + Feier & Tanz im Saal +
+
+
+
+
+ + +