nimuli/app/Livewire/Pages/Bio/Edit.php

158 lines
5.1 KiB
PHP

<?php
namespace App\Livewire\Pages\Bio;
use App\Domains\Bio\Models\BioBlock;
use App\Domains\Bio\Models\BioPage;
use Illuminate\View\View;
use Livewire\Component;
class Edit extends Component
{
public int $pageId = 0;
public string $workspaceUlid = '';
public string $publicUrlBase = '';
public string $displayUrlBase = '';
public function mount(string $bioUlid): void
{
$workspace = require_workspace();
$page = BioPage::where('ulid', $bioUlid)
->where('workspace_id', $workspace->id)
->firstOrFail();
$this->pageId = $page->id;
$this->workspaceUlid = $workspace->ulid;
$apex = config('services.hetzner.zone', 'nimu.li');
if (! $workspace->isFreePlan() && $workspace->subdomain_full) {
$this->publicUrlBase = "https://{$workspace->subdomain_full}/b";
$this->displayUrlBase = "{$workspace->subdomain_full}/b";
} else {
$this->publicUrlBase = "https://{$apex}/b/{$workspace->slug}";
$this->displayUrlBase = "{$apex}/b/{$workspace->slug}";
}
}
public function save(array $state): void
{
$page = BioPage::findOrFail($this->pageId);
$newSlug = $state['slug'] ?? $page->slug;
$slugTaken = BioPage::where('workspace_id', $page->workspace_id)
->where('slug', $newSlug)
->where('id', '!=', $page->id)
->whereNull('deleted_at')
->exists();
if ($slugTaken) {
$this->dispatch('toast', message: 'Slug "' . $newSlug . '" ist bereits vergeben.', type: 'error');
return;
}
if (! preg_match('/^[a-zA-Z0-9_-]{1,64}$/', $newSlug)) {
$this->dispatch('toast', message: 'Slug: nur Buchstaben, Zahlen, - und _. Max 64 Zeichen.', type: 'error');
return;
}
$displayName = $state['profile']['displayName'] ?? '';
$page->update([
'slug' => $newSlug,
'title' => ['en' => $displayName, 'de' => $displayName],
'is_published' => false,
'theme' => [
'profile' => $state['profile'] ?? [],
'theme' => $state['theme'] ?? [],
'socials' => $state['socials'] ?? [],
],
]);
BioBlock::where('bio_page_id', $this->pageId)->delete();
foreach ($state['blocks'] ?? [] as $i => $block) {
BioBlock::create([
'bio_page_id' => $this->pageId,
'position' => $i,
'type' => $block['type'] ?? 'link',
'config' => array_diff_key($block, array_flip(['id', 'type', '_collapsed'])),
]);
}
$this->dispatch('toast', message: 'Gespeichert', type: 'success');
}
public function publish(array $state): void
{
$this->save($state);
BioPage::where('id', $this->pageId)->update(['is_published' => true]);
$this->dispatch('toast', message: 'Veröffentlicht', type: 'success');
}
public function unpublish(): void
{
BioPage::where('id', $this->pageId)->update(['is_published' => false]);
$this->dispatch('toast', message: 'Als Entwurf gespeichert', type: 'success');
}
public function render(): View
{
$page = BioPage::with('blocks')->findOrFail($this->pageId);
$theme = is_array($page->theme) ? $page->theme : [];
$initialState = [
'uid' => $page->blocks->count() + 100,
'slug' => $page->slug,
'isPublished' => $page->is_published,
'profile' => $theme['profile'] ?? [
'avatar' => null,
'displayName' => $page->getTranslation('title', 'en'),
'handle' => $page->slug,
'bio' => '',
'verified' => false,
],
'theme' => array_merge([
'bgType' => 'gradient',
'bg1' => '#0f0a2e',
'bg2' => '#6b1b9a',
'bgImage' => null,
'dark' => true,
'button' => 'rounded',
'font' => 'geist',
'borderColor' => '#7c3aed',
'shadowColor' => '#18181b',
], $theme['theme'] ?? []),
'socials' => $theme['socials'] ?? [],
'blocks' => $page->blocks
->sortBy('position')
->map(fn ($b) => array_merge(
['id' => $b->id, 'type' => $b->type],
$b->config ?? []
))
->values()
->toArray(),
];
return view('livewire.pages.bio.edit', [
'page' => $page,
'workspaceUlid' => $this->workspaceUlid,
'bioUlid' => $page->ulid,
'initialState' => $initialState,
'publicUrlBase' => $this->publicUrlBase,
'displayUrlBase' => $this->displayUrlBase,
])->layout('layouts.nimuli-app', ['title' => 'Bio Editor']);
}
}