feat(admin): Weeztix setup wizard, integration status badges

- Summary view when Weeztix is configured; edits only via 3-step wizard
- Step 1: reuse or replace OAuth client ID/secret; callback URL shown
- Step 2: OAuth connect (resume wizard after callback when started from wizard)
- Step 3: coupon, prefix, usage; finishing exits wizard
- PreregistrationPage: mailwizz/weeztix integration status helpers
- Pages index: Integrations column with MW/WZ badges; edit page: status cards

Made-with: Cursor
This commit is contained in:
2026-04-05 11:12:10 +02:00
parent e0de8a05fa
commit 89931b817d
8 changed files with 504 additions and 210 deletions

View File

@@ -28,7 +28,7 @@ class PageController extends Controller
{
$query = PreregistrationPage::query()
->withCount('subscribers')
->with('weeztixConfig')
->with(['weeztixConfig', 'mailwizzConfig'])
->orderByDesc('start_date');
if (! $request->user()?->isSuperadmin()) {
@@ -86,7 +86,11 @@ class PageController extends Controller
public function edit(PreregistrationPage $page): View
{
$page->load(['blocks' => fn ($q) => $q->orderBy('sort_order')]);
$page->load([
'blocks' => fn ($q) => $q->orderBy('sort_order'),
'mailwizzConfig',
'weeztixConfig',
]);
return view('admin.pages.edit', compact('page'));
}

View File

@@ -8,18 +8,34 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\UpdateWeeztixConfigRequest;
use App\Models\PreregistrationPage;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
class WeeztixController extends Controller
{
public function edit(PreregistrationPage $page): View
public function edit(Request $request, PreregistrationPage $page): View
{
$this->authorize('update', $page);
$page->load('weeztixConfig');
return view('admin.weeztix.edit', compact('page'));
$showWizard = $page->weeztixConfig === null || $request->boolean('wizard');
$wizardStep = $showWizard ? min(3, max(1, (int) $request->query('step', 1))) : 1;
if ($showWizard && $page->weeztixConfig === null && $wizardStep !== 1) {
return redirect()
->route('admin.pages.weeztix.edit', ['page' => $page, 'wizard' => 1, 'step' => 1]);
}
$hasStoredCredentials = $page->weeztixConfig !== null
&& is_string($page->weeztixConfig->client_id)
&& $page->weeztixConfig->client_id !== '';
return view('admin.weeztix.edit', compact(
'page',
'showWizard',
'wizardStep',
'hasStoredCredentials'
));
}
public function update(UpdateWeeztixConfigRequest $request, PreregistrationPage $page): RedirectResponse
@@ -41,8 +57,26 @@ class WeeztixController extends Controller
);
});
$page->load('weeztixConfig');
if ($request->boolean('wizard')) {
if ($request->boolean('wizard_coupon_save')) {
return redirect()
->route('admin.pages.weeztix.edit', ['page' => $page])
->with('status', __('Weeztix-configuratie opgeslagen.'));
}
return redirect()
->route('admin.pages.weeztix.edit', [
'page' => $page,
'wizard' => 1,
'step' => 2,
])
->with('status', __('Weeztix-configuratie opgeslagen.'));
}
return redirect()
->route('admin.pages.weeztix.edit', $page)
->route('admin.pages.weeztix.edit', ['page' => $page])
->with('status', __('Weeztix-configuratie opgeslagen.'));
}

View File

@@ -15,7 +15,7 @@ use RuntimeException;
class WeeztixOAuthController extends Controller
{
public function redirect(PreregistrationPage $page): RedirectResponse
public function redirect(Request $request, PreregistrationPage $page): RedirectResponse
{
$this->authorize('update', $page);
@@ -38,6 +38,7 @@ class WeeztixOAuthController extends Controller
session([
'weeztix_oauth_state' => $state,
'weeztix_page_id' => $page->id,
'weeztix_oauth_resume_wizard' => $request->boolean('wizard'),
]);
$redirectUri = $config->redirect_uri;
@@ -90,7 +91,7 @@ class WeeztixOAuthController extends Controller
$config = $page->weeztixConfig;
if ($config === null) {
session()->forget(['weeztix_oauth_state', 'weeztix_page_id']);
$this->forgetOauthSession();
return redirect()
->route('admin.pages.weeztix.edit', $page)
@@ -110,30 +111,52 @@ class WeeztixOAuthController extends Controller
'message' => $e->getMessage(),
]);
session()->forget(['weeztix_oauth_state', 'weeztix_page_id']);
$resumeWizard = $this->forgetOauthSession();
return redirect()
->route('admin.pages.weeztix.edit', $page)
->route('admin.pages.weeztix.edit', $this->weeztixEditParams($page, $resumeWizard, 2))
->with('error', __('Verbinden met Weeztix is mislukt. Controleer je gegevens en probeer opnieuw.'));
}
session()->forget(['weeztix_oauth_state', 'weeztix_page_id']);
$resumeWizard = $this->forgetOauthSession();
return redirect()
->route('admin.pages.weeztix.edit', $page)
->route('admin.pages.weeztix.edit', $this->weeztixEditParams($page, $resumeWizard, 3))
->with('status', __('Succesvol verbonden met Weeztix.'));
}
/**
* @return array{page: PreregistrationPage, wizard?: int, step?: int}
*/
private function weeztixEditParams(PreregistrationPage $page, bool $resumeWizard, int $step): array
{
$params = ['page' => $page];
if ($resumeWizard) {
$params['wizard'] = 1;
$params['step'] = $step;
}
return $params;
}
private function forgetOauthSession(): bool
{
$resumeWizard = (bool) session()->pull('weeztix_oauth_resume_wizard', false);
session()->forget(['weeztix_oauth_state', 'weeztix_page_id']);
return $resumeWizard;
}
private function redirectToWeeztixEditWithSessionPage(string $message): RedirectResponse
{
$pageId = session('weeztix_page_id');
session()->forget(['weeztix_oauth_state', 'weeztix_page_id']);
$resumeWizard = $this->forgetOauthSession();
if (is_int($pageId) || is_numeric($pageId)) {
$page = PreregistrationPage::query()->find((int) $pageId);
if ($page !== null) {
return redirect()
->route('admin.pages.weeztix.edit', $page)
->route('admin.pages.weeztix.edit', $this->weeztixEditParams($page, $resumeWizard, 2))
->with('error', $message);
}
}