Files
2026-03-19 18:42:19 +02:00

103 lines
5.6 KiB
PHP

<x-analytics-layout :website="$website" title="UTM Builder">
<div class="max-w-3xl" x-data="utmBuilder('{{ $website->domain }}')">
<div class="bg-white rounded-xl border border-gray-200 p-6 space-y-5">
<div>
<h3 class="text-base font-semibold text-gray-900">Campaign URL Builder</h3>
<p class="text-sm text-gray-500 mt-1">Generate URLs with UTM parameters to track your marketing campaigns.</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Website URL <span class="text-red-500">*</span></label>
<input type="url" x-model="url" required placeholder="https://{{ $website->domain }}/landing-page"
class="block w-full rounded-lg border-gray-300 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Campaign Source <span class="text-red-500">*</span></label>
<input type="text" x-model="source" required placeholder="e.g. google, newsletter, facebook"
class="block w-full rounded-lg border-gray-300 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
<p class="text-xs text-gray-400 mt-1">Where the traffic originates</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Campaign Medium <span class="text-red-500">*</span></label>
<input type="text" x-model="medium" required placeholder="e.g. cpc, email, social"
class="block w-full rounded-lg border-gray-300 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
<p class="text-xs text-gray-400 mt-1">Marketing medium type</p>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Campaign Name <span class="text-red-500">*</span></label>
<input type="text" x-model="campaign" required placeholder="e.g. spring_sale, product_launch"
class="block w-full rounded-lg border-gray-300 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Campaign Term <span class="text-gray-400 font-normal">(optional)</span></label>
<input type="text" x-model="term" placeholder="e.g. running+shoes"
class="block w-full rounded-lg border-gray-300 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
<p class="text-xs text-gray-400 mt-1">Paid search keywords</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Campaign Content <span class="text-gray-400 font-normal">(optional)</span></label>
<input type="text" x-model="content" placeholder="e.g. logolink, textlink"
class="block w-full rounded-lg border-gray-300 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
<p class="text-xs text-gray-400 mt-1">Differentiate ads or links</p>
</div>
</div>
</div>
{{-- Generated URL --}}
<div class="mt-6 bg-white rounded-xl border border-gray-200 p-6" x-show="generatedUrl" x-cloak>
<h3 class="text-sm font-semibold text-gray-900 mb-2">Generated URL</h3>
<div class="flex items-center gap-2">
<code class="flex-1 block text-sm bg-gray-50 rounded-lg border border-gray-200 px-3 py-2.5 font-mono text-gray-800 break-all select-all" x-text="generatedUrl" id="generated-url"></code>
<button
@click="copyUrl()"
class="shrink-0 inline-flex items-center gap-1 rounded-lg bg-indigo-600 px-3 py-2.5 text-sm font-medium text-white hover:bg-indigo-500 transition"
>
<span x-show="!copied">Copy</span>
<span x-show="copied" x-cloak>Copied!</span>
</button>
</div>
</div>
</div>
<script>
function utmBuilder(domain) {
return {
url: '',
source: '',
medium: '',
campaign: '',
term: '',
content: '',
copied: false,
get generatedUrl() {
if (!this.url || !this.source || !this.medium || !this.campaign) return '';
try {
const u = new URL(this.url);
u.searchParams.set('utm_source', this.source);
u.searchParams.set('utm_medium', this.medium);
u.searchParams.set('utm_campaign', this.campaign);
if (this.term) u.searchParams.set('utm_term', this.term);
if (this.content) u.searchParams.set('utm_content', this.content);
return u.toString();
} catch {
return '';
}
},
copyUrl() {
navigator.clipboard.writeText(this.generatedUrl);
this.copied = true;
setTimeout(() => this.copied = false, 2000);
}
};
}
</script>
</x-analytics-layout>