diff --git a/.gitignore b/.gitignore index c7cf1fa..63b50a5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /public/storage /storage/*.key /storage/pail +/storage/media-library /vendor .env .env.backup diff --git a/lang/de.json b/lang/de.json index f77f2a7..f9824a0 100644 --- a/lang/de.json +++ b/lang/de.json @@ -473,5 +473,22 @@ "Über den Kurs": "", "Über uns": "", "Login with lightning ⚡": "", - "Wähle die Stadt aus...": "" + "Wähle die Stadt aus...": "", + ":count Events erfolgreich erstellt!": "", + "Serientermine erstellen": "", + "Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen": "", + "Datum des ersten Termins": "", + "Datum des letzten Termins": "", + "Intervall": "", + "Monatlich": "", + "Wöchentlich": "", + "Wie oft soll das Event wiederholt werden?": "", + "Vorschau der Termine": "", + "Uhr": "", + "Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.": "", + "Serientermine erstellen?": "", + "Du bist dabei, mehrere Events zu erstellen.": "", + "Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.": "", + "Bist du sicher, dass die Einstellungen korrekt sind?": "", + "Jetzt erstellen": "" } \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index 7e2ab32..c431d6f 100644 --- a/lang/en.json +++ b/lang/en.json @@ -473,5 +473,22 @@ "Über den Kurs": "About the course", "Über uns": "About us", "Login with lightning ⚡": "Login with lightning ⚡", - "Wähle die Stadt aus...": "Select the city..." + "Wähle die Stadt aus...": "Select the city...", + ":count Events erfolgreich erstellt!": ":count events successfully created!", + "Serientermine erstellen": "Create recurring events", + "Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen": "Enable this option to create multiple events at regular intervals", + "Datum des ersten Termins": "Date of first event", + "Datum des letzten Termins": "Date of last event", + "Intervall": "Interval", + "Monatlich": "Monthly", + "Wöchentlich": "Weekly", + "Wie oft soll das Event wiederholt werden?": "How often should the event be repeated?", + "Vorschau der Termine": "Preview of events", + "Uhr": "o'clock", + "Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.": "Preview limited to 100 events. More events may be created.", + "Serientermine erstellen?": "Create recurring events?", + "Du bist dabei, mehrere Events zu erstellen.": "You are about to create multiple events.", + "Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.": "Incorrectly created events must all be deleted manually.", + "Bist du sicher, dass die Einstellungen korrekt sind?": "Are you sure the settings are correct?", + "Jetzt erstellen": "Create now" } diff --git a/lang/es.json b/lang/es.json index dac6075..87448a5 100644 --- a/lang/es.json +++ b/lang/es.json @@ -472,5 +472,22 @@ "Über den Kurs": "Sobre el curso", "Über uns": "Sobre nosotros", "Login with lightning ⚡": "Inicia sesión con lightning ⚡", - "Wähle die Stadt aus...": "Selecciona la ciudad..." + "Wähle die Stadt aus...": "Selecciona la ciudad...", + ":count Events erfolgreich erstellt!": "¡:count eventos creados exitosamente!", + "Serientermine erstellen": "Crear eventos recurrentes", + "Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen": "Activa esta opción para crear múltiples eventos con intervalos regulares", + "Datum des ersten Termins": "Fecha del primer evento", + "Datum des letzten Termins": "Fecha del último evento", + "Intervall": "Intervalo", + "Monatlich": "Mensual", + "Wöchentlich": "Semanal", + "Wie oft soll das Event wiederholt werden?": "¿Con qué frecuencia debe repetirse el evento?", + "Vorschau der Termine": "Vista previa de eventos", + "Uhr": "hora", + "Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.": "Vista previa limitada a 100 eventos. Es posible que se creen más eventos.", + "Serientermine erstellen?": "¿Crear eventos recurrentes?", + "Du bist dabei, mehrere Events zu erstellen.": "Estás a punto de crear múltiples eventos.", + "Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.": "Los eventos creados incorrectamente deberán eliminarse manualmente.", + "Bist du sicher, dass die Einstellungen korrekt sind?": "¿Estás seguro de que la configuración es correcta?", + "Jetzt erstellen": "Crear ahora" } diff --git a/lang/hu.json b/lang/hu.json index d8101ef..2162449 100644 --- a/lang/hu.json +++ b/lang/hu.json @@ -467,5 +467,23 @@ "Über den Kurs": "A kurzusról", "Über uns": "Rólunk", "Login with lightning ⚡": "Bejelentkezés lightning-gal ⚡", - "Wähle die Stadt aus...": "Válaszd ki a várost..." + "Wähle die Stadt aus...": "Válaszd ki a várost...", + ":count Events erfolgreich erstellt!": ":count esemény sikeresen létrehozva!", + "Serientermine erstellen": "Ismétlődő időpontok létrehozása", + "Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen": "Aktiváld ezt az opciót több esemény rendszeres időközönkénti létrehozásához", + "Datum des ersten Termins": "Az első időpont dátuma", + "Datum des letzten Termins": "Az utolsó időpont dátuma", + "Intervall": "Intervallum", + "Monatlich": "Havonta", + "Wöchentlich": "Hetente", + "Wie oft soll das Event wiederholt werden?": "Milyen gyakran ismétlődjön az esemény?", + "Vorschau der Termine": "Időpontok előnézete", + "Events": "Események", + "Uhr": "óra", + "Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.": "Az előnézet 100 időpontra korlátozódik. Lehet, hogy több időpont lesz létrehozva.", + "Serientermine erstellen?": "Ismétlődő időpontok létrehozása?", + "Du bist dabei, mehrere Events zu erstellen.": "Több esemény létrehozására készülsz.", + "Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.": "A hibásan létrehozott időpontokat egyesével kell törölni.", + "Bist du sicher, dass die Einstellungen korrekt sind?": "Biztos vagy benne, hogy a beállítások megfelelőek?", + "Jetzt erstellen": "Létrehozás most" } diff --git a/lang/nl.json b/lang/nl.json index 544f085..4315266 100644 --- a/lang/nl.json +++ b/lang/nl.json @@ -469,5 +469,23 @@ "Über den Kurs": "Over de cursus", "Über uns": "Over ons", "Login with lightning ⚡": "Login met lightning ⚡", - "Wähle die Stadt aus...": "Selecteer de stad..." + "Wähle die Stadt aus...": "Selecteer de stad...", + ":count Events erfolgreich erstellt!": ":count evenementen succesvol aangemaakt!", + "Serientermine erstellen": "Serie-afspraken aanmaken", + "Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen": "Activeer deze optie om meerdere evenementen met regelmatige intervallen aan te maken", + "Datum des ersten Termins": "Datum van de eerste afspraak", + "Datum des letzten Termins": "Datum van de laatste afspraak", + "Intervall": "Interval", + "Monatlich": "Maandelijks", + "Wöchentlich": "Wekelijks", + "Wie oft soll das Event wiederholt werden?": "Hoe vaak moet het evenement worden herhaald?", + "Vorschau der Termine": "Voorvertoning van afspraken", + "Events": "Evenementen", + "Uhr": "uur", + "Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.": "Voorvertoning beperkt tot 100 afspraken. Er kunnen mogelijk meer afspraken worden aangemaakt.", + "Serientermine erstellen?": "Serie-afspraken aanmaken?", + "Du bist dabei, mehrere Events zu erstellen.": "Je staat op het punt meerdere evenementen aan te maken.", + "Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.": "Verkeerd aangemaakte afspraken moeten allemaal handmatig weer worden verwijderd.", + "Bist du sicher, dass die Einstellungen korrekt sind?": "Weet je zeker dat de instellingen correct zijn?", + "Jetzt erstellen": "Nu aanmaken" } diff --git a/lang/pl.json b/lang/pl.json index d770352..c5d9dc9 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -445,5 +445,23 @@ "Update Venue": "Zaktualizuj miejsce", "Venues": "Miejsca", "Verbinde dich mit Bitcoinern in deiner Nähe": "Połącz się z Bitcoinerami w Twojej okolicy", - "Wähle die Stadt aus...": "Wybierz miasto..." + "Wähle die Stadt aus...": "Wybierz miasto...", + ":count Events erfolgreich erstellt!": ":count wydarzeń zostało pomyślnie utworzonych!", + "Serientermine erstellen": "Utwórz terminy cykliczne", + "Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen": "Włącz tę opcję, aby utworzyć wiele wydarzeń w regularnych odstępach czasu", + "Datum des ersten Termins": "Data pierwszego terminu", + "Datum des letzten Termins": "Data ostatniego terminu", + "Intervall": "Interwał", + "Monatlich": "Miesięcznie", + "Wöchentlich": "Tygodniowo", + "Wie oft soll das Event wiederholt werden?": "Jak często wydarzenie ma być powtarzane?", + "Vorschau der Termine": "Podgląd terminów", + "Events": "Wydarzenia", + "Uhr": "godz.", + "Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.": "Podgląd ograniczony do 100 terminów. Może zostać utworzonych więcej terminów.", + "Serientermine erstellen?": "Utworzyć terminy cykliczne?", + "Du bist dabei, mehrere Events zu erstellen.": "Zamierzasz utworzyć wiele wydarzeń.", + "Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.": "Błędnie utworzone terminy trzeba będzie usunąć ręcznie.", + "Bist du sicher, dass die Einstellungen korrekt sind?": "Czy jesteś pewien, że ustawienia są prawidłowe?", + "Jetzt erstellen": "Utwórz teraz" } diff --git a/lang/pt.json b/lang/pt.json index 5472ca6..c391e38 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -467,5 +467,23 @@ "Über den Kurs": "Sobre o curso", "Über uns": "Sobre nós", "Login with lightning ⚡": "Login com lightning ⚡", - "Wähle die Stadt aus...": "Selecione a cidade..." + "Wähle die Stadt aus...": "Selecione a cidade...", + ":count Events erfolgreich erstellt!": ":count eventos criados com sucesso!", + "Serientermine erstellen": "Criar eventos recorrentes", + "Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen": "Ative esta opção para criar vários eventos com intervalos regulares", + "Datum des ersten Termins": "Data do primeiro evento", + "Datum des letzten Termins": "Data do último evento", + "Intervall": "Intervalo", + "Monatlich": "Mensal", + "Wöchentlich": "Semanal", + "Wie oft soll das Event wiederholt werden?": "Com que frequência o evento deve ser repetido?", + "Vorschau der Termine": "Prévia dos eventos", + "Events": "Eventos", + "Uhr": "horas", + "Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.": "Prévia limitada a 100 eventos. Mais eventos podem ser criados.", + "Serientermine erstellen?": "Criar eventos recorrentes?", + "Du bist dabei, mehrere Events zu erstellen.": "Você está prestes a criar vários eventos.", + "Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.": "Eventos criados incorretamente devem ser excluídos manualmente.", + "Bist du sicher, dass die Einstellungen korrekt sind?": "Tem certeza de que as configurações estão corretas?", + "Jetzt erstellen": "Criar agora" } diff --git a/resources/views/livewire/meetups/create-edit-events.blade.php b/resources/views/livewire/meetups/create-edit-events.blade.php index 736b8ca..d4edd2c 100644 --- a/resources/views/livewire/meetups/create-edit-events.blade.php +++ b/resources/views/livewire/meetups/create-edit-events.blade.php @@ -20,6 +20,44 @@ class extends Component { public string $startDate = ''; public string $startTime = ''; + public bool $seriesMode = false; + public string $endDate = ''; + public string $interval = 'monthly'; + + public function getPreviewDatesProperty(): array + { + if (!$this->seriesMode || !$this->startDate || !$this->endDate) { + return []; + } + + try { + $timezone = auth()->user()->timezone ?? 'Europe/Berlin'; + $startDate = \Carbon\Carbon::createFromFormat('Y-m-d H:i', $this->startDate . ' ' . $this->startTime, $timezone); + $endDate = \Carbon\Carbon::createFromFormat('Y-m-d', $this->endDate, $timezone); + + $dates = []; + $currentDate = $startDate->copy(); + + while ($currentDate->lessThanOrEqualTo($endDate) && count($dates) < 100) { + $dates[] = [ + 'date' => $currentDate->copy(), + 'formatted' => $currentDate->translatedFormat('l, d.m.Y'), + 'time' => $currentDate->format('H:i'), + ]; + + if ($this->interval === 'weekly') { + $currentDate->addWeek(); + } else { + $currentDate->addMonth(); + } + } + + return $dates; + } catch (\Exception $e) { + return []; + } + } + #[Validate('required|string|max:255')] public ?string $location = null; @@ -46,21 +84,43 @@ class extends Component { $defaultStart = now($timezone)->next('Monday')->setTime(19, 0); $this->startDate = $defaultStart->format('Y-m-d'); $this->startTime = $defaultStart->format('H:i'); + $this->endDate = $defaultStart->copy()->addMonths(6)->format('Y-m-d'); } } public function save(): void { - $this->validate([ + $validationRules = [ 'startDate' => 'required|date', 'startTime' => 'required', 'location' => 'required|string|max:255', 'description' => 'required|string', 'link' => 'required|url|max:255', - ]); + ]; + + if ($this->seriesMode) { + $validationRules['endDate'] = 'required|date|after:startDate'; + $validationRules['interval'] = 'required|in:weekly,monthly'; + } + + $this->validate($validationRules); $timezone = auth()->user()->timezone ?? 'Europe/Berlin'; + if ($this->seriesMode && !$this->event) { + // Create series of events + $this->createEventSeries($timezone); + } else { + // Create or update single event + $this->createOrUpdateSingleEvent($timezone); + } + + $this->redirect(route('meetups.landingpage', ['meetup' => $this->meetup, 'country' => $this->country]), + navigate: true); + } + + private function createOrUpdateSingleEvent(string $timezone): void + { // Combine date and time in user's timezone, then convert to UTC $localDateTime = \Carbon\Carbon::createFromFormat('Y-m-d H:i', $this->startDate . ' ' . $this->startTime, $timezone); $utcDateTime = $localDateTime->setTimezone('UTC'); @@ -86,9 +146,40 @@ class extends Component { ]); session()->flash('status', __('Event erfolgreich erstellt!')); } + } - $this->redirect(route('meetups.landingpage', ['meetup' => $this->meetup, 'country' => $this->country]), - navigate: true); + private function createEventSeries(string $timezone): void + { + $startDate = \Carbon\Carbon::createFromFormat('Y-m-d H:i', $this->startDate . ' ' . $this->startTime, $timezone); + $endDate = \Carbon\Carbon::createFromFormat('Y-m-d', $this->endDate, $timezone); + + $currentDate = $startDate->copy(); + $eventsCreated = 0; + + while ($currentDate->lessThanOrEqualTo($endDate)) { + $utcDateTime = $currentDate->copy()->setTimezone('UTC'); + + $this->meetup->meetupEvents()->create([ + 'start' => $utcDateTime, + 'location' => $this->location, + 'description' => $this->description, + 'link' => $this->link, + 'created_by' => auth()->id(), + 'attendees' => [], + 'might_attendees' => [], + ]); + + $eventsCreated++; + + // Move to next date based on interval + if ($this->interval === 'weekly') { + $currentDate->addWeek(); + } else { + $currentDate->addMonth(); + } + } + + session()->flash('status', __(':count Events erfolgreich erstellt!', ['count' => $eventsCreated])); } public function delete(): void @@ -109,15 +200,25 @@ class extends Component {
+ + @if(!$event) + + {{ __('Serientermine erstellen') }} + + {{ __('Aktiviere diese Option, um mehrere Events mit regelmäßigen Abständen zu erstellen') }} + + + @endif + {{ __('Event Details') }}
- {{ __('Datum') }} * + {{ $seriesMode ? __('Startdatum') : __('Datum') }} * - {{ __('An welchem Tag findet das Event statt?') }} + {{ $seriesMode ? __('Datum des ersten Termins') : __('An welchem Tag findet das Event statt?') }} @@ -129,6 +230,27 @@ class extends Component {
+ @if($seriesMode) +
+ + {{ __('Enddatum') }} * + + {{ __('Datum des letzten Termins') }} + + + + + {{ __('Intervall') }} * + + + + + {{ __('Wie oft soll das Event wiederholt werden?') }} + + +
+ @endif + {{ __('Ort') }} @@ -151,6 +273,40 @@ class extends Component {
+ + @if($seriesMode && count($this->previewDates) > 0) + +
+ {{ __('Vorschau der Termine') }} + {{ count($this->previewDates) }} {{ __('Events') }} +
+ + + +
+ @foreach($this->previewDates as $index => $dateInfo) + +
+
+ {{ $index + 1 }} +
+
+ {{ $dateInfo['formatted'] }} + {{ $dateInfo['time'] }} {{ __('Uhr') }} +
+
+
+ @endforeach +
+ + @if(count($this->previewDates) >= 100) + + {{ __('Vorschau auf 100 Termine begrenzt. Es werden möglicherweise mehr Termine erstellt.') }} + + @endif +
+ @endif +
@@ -174,10 +330,45 @@ class extends Component { @endif - - {{ $event ? __('Event aktualisieren') : __('Event erstellen') }} - + @if($seriesMode) + + + {{ __('Serientermine erstellen') }} + + + @else + + {{ $event ? __('Event aktualisieren') : __('Event erstellen') }} + + @endif
+ + + +
+
+ {{ __('Serientermine erstellen?') }} + + + {{ __('Du bist dabei, mehrere Events zu erstellen.') }}
+ {{ __('Falsch angelegte Termine müssen alle händisch wieder gelöscht werden.') }}

+ {{ __('Bist du sicher, dass die Einstellungen korrekt sind?') }} +
+
+ +
+ + + + {{ __('Abbrechen') }} + + + + {{ __('Jetzt erstellen') }} + +
+
+