263 lines
16 KiB
PHP
263 lines
16 KiB
PHP
@php
|
|
$config = $page->mailwizzConfig;
|
|
$existing = $config !== null
|
|
? [
|
|
'list_uid' => $config->list_uid,
|
|
'list_name' => $config->list_name,
|
|
'field_email' => $config->field_email,
|
|
'field_first_name' => $config->field_first_name,
|
|
'field_last_name' => $config->field_last_name,
|
|
'field_phone' => $config->field_phone,
|
|
'tag_field' => $config->tag_field,
|
|
'tag_value' => $config->tag_value,
|
|
]
|
|
: null;
|
|
@endphp
|
|
|
|
@extends('layouts.admin')
|
|
|
|
@section('title', __('Mailwizz') . ' — ' . $page->title)
|
|
|
|
@section('mobile_title', __('Mailwizz'))
|
|
|
|
@section('content')
|
|
<div class="mx-auto max-w-3xl" x-data="mailwizzWizard(@js([
|
|
'listsUrl' => route('admin.mailwizz.lists'),
|
|
'fieldsUrl' => route('admin.mailwizz.fields'),
|
|
'csrf' => csrf_token(),
|
|
'phoneEnabled' => $page->isPhoneFieldEnabledForSubscribers(),
|
|
'hasExistingConfig' => $config !== null,
|
|
'existing' => $existing,
|
|
'strings' => [
|
|
'apiKeyRequired' => __('Enter your Mailwizz API key to continue.'),
|
|
'genericError' => __('Something went wrong. Please try again.'),
|
|
'noListsError' => __('No mailing lists were returned. Check your API key or create a list in Mailwizz.'),
|
|
'selectListError' => __('Select a mailing list.'),
|
|
'mapFieldsError' => __('Map email, first name, and last name to Mailwizz fields.'),
|
|
'tagFieldError' => __('Select a checkbox list field for source / tag tracking.'),
|
|
'tagValueError' => __('Select the tag option that identifies this pre-registration.'),
|
|
],
|
|
]))">
|
|
<div class="mb-8">
|
|
<a href="{{ route('admin.pages.edit', $page) }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-500">← {{ __('Back to page') }}</a>
|
|
<h1 class="mt-4 text-2xl font-semibold text-slate-900">{{ __('Mailwizz') }}</h1>
|
|
<p class="mt-2 text-sm text-slate-600">{{ __('Page:') }} <span class="font-medium text-slate-800">{{ $page->title }}</span></p>
|
|
</div>
|
|
|
|
@if ($errors->any())
|
|
<div class="mb-6 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-900" role="alert">
|
|
<p class="font-medium">{{ __('Please fix the following:') }}</p>
|
|
<ul class="mt-2 list-disc space-y-1 pl-5">
|
|
@foreach ($errors->all() as $message)
|
|
<li>{{ $message }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
@if ($config !== null)
|
|
<div class="mb-8 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-900">
|
|
<p class="font-medium">{{ __('Integration active') }}</p>
|
|
<p class="mt-1 text-emerald-800">
|
|
{{ __('List:') }}
|
|
<span class="font-mono text-xs">{{ $config->list_name ?: $config->list_uid }}</span>
|
|
</p>
|
|
<form action="{{ route('admin.pages.mailwizz.destroy', $page) }}" method="post" class="mt-3"
|
|
onsubmit="return confirm(@js(__('Remove Mailwizz integration for this page? Subscribers will stay in the database but will no longer sync.')));">
|
|
@csrf
|
|
@method('DELETE')
|
|
<button type="submit" class="text-sm font-semibold text-red-700 underline hover:text-red-800">
|
|
{{ __('Remove integration') }}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="mb-6 flex flex-wrap gap-2 text-xs font-medium text-slate-500">
|
|
<span :class="step >= 1 ? 'text-indigo-600' : ''">1. {{ __('API key') }}</span>
|
|
<span aria-hidden="true">→</span>
|
|
<span :class="step >= 2 ? 'text-indigo-600' : ''">2. {{ __('List') }}</span>
|
|
<span aria-hidden="true">→</span>
|
|
<span :class="step >= 3 ? 'text-indigo-600' : ''">3. {{ __('Field mapping') }}</span>
|
|
<span aria-hidden="true">→</span>
|
|
<span :class="step >= 4 ? 'text-indigo-600' : ''">4. {{ __('Tag / source') }}</span>
|
|
</div>
|
|
|
|
<div class="rounded-xl border border-slate-200 bg-white p-6 shadow-sm sm:p-8">
|
|
<div x-show="errorMessage !== ''" x-cloak class="mb-6 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800" x-text="errorMessage"></div>
|
|
|
|
{{-- Step 1 --}}
|
|
<div x-show="step === 1" x-cloak class="space-y-4">
|
|
<p class="text-sm leading-relaxed text-slate-600">
|
|
{{ __('First, create a mailing list in Mailwizz with the required custom fields. Add a custom field of type Checkbox List with an option value you will use to track this pre-registration source.') }}
|
|
</p>
|
|
@if ($config !== null)
|
|
<p class="text-sm text-amber-800">
|
|
{{ __('Enter your API key and connect to load Mailwizz data (the same key as before is fine). If you clear the key field before saving, the previously stored key is kept.') }}
|
|
</p>
|
|
@endif
|
|
<div>
|
|
<label for="mailwizz_api_key" class="block text-sm font-medium text-slate-700">{{ __('Mailwizz API key') }}</label>
|
|
<input
|
|
id="mailwizz_api_key"
|
|
type="password"
|
|
autocomplete="off"
|
|
x-model="apiKey"
|
|
class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-slate-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
placeholder="{{ __('Paste API key') }}"
|
|
>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
class="rounded-lg bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 disabled:opacity-50"
|
|
:disabled="loading"
|
|
@click="connectLists()"
|
|
>
|
|
<span x-show="!loading">{{ __('Connect & load lists') }}</span>
|
|
<span x-show="loading" x-cloak>{{ __('Connecting…') }}</span>
|
|
</button>
|
|
</div>
|
|
|
|
{{-- Step 2 --}}
|
|
<div x-show="step === 2" x-cloak class="space-y-4">
|
|
<div>
|
|
<label for="mailwizz_list" class="block text-sm font-medium text-slate-700">{{ __('Mailing list') }}</label>
|
|
<select
|
|
id="mailwizz_list"
|
|
x-model="selectedListUid"
|
|
@change="syncListNameFromSelection()"
|
|
class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-slate-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
>
|
|
<option value="">{{ __('Select a list…') }}</option>
|
|
<template x-for="list in lists" :key="list.list_uid">
|
|
<option :value="list.list_uid" x-text="list.name"></option>
|
|
</template>
|
|
</select>
|
|
</div>
|
|
<div class="flex flex-wrap gap-3">
|
|
<button type="button" class="rounded-lg border border-slate-300 bg-white px-4 py-2.5 text-sm font-semibold text-slate-700 hover:bg-slate-50" @click="step = 1">
|
|
{{ __('Back') }}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="rounded-lg bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 disabled:opacity-50"
|
|
:disabled="loading"
|
|
@click="loadFieldsAndGoStep3()"
|
|
>
|
|
<span x-show="!loading">{{ __('Load fields') }}</span>
|
|
<span x-show="loading" x-cloak>{{ __('Loading…') }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Step 3 --}}
|
|
<div x-show="step === 3" x-cloak class="space-y-5">
|
|
<p class="text-sm text-slate-600">{{ __('Map each local field to the matching Mailwizz custom field (by tag).') }}</p>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-slate-700">{{ __('Email') }}</label>
|
|
<select x-model="fieldEmail" class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
|
<option value="">{{ __('Select field…') }}</option>
|
|
<template x-for="f in emailFieldChoices()" :key="f.tag">
|
|
<option :value="f.tag" x-text="f.label + ' (' + f.tag + ')'"></option>
|
|
</template>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-slate-700">{{ __('First name') }}</label>
|
|
<select x-model="fieldFirstName" class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
|
<option value="">{{ __('Select field…') }}</option>
|
|
<template x-for="f in textFields()" :key="'fn-' + f.tag">
|
|
<option :value="f.tag" x-text="f.label + ' (' + f.tag + ')'"></option>
|
|
</template>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-slate-700">{{ __('Last name') }}</label>
|
|
<select x-model="fieldLastName" class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
|
<option value="">{{ __('Select field…') }}</option>
|
|
<template x-for="f in textFields()" :key="'ln-' + f.tag">
|
|
<option :value="f.tag" x-text="f.label + ' (' + f.tag + ')'"></option>
|
|
</template>
|
|
</select>
|
|
</div>
|
|
<div x-show="phoneEnabled">
|
|
<label class="block text-sm font-medium text-slate-700">{{ __('Phone') }} <span class="font-normal text-slate-500">({{ __('optional') }})</span></label>
|
|
<select x-model="fieldPhone" class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
|
<option value="">{{ __('Select field…') }}</option>
|
|
<template x-for="f in phoneFields()" :key="'ph-' + f.tag">
|
|
<option :value="f.tag" x-text="f.label + ' (' + f.tag + ')'"></option>
|
|
</template>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-slate-700">{{ __('Tag / source (checkbox list)') }}</label>
|
|
<select
|
|
x-model="tagField"
|
|
@change="tagValue = ''"
|
|
class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
>
|
|
<option value="">{{ __('Select checkbox list field…') }}</option>
|
|
<template x-for="f in checkboxFields()" :key="'cb-' + f.tag">
|
|
<option :value="f.tag" x-text="f.label + ' (' + f.tag + ')'"></option>
|
|
</template>
|
|
</select>
|
|
</div>
|
|
<p x-show="checkboxFields().length === 0" class="text-sm text-amber-800">
|
|
{{ __('No checkbox list fields were returned for this list. Add one in Mailwizz, then run “Load fields” again from step 2.') }}
|
|
</p>
|
|
|
|
<div class="flex flex-wrap gap-3">
|
|
<button type="button" class="rounded-lg border border-slate-300 bg-white px-4 py-2.5 text-sm font-semibold text-slate-700 hover:bg-slate-50" @click="step = 2">
|
|
{{ __('Back') }}
|
|
</button>
|
|
<button type="button" class="rounded-lg bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500" @click="goStep4()">
|
|
{{ __('Continue') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Step 4 --}}
|
|
<div x-show="step === 4" x-cloak class="space-y-5">
|
|
<p class="text-sm text-slate-600">{{ __('Choose the checkbox option that marks subscribers from this pre-registration page.') }}</p>
|
|
|
|
<fieldset class="space-y-2">
|
|
<legend class="sr-only">{{ __('Tag value') }}</legend>
|
|
<template x-for="opt in tagOptionsList()" :key="opt.key">
|
|
<label class="flex cursor-pointer items-start gap-3 rounded-lg border border-slate-200 p-3 hover:bg-slate-50">
|
|
<input type="radio" name="tag_value_choice" class="mt-1 text-indigo-600" :value="opt.key" x-model="tagValue">
|
|
<span class="text-sm text-slate-800" x-text="opt.label"></span>
|
|
</label>
|
|
</template>
|
|
</fieldset>
|
|
<p x-show="tagField && tagOptionsList().length === 0" class="text-sm text-amber-800">
|
|
{{ __('This field has no options defined in Mailwizz. Add options to the checkbox list field, then reload fields.') }}
|
|
</p>
|
|
|
|
<form x-ref="saveForm" method="post" action="{{ route('admin.pages.mailwizz.update', $page) }}" class="space-y-4">
|
|
@csrf
|
|
@method('PUT')
|
|
<input type="hidden" name="api_key" x-bind:value="apiKey">
|
|
<input type="hidden" name="list_uid" x-bind:value="selectedListUid">
|
|
<input type="hidden" name="list_name" x-bind:value="selectedListName">
|
|
<input type="hidden" name="field_email" x-bind:value="fieldEmail">
|
|
<input type="hidden" name="field_first_name" x-bind:value="fieldFirstName">
|
|
<input type="hidden" name="field_last_name" x-bind:value="fieldLastName">
|
|
<input type="hidden" name="field_phone" x-bind:value="phoneEnabled ? fieldPhone : ''">
|
|
<input type="hidden" name="tag_field" x-bind:value="tagField">
|
|
<input type="hidden" name="tag_value" x-bind:value="tagValue">
|
|
|
|
<div class="flex flex-wrap gap-3">
|
|
<button type="button" class="rounded-lg border border-slate-300 bg-white px-4 py-2.5 text-sm font-semibold text-slate-700 hover:bg-slate-50" @click="step = 3">
|
|
{{ __('Back') }}
|
|
</button>
|
|
<button type="button" class="rounded-lg bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500" @click="submitSave()">
|
|
{{ __('Save configuration') }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|