Compare commits

..

No commits in common. "c83c892f53dd20504a29140c72d1ff997ecfac11" and "9610bee8ca705eece43d104401f0841db621ac79" have entirely different histories.

16 changed files with 148 additions and 309 deletions

View File

@ -3,9 +3,7 @@
namespace Silva\Adrema; namespace Silva\Adrema;
use Backend; use Backend;
use Silva\Adrema\Components\EventDescription;
use Silva\Adrema\Components\EventIndex; use Silva\Adrema\Components\EventIndex;
use Silva\Adrema\Components\EventRegister;
use Silva\Adrema\Models\Settings; use Silva\Adrema\Models\Settings;
use System\Classes\PluginBase; use System\Classes\PluginBase;
@ -52,8 +50,6 @@ class Plugin extends PluginBase
{ {
return [ return [
EventIndex::class => 'adrema_event_index', EventIndex::class => 'adrema_event_index',
EventRegister::class => 'adrema_event_register',
EventDescription::class => 'adrema_event_description',
]; ];
} }

@ -1 +1 @@
Subproject commit 9666310ebfa9125ea0d2771b63166b39d7179999 Subproject commit 57e0c30952ee42ce2d8a4c9fb9af4e4c709d657e

View File

@ -1,17 +0,0 @@
<?php
namespace Silva\Adrema\Components;
class EventDescription extends EventManager
{
public function onRun()
{
$this->loadColors();
$this->loadSingleEvent();
}
public function isRegistering(): bool
{
return false;
}
}

View File

@ -2,10 +2,125 @@
namespace Silva\Adrema\Components; namespace Silva\Adrema\Components;
class EventIndex extends EventManager use Cms\Classes\ComponentBase;
use Cms\Classes\Page;
use Silva\Adrema\Exceptions\ComponentException;
use Silva\Adrema\Models\Settings;
use Silva\Adrema\Support\FetchAllEvents;
class EventIndex extends ComponentBase
{ {
protected function isRegistering(): bool
public $settings;
/** @var string The active event */
public ?string $eventSlug;
public ?array $event;
public string $currentUrl;
public function componentDetails()
{ {
return false; return [
'name' => 'EventOverview Component',
'description' => 'No description provided yet...'
];
}
public function onRun()
{
$this->addJs('assets/vendor/adrema-form/dist/main.js');
$this->currentUrl = url()->current();
// $this->addJs('http://localhost:5174/src/main.js', ['type' => 'module']);
$this->settings = [
'primary_color' => Settings::get('primary_color'),
...$this->resolvePageUrls(),
];
$this->eventSlug = $this->property('eventSlug');
if ($this->eventSlug) {
$events = data_get(app(FetchAllEvents::class)->run(), 'data');
throw_if(is_null($events), ComponentException::class, 'event_fetching_failed');
$this->event = collect($events)->first(fn ($event) => $event['slug'] === $this->eventSlug);
$this->page->title = $this->event['name'];
}
}
/**
* @return array<string, string>
*/
protected function resolvePageUrls(): array
{
$indexPage = $this->getPageFromProperty('indexPage');
$singlePage = $this->getPageFromProperty('singlePage');
$registerPage = $this->getPageFromProperty('registerPage');
throw_if(!str($singlePage->url)->contains(':slug'), ComponentException::class, 'slug_not_found');
throw_if(!str($registerPage->url)->contains(':slug'), ComponentException::class, 'slug_not_found');
return [
'indexUrl' => $indexPage->url,
'singleUrl' => $singlePage->url,
'registerUrl' => $registerPage->url,
];
}
protected function getPageFromProperty(string $property): Page
{
throw_if(!$this->property('indexPage') || !$this->property('singlePage') || !$this->property('registerPage'), ComponentException::class, 'not_all_pages_set');
$page = Page::find($this->property($property));
throw_if($page === null, ComponentException::class, 'page_not_found');
return $page;
}
public function defineProperties()
{
return [
'indexPage' => [
'title' => __('properties.index_page_title'),
'type' => 'dropdown',
'default' => null,
],
'singlePage' => [
'title' => __('properties.single_page_title'),
'type' => 'dropdown',
'default' => null,
],
'registerPage' => [
'title' => __('properties.register_page_title'),
'type' => 'dropdown',
'default' => null,
],
'eventSlug' => [
'title' => __('properties.event_slug_title'),
'type' => 'text',
'default' => null,
],
];
}
public function getIndexPageOptions(): array
{
return $this->pageOptions();
}
public function getSinglePageOptions(): array
{
return $this->pageOptions();
}
public function getRegisterPageOptions(): array
{
return $this->pageOptions();
}
private function pageOptions(): array
{
return Page::get()
->mapWithKeys(fn ($page) => [$page->fileName => $page->title])
->toArray();
} }
} }

View File

@ -1,178 +0,0 @@
<?php
namespace Silva\Adrema\Components;
use Illuminate\Support\Collection;
use Cms\Classes\ComponentBase;
use Cms\Classes\Page;
use Silva\Adrema\Exceptions\ComponentException;
use Silva\Adrema\Models\Settings;
use Silva\Adrema\Support\FetchAllEvents;
use Silva\Adrema\Support\FetchSingleEvent;
abstract class EventManager extends ComponentBase
{
public array $settings = [];
public ?array $event = null;
/** @var Collection<int, mixed> */
public Collection $events;
public string $currentUrl;
abstract protected function isRegistering(): bool;
public function componentDetails()
{
$componentName = str(class_basename(static::class))->snake();
return [
'name' => __("{$componentName}_component_name"),
'description' => __("{$componentName}_component_description"),
];
}
public function onRun()
{
$this->addAssets();
$this->loadColors();
$this->loadSettings();
$this->loadSingleEvent();
$this->page['breadcrumbs'] = $this->getBreadcrumbs();
}
private function getBreadcrumbs(): Collection
{
$breadcrumbs = collect([]);
$breadcrumbs->push(['url' => $this->settings['indexUrl'], 'title' => 'Veranstaltungen', 'isActive' => $this->event === null]);
if ($this->event) {
$breadcrumbs->push([
'url' => (string) str($this->settings['singleUrl'])->replace(':slug', $this->event['slug']),
'title' => $this->event['name'],
'isActive' => !$this->isRegistering()
]);
}
if ($this->event && $this->isRegistering()) {
$breadcrumbs->push([
'url' => (string) str($this->settings['registerUrl'])->replace(':slug', $this->event['slug']),
'title' => 'Anmeldung',
'isActive' => true,
]);
}
return $breadcrumbs;
}
public function defineProperties()
{
return [
'indexPage' => [
'title' => __('properties.index_page_title'),
'type' => 'dropdown',
'default' => null,
],
'singlePage' => [
'title' => __('properties.single_page_title'),
'type' => 'dropdown',
'default' => null,
],
'registerPage' => [
'title' => __('properties.register_page_title'),
'type' => 'dropdown',
'default' => null,
],
'eventSlug' => [
'title' => __('properties.event_slug_title'),
'type' => 'text',
'default' => null,
],
];
}
public function getIndexPageOptions(): array
{
return $this->pageOptions();
}
public function getSinglePageOptions(): array
{
return $this->pageOptions();
}
public function getRegisterPageOptions(): array
{
return $this->pageOptions();
}
private function pageOptions(): array
{
return Page::get()
->mapWithKeys(fn ($page) => [$page->fileName => $page->title])
->toArray();
}
private function getPageFromProperty(string $property): Page
{
throw_if(!$this->property('indexPage') || !$this->property('singlePage') || !$this->property('registerPage'), ComponentException::class, 'not_all_pages_set');
$page = Page::find($this->property($property));
throw_if($page === null, ComponentException::class, 'page_not_found');
return $page;
}
/**
* @return array<string, string>
*/
private function resolvePageUrls(): array
{
$indexPage = $this->getPageFromProperty('indexPage');
$singlePage = $this->getPageFromProperty('singlePage');
$registerPage = $this->getPageFromProperty('registerPage');
throw_if(!str($singlePage->url)->contains(':slug'), ComponentException::class, 'slug_not_found');
throw_if(!str($registerPage->url)->contains(':slug'), ComponentException::class, 'slug_not_found');
return [
'indexUrl' => $indexPage->url,
'singleUrl' => $singlePage->url,
'registerUrl' => $registerPage->url,
];
}
protected function loadSingleEvent(): void
{
$eventSlug = $this->property('eventSlug');
if (!$eventSlug) {
return;
}
$this->events = $this->page['events'] = collect(app(FetchAllEvents::class)->run()['data']);
$this->event = $this->page['event'] = $this->events->first(fn ($event) => $event['slug'] == $eventSlug);
$this->currentUrl = url()->current();
}
private function addAssets(): void
{
// $this->addJs('assets/vendor/adrema-form/dist/main.js');
$this->addJs('http://localhost:5174/src/main.js', ['type' => 'module']);
}
private function loadSettings(): void
{
$this->settings = [
...$this->settings,
...$this->resolvePageUrls(),
];
}
protected function loadColors(): void
{
$this->settings = [
...$this->settings,
'primary_color' => Settings::get('primary_color'),
];
}
}

View File

@ -1,11 +0,0 @@
<?php
namespace Silva\Adrema\Components;
class EventRegister extends EventManager
{
protected function isRegistering(): bool
{
return true;
}
}

View File

@ -1,9 +0,0 @@
<script type="text/javascript">
var adrema_event_description = {{__SELF__.event.description | json_encode | raw}};
</script>
<event-description
description-var-name="adrema_event_description"
style="--primary: {{__SELF__.settings.primary_color}}; --primaryfg: #d1f8ff; --secondary: #800a19; --font: hsl(181, 84%, 78%); --circle: hsl(181, 86%, 16%)"
image="{{__SELF__.event.image }}"
></event-description>

View File

@ -1,9 +1,18 @@
{% include 'silva.adrema::head' %} {% if __SELF__.event %}
{% put metatags %}
<meta property="og:title" content="{{__SELF__.event.name}}">
<meta property="og:url" content="{{__SELF__.currentUrl}}">
<meta property="og:description" content="{{__SELF__.event.excerpt}}">
<meta property="og:image" content="{{__SELF__.event.image}}">
<meta property="og:type" content="article">
{% endput %}
{% endif %}
<event-index <event-index
style="--primary: {{__SELF__.settings.primary_color}}; --primaryfg: #d1f8ff; --secondary: #800a19; --font: hsl(181, 84%, 78%); --circle: hsl(181, 86%, 16%)" style="--primary: {{__SELF__.settings.primary_color}}; --primaryfg: #d1f8ff; --secondary: #800a19; --font: hsl(181, 84%, 78%); --circle: hsl(181, 86%, 16%)"
index-url="{{__SELF__.settings.indexUrl}}" index-url="{{__SELF__.settings.indexUrl}}"
single-url="{{__SELF__.settings.singleUrl}}" single-url="{{__SELF__.settings.singleUrl}}"
register-url="{{__SELF__.settings.registerUrl}}" register-url="{{__SELF__.settings.registerUrl}}"
{% if __SELF__.event %} visible-event-slug="{{__SELF__.event.slug }}" {% endif %} url="/api/silva_adrema_event_overview"
{% if __SELF__.event %} event="{{__SELF__.event.slug }}" {% endif %}
></event-index> ></event-index>

View File

@ -1,9 +0,0 @@
{% include 'silva.adrema::head' %}
<event-form
style="--primary: {{__SELF__.settings.primary_color}}; --primaryfg: #d1f8ff; --secondary: #800a19; --font: hsl(181, 84%, 78%); --circle: hsl(181, 86%, 16%)"
index-url="{{__SELF__.settings.indexUrl}}"
single-url="{{__SELF__.settings.singleUrl}}"
register-url="{{__SELF__.settings.registerUrl}}"
config-var-name="adrema_event_config"
></event-form>

View File

@ -5,9 +5,5 @@
"properties.index_page_title": "Seite für Übersicht", "properties.index_page_title": "Seite für Übersicht",
"properties.single_page_title": "Seite für Einzelansicht", "properties.single_page_title": "Seite für Einzelansicht",
"properties.register_page_title": "Seite zum anmelden", "properties.register_page_title": "Seite zum anmelden",
"event_index_component_name": "Veranstaltungs-Übersicht",
"event_index_component_description": "Übersicht aller bevorstehenden Adrema-Veranstaltungen.",
"event_register_component_name": "Veranstaltungs-Anmeldung",
"event_register_component_description": "Für einzelne Veranstaltung anmelden.",
"properties.event_slug_title": "Veranstaltung slug" "properties.event_slug_title": "Veranstaltung slug"
} }

View File

@ -6,10 +6,6 @@
"properties.single_page_title": "Page for single view", "properties.single_page_title": "Page for single view",
"properties.register_page_title": "Page for registration", "properties.register_page_title": "Page for registration",
"properties.event_slug_title": "Event slug", "properties.event_slug_title": "Event slug",
"event_index_component_name": "Event overview",
"event_index_component_description": "Overview of all upcoming Adrema-Events",
"event_register_component_name": "Event-Registration",
"event_register_component_description": "Register for a single event.",
"errors.not_all_pages_set": "You didn't assign all pages. Please edit your components.", "errors.not_all_pages_set": "You didn't assign all pages. Please edit your components.",
"errors.page_not_found": "One page cannot be found. Event component cannot be rendered.", "errors.page_not_found": "One page cannot be found. Event component cannot be rendered.",
"errors.slug_not_found": "You need to set a placeholder in page urls to set the event slug (\":slug\")", "errors.slug_not_found": "You need to set a placeholder in page urls to set the event slug (\":slug\")",

View File

@ -1,9 +1,13 @@
<?php <?php
use Silva\Adrema\Support\Proxy; use Silva\Adrema\Support\FetchAllEvents;
Route::get( Route::get('/api/silva_adrema_event_overview', function () {
'/adrema-api/{route}', $events = app(FetchAllEvents::class)->run();
fn (string $route) => Response::json(app(Proxy::class)->run($route))
) if (is_null($events)) {
->where('route', '[a-zA-Z0-9\-/]+')->middleware('api'); return Response::json(['message' => 'Fehler beim Laden der Veranstaltungen'], 422);
}
return Response::json($events);
})->middleware('api');

View File

@ -2,17 +2,20 @@
namespace Silva\Adrema\Support; namespace Silva\Adrema\Support;
use Illuminate\Support\Collection; use Silva\Adrema\Models\Settings;
use Http;
class FetchAllEvents class FetchAllEvents
{ {
public function run(): ?Collection public function run(): ?array
{ {
$events = app(Proxy::class)->run('/api/form'); $baseUrl = Settings::get('base_url');
$response = Http::get($baseUrl . '/api/form');
if (!$events) { if (!$response->ok()) {
return null; return null;
} }
return collect($events);
return $response->json();
} }
} }

View File

@ -1,14 +0,0 @@
<?php
namespace Silva\Adrema\Support;
class FetchSingleEvent
{
public function run(string $slug): ?array
{
$events = data_get(app(FetchAllEvents::class)->run(), 'data');
throw_if(is_null($events), ComponentException::class, 'event_fetching_failed');
return collect($events)->first(fn ($event) => $event['slug'] === $slug);
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace Silva\Adrema\Support;
use Silva\Adrema\Models\Settings;
use Http;
class Proxy
{
public function run(string $url): ?array
{
$url = str($url)->start('/');
$baseUrl = Settings::get('base_url');
$response = Http::get($baseUrl . $url);
if (!$response->ok()) {
return null;
}
return $response->json();
}
}

View File

@ -1,19 +0,0 @@
{% if __SELF__.event %}
{% put metatags %}
<meta property="og:title" content="{{__SELF__.event.name}}">
<meta property="og:url" content="{{__SELF__.currentUrl}}">
<meta property="og:description" content="{{__SELF__.event.excerpt}}">
<meta property="og:image" content="{{__SELF__.event.image}}">
<meta property="og:type" content="article">
{% endput %}
<script type="text/javascript">
var adrema_event_config = {{__SELF__.event.config | json_encode | raw}};
</script>
{% endif %}
{% put metatags %}
<meta name="adrema_base_url" content="/adrema-api">
{% endput %}