PageSourceSearch

https://www.hofladenfinder.org/js/components/details-edit/location-form.js

js hofladenfinder.org collected 2026-10-09 04:38:57 UTC 32,300 bytes, 532 lines download raw bytes

1import { } from "./week-day-editor.js"
2import { } from "./product-picker.js"
3import { } from "./feature-picker.js"
4import { } from "./base-information.js";
5import { } from "./../common/spinner.js";
6import { } from "./../common/error-message.js";
7import { Utils } from "./../../helper/utils.js";
8
9export class LocationForm extends HTMLElement {
10
11    connectedCallback() {
12        this.render();
13    }
14
15    render() {
16        this.innerHTML = /* html */`
17
18        <section id="pricing" aria-labelledby="premium-heading" class="bg-green-50 py-8 sm:py-24">
19            <div class="mx-auto grid max-w-7xl items-start gap-8 px-6 lg:grid-cols-2 lg:px-8">
20
21                <div class="max-w-xl lg:pt-8">
22                    <h2 id="premium-heading" class="mt-2 text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl">
23                        Mehr Kunden für<br>deinen Hofladen
24                    </h2>
25
26                    <p class="mt-6 text-lg leading-8 text-gray-600">
27                        Über 80.000 Menschen suchen jeden Monat auf HofladenFinder
28                        nach frischen Produkten in ihrer Region. Mach sie auf deinen
29                        Hofladen und dein Angebot aufmerksam.
30                    </p>
31
32                    <button id="newest-entries" type="button" class="mt-6 inline-flex cursor-pointer items-center gap-2 rounded-xl border border-green-700 px-5 py-3 text-base font-semibold text-green-700 transition-colors hover:bg-green-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-700">
33                        Neueste Hofläden ansehen
34                    </button>
35                </div>
36
37                <div id="premium-card" class="flex h-full w-full max-w-lg justify-self-center overflow-hidden rounded-3xl border border-green-900/10 bg-white shadow-xl">
38                    <div class="flex w-full flex-col p-8 sm:p-10">
39                        <h3 id="tier-team" class="text-xl font-semibold text-green-700">
40                            Premium
41                        </h3>
42
43                        <p class="mt-2 text-sm leading-6 text-gray-600">
44                            Mehr Sichtbarkeit für deinen Hofladen.
45                        </p>
46
47                        <div class="mt-6 rounded-2xl bg-green-50 p-6">
48                            <div class="flex flex-wrap items-baseline gap-2">
49                                <span id="monthly-rate" class="text-5xl font-semibold tracking-tight text-gray-900">19 EUR</span>
50                                <span class="text-base font-medium text-gray-600">/ Monat</span>
51                            </div>
52
53                            <p id="yearly-rate" class="mt-3 text-sm leading-6 text-gray-600">
54                                Monatlich kündbar
55                            </p>
56                        </div>
57
58                        <p class="mt-8 text-sm font-semibold text-gray-900">
59                            Deine Vorteile
60                        </p>
61
62                        <ul role="list" class="mt-5 space-y-5 text-sm leading-6 text-gray-700">
63                            <li class="flex items-start gap-3">
64                                <span aria-hidden="true" class="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-green-100 font-bold text-green-700">✓</span>
65                                <span>Vollwertiger Hofladen-Eintrag</span>
66                            </li>
67
68                            <li class="flex items-start gap-3">
69                                <span aria-hidden="true" class="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-green-100 font-bold text-green-700">✓</span>
70                                <span>Top-Platzierung im Umkreis von 20&nbsp;km</span>
71                            </li>
72
73                            <li class="flex items-start gap-3">
74                                <span aria-hidden="true" class="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-green-100 font-bold text-green-700">✓</span>
75                                <span>Hervorgehoben in der Suche</span>
76                            </li>
77
78                            <li class="flex items-start gap-3">
79                                <span aria-hidden="true" class="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-green-100 font-bold text-green-700">✓</span>
80                                <span>Für Google optimiert</span>
81                            </li>
82                        </ul>
83
84                        <div class="mt-auto pt-8">
85                            <button id="next-1-button" type="button" aria-describedby="tier-team yearly-rate" class="flex w-full cursor-pointer items-center justify-center gap-2 rounded-xl bg-green-700 px-5 py-3 text-base font-semibold text-white shadow-sm transition-colors hover:bg-green-800 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-700 disabled:cursor-wait disabled:opacity-70">
86                                <span>Weiter</span>
87                            </button>
88                        </div>
89                    </div>
90                </div>
91            </div>
92
93            <div class="mx-auto mt-24 max-w-7xl px-6 lg:mt-48 lg:px-8">
94                <div class="mx-auto max-w-3xl">
95                    <h2 class="mb-8 text-2xl font-semibold tracking-tight text-gray-900 sm:text-3xl">
96                        Häufige Fragen
97                    </h2>
98
99                    <div class="space-y-3">
100                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
101                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
102                                Für wen ist ein Premium-Eintrag sinnvoll?
103                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
104                            </summary>
105                            <p class="px-6 pb-6 leading-7 text-gray-600">
106                                Für Betriebe, die mehr Kunden in ihrer Region gewinnen möchten. Durch einen Premium-Eintrag wird dein Betrieb im Umkreis von 20&nbsp;km beworben. Das heißt, er taucht in der Suche weit oben auf. Da auf HofladenFinder viele Menschen mit Interesse an hochwertigen Lebensmitteln unterwegs sind, ist die Werbung hier besonders effektiv.
107                            </p>
108                        </details>
109
110                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
111                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
112                                Bekomme ich in jedem Fall mehr Kunden?
113                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
114                            </summary>
115                            <p class="px-6 pb-6 leading-7 text-gray-600">
116                                Ein Eintrag kann helfen, neue Kunden auf deinen Hofladen aufmerksam zu machen. Bei 80.000 Nutzern monatlich ist das sogar sehr wahrscheinlich, eine bestimmte Zahl an Besuchen oder Einkäufen lässt sich aber nicht versprechen.
117                            </p>
118                        </details>
119
120                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
121                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
122                                Ich habe bereits eine Website!
123                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
124                            </summary>
125                            <p class="px-6 pb-6 leading-7 text-gray-600">
126                                Als reichweitenstarkes Portal kann dir HofladenFinder Menschen vermitteln, die sonst nicht auf deinen Betrieb aufmerksam geworden wären.
127                            </p>
128                        </details>
129
130                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
131                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
132                                Ich bin bereits auf Google-Maps!
133                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
134                            </summary>
135                            <p class="px-6 pb-6 leading-7 text-gray-600">
136                                Dann bist du zwar auffindbar, die meisten Betriebe erhalten dadurch allerdings nicht sehr viel mehr Sichtbarkeit. Durch HofladenFinder erhalten viele Betriebe monatlich mehrere hundert Aufrufe von Menschen aus ihrer Region.
137                            </p>
138                        </details>
139
140                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
141                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
142                                Das ist mir zu teuer!
143                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
144                            </summary>
145                            <p class="px-6 pb-6 leading-7 text-gray-600">
146                                So teuer ist es gar nicht. Genau genommen ist es sogar günstig. Auf Werbeplattformen wie Google oder Facebook kostet ein einzelner Aufruf schnell mehr als 1 EUR im Bereich gesunde Lebensmittel. Erhält ein Eintrag auf HofladenFinder monatlich 100 Aufrufe, sind das lediglich 19 cent je Aufruf. Bei 200 Aufrufen bereits unter 10 cent je Aufruf.
147                            </p>
148                        </details>
149
150                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
151                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
152                                Kann ich den Premium-Eintrag für nur einen Monat buchen?                                
153                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
154                            </summary>
155                            <p class="px-6 pb-6 leading-7 text-gray-600">
156                                Ja. Ein Premium-Eintrag ist grundsätzlich monatlich kündbar. Wir empfehlen allerdings, einen Premium-Eintrag mehr als einen Monat zu nutzen, da nach der Erstellung Suchmaschinen wie Google einige Zeit brauchen, die neue Seite zu entdecken.
157                            </p>
158                        </details>
159
160                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
161                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
162                                Was passiert bei einer Kündigung?                                
163                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
164                            </summary>
165                            <p class="px-6 pb-6 leading-7 text-gray-600">
166                                Dein Hofladen wird als Basis-Eintrag weitergeführt. Das heißt, die Informationen deines Eintrags bleiben erhalten und sind weiterhin auffindbar, der Werbe-Effekt bleibt allerdings aus.
167                            </p>
168                        </details>
169
170                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
171                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
172                                Was sollte ich über meinen Hofladen erzählen?
173                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
174                            </summary>
175                            <p class="px-6 pb-6 leading-7 text-gray-600">
176                                Am besten das, was du einem neuen Kunden auch vor Ort erzählen würdest. Was gibt es bei dir? Was produzierst du selbst? Wann lohnt sich ein Besuch besonders? Dazu gehören praktische Angaben wie Öffnungszeiten und Anfahrt. Wenn dein Laden etwas versteckt liegt, ist ein kurzer Hinweis oft hilfreicher als ein langer Werbetext.
177                            </p>
178                        </details>
179
180                        <details class="group rounded-2xl border border-green-900/10 bg-white shadow-sm">
181                            <summary class="flex cursor-pointer list-none items-center justify-between gap-4 p-6 font-semibold text-gray-900 [&::-webkit-details-marker]:hidden">
182                                Muss ich dafür einen perfekten Werbetext schreiben?
183                                <span aria-hidden="true" class="shrink-0 text-2xl font-light text-green-700 transition-transform group-open:rotate-45">+</span>
184                            </summary>
185                            <p class="px-6 pb-6 leading-7 text-gray-600">
186                                Nein. Beschreibe deinen Hofladen so, wie er ist. Ob eigene Kartoffeln, frische Eier oder selbst gemachte Konfitüre. Besucher möchten wissen, was sie bei dir bekommen.
187                            </p>
188                        </details>
189                    </div>
190                </div>
191            </div>
192        </section>
193
194        <form hidden class="max-w-2xl mx-auto mb-16 mt-6 relative">
195            <div class="bg-white rounded-4xl shadow-xl shadow-stone-200/50 border border-stone-200 overflow-hidden">
196                <div id="location-header" class="px-8 py-8 bg-white border-b border-stone-100 flex justify-between items-center">
197                    <div>
198                        <h1 id="header" class="text-2xl font-extrabold text-stone-900 tracking-tight"></h1>
199                        <p id="sub-header" class="text-stone-500 text-sm mt-1"></p>
200                    </div>
201                    <div class="text-emerald-600 bg-emerald-100 w-12 h-12 rounded-2xl flex items-center justify-center border-2 border-emerald-100">
202                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
203                                stroke="currentColor" class="w-7 h-7">
204                            <path stroke-linecap="round" stroke-linejoin="round"
205                                    d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
206                            <path stroke-linecap="round" stroke-linejoin="round"
207                                    d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z" />
208                        </svg>
209                    </div>
210                </div>
211
212                <div id="location-content" class="p-8">
213                    <wc-base-information></wc-base-information>
214
215                    <h2 class="text-xs font-black text-stone-700 uppercase tracking-widest ml-1 border-b border-stone-100 pb-2">
216                        Öffnungszeiten
217                    </h2>
218                    <wc-week-day-editor></wc-week-day-editor>
219
220                    <div class="space-y-4 pt-2">
221                        <h3 class="text-xs font-black text-stone-700 uppercase tracking-widest ml-1 border-b border-stone-100 pb-2">
222                            Verkauf
223                        </h3>
224                        <wc-product-picker></wc-product-picker>
225                    </div>
226
227                    <div class="space-y-3 pt-2">
228                        <h3 class="text-xs font-black text-stone-700 uppercase tracking-widest ml-1 border-b border-stone-100 pb-2">
229                            Ausstattung
230                        </h3>
231                        <wc-feature-picker></wc-feature-picker>
232                    </div>
233
234                    <div hidden id="upgrade-option" class="py-2 pb-8">
235                        <div id="premium-options" class="space-y-3">
236                            <h3 class="ml-1 border-b border-stone-100 pb-2 text-xs font-black uppercase tracking-widest text-stone-700">
237                                Eintrag hervorheben?
238                            </h3>
239
240                            <div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
241                                <button id="premium-button" type="button" class="group flex h-full items-start gap-4 roun
241ded-2xl border border-stone-200 bg-stone-50/30 p-4 text-left transition-colors hover:border-emerald-500 hover:bg-emerald-50/30 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-emerald-500/20">
242                                    <span class="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-amber-50">
243                                        <svg viewBox="0 0 64 64" fill="none" aria-hidden="true" class="h-8 w-8">
244                                            <path d="M30 5 37.5 21 55 23.5 42.5 36 45.5 53.5 30 45 14.5 53.5 17.5 36 5 23.5 22.5 21Z" fill="#FBBF24" stroke="#D97706" stroke-width="2" stroke-linejoin="round"/>
245                                            <circle cx="48" cy="47" r="14" fill="#047857" />
246                                            <path d="M48 40v14M41 47h14" stroke="white" stroke-width="4" stroke-linecap="round"/>
247                                        </svg>
248                                    </span>
249
250                                    <span class="flex min-w-0 flex-1 flex-col">
251                                        <span class="text-sm font-semibold text-stone-900">
252                                            Premium-Eintrag
253                                        </span>
254                                        <span class="mt-1 text-xs leading-relaxed text-stone-500">
255                                            Dein Eintrag wird im Umkreis von 20&nbsp;km auf einem der ersten beiden Plätze angezeigt. (19 EUR/Monat)
256                                        </span>
257                                    </span>
258                                </button>
259
260                                <button id="non-premium-button" type="button" class="group flex h-full items-start gap-4 roun
260ded-2xl border border-stone-200 bg-stone-50/30 p-4 text-left transition-colors hover:border-emerald-500 hover:bg-emerald-50/30 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-emerald-500/20">
261                                    <span class="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-stone-100">
262                                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="h-6 w-6 text-stone-500">
263                                            <rect x="5" y="3" width="14" height="18" rx="2" />
264                                            <path d="M9 8h6M9 12h6M9 16h4" />
265                                        </svg>
266                                    </span>
267
268                                    <span class="flex min-w-0 flex-1 flex-col">
269                                        <span class="text-sm font-semibold text-stone-900">
270                                            Kein Premium-Eintrag
271                                        </span>
272                                        <span class="mt-1 text-xs leading-relaxed text-stone-500">
273                                            Dein Eintrag wird nicht im Umkreis von 20&nbsp;km beworben.
274                                        </span>
275                                    </span>
276                                </button>
277                            </div>
278                        </div>
279                    </div>
280
281                    <div class="py-2">
282                        <div class="space-y-3">
283                            <h3 class="text-xs font-black text-stone-700 uppercase tracking-widest ml-1 border-b border-stone-100 pb-2">
284                                    Bist du der Hofladenbetreiber?
285                            </h3>
286                            <div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
287                                <label class="relative flex cursor-pointer rounded-2xl border border-stone-200 bg-stone-50/30 p-4 transition-all hover:bg-white has-checked:border-emerald-500 has-checked:bg-emerald-50/20 has-checked:ring-4 has-checked:ring-emerald-500/10">
288                                    <input id="owner" type="radio" name="is-owner" value="true" class="accent-emerald-600 mt-0.5 h-4 w-4 border-stone-300 text-emerald-600 focus:ring-emerald-500">
289                                    <span class="ml-3 flex flex-col">
290                                        <span class="block text-sm font-semibold text-stone-900">Ja, ich bin der Betreiber</span>
291                                        <span class="mt-1 text-xs text-stone-500">Ich verwalte diesen Eintrag selbst.</span>
292                                    </span>
293                                </label>
294
295                                <label class="relative flex cursor-pointer rounded-2xl border border-stone-200 bg-stone-50/30 p-4 transition-all hover:bg-white has-checked:border-emerald-500 has-checked:bg-emerald-50/20 has-checked:ring-4 has-checked:ring-emerald-500/10">
296                                    <input id="no-owner" type="radio" name="is-owner" value="false" class="accent-emerald-600 mt-0.5 h-4 w-4 border-stone-300 text-emerald-600 focus:ring-emerald-500">
297                                    <span class="ml-3 flex flex-col">
298                                        <span class="block text-sm font-semibold text-stone-900">Nein, Kunde / Tippgeber</span>
299                                        <span class="mt-1 text-xs text-stone-500">Ich kenne diesen Laden und empfehle ihn.</span>
300                                    </span>
301                                </label>
302                            </div>
303                        </div>
304                        <div id="email-container" hidden class="pt-4">
305                            <p class="text-xs font-black text-stone-700 uppercase tracking-widest ml-1 mb-1">
306                                E-Mail
307                            </p>
308                            <input id="email" autocomplete="email" type="email" class="w-full placeholder:text-stone-400 px-4 py-3.5 rounded-xl border border-stone-200 focus:outline-none focus:ring-4 focus:ring-emerald-500/10 focus:border-emerald-500 transition-all bg-stone-50/30">
309                        </div>
310                    </div>
311
312                    <wc-error-message></wc-error-message>
313
314                    <div class="sm:text-right mt-14">
315                        <button type="button" id="next-2-button" class="cursor-pointer w-full sm:w-62 inline-flex justify-center px-4 py-3 font-semibold leading-6 text-sm shadow rounded-md text-white bg-orange-500 hover:bg-orange-600 transition ease-in-out duration-150">
316                            <wc-spinner color="text-white" hidden></wc-spinner>
317                            <div>{button}</div>
318                        </button>
319                    </div>
320                </div>
321            </div>
322        </form>
323        `;
324
325        this.baseInformation = this.querySelector("wc-base-information");
326        this.weekDayEditor = this.querySelector("wc-week-day-editor");
327        this.productPicker = this.querySelector("wc-product-picker");
328        this.featurePicker = this.querySelector("wc-feature-picker");
329        this.spinner = this.querySelector("wc-spinner");
330        this.errorMessage = this.querySelector("wc-error-message");
331        this.locationContent = this.querySelector("#location-content");
332        this.locationHeader = this.querySelector("#location-header");
333        this.owner = this.querySelector("#owner");
334        this.noOwner = this.querySelector("#no-owner");
335        this.email = this.querySelector("#email");
336        this.emailContainer = this.querySelector("#email-container");
337        this.next1Button = this.querySelector("#next-1-button");
338        this.next2Button = this.querySelector("#next-2-button");
339        this.pricing = this.querySelector("#pricing");
340        this.form = this.querySelector("form");
341        this.monthlyRate = this.querySelector("#monthly-rate");
342        this.yearlyRate = this.querySelector("#yearly-rate");
343        this.newestEntries = this.querySelector("#newest-entries");
344        this.upgradeOption = this.querySelector("#upgrade-option");
345        this.premiumButton = this.querySelector("#premium-button");
346        this.nonPremiumButton = this.querySelector("#non-premium-button");
347
348        this.newestEntries.addEventListener("click", () => {
349            this.dispatchEvent(new CustomEvent("newest_entries_clicked", { bubbles: true, composed: true }));
350        });
351
352        this.owner.addEventListener("change", () => {
353            this.emailContainer.hidden = false;
354        });
355
356        this.noOwner.addEventListener("change", () => {
357            this.emailContainer.hidden = true;
358            this.email.value = "";
359        });
360
361        this.next1Button.addEventListener("click", () => {
362            this.pricing.hidden = true;
363            this.form.hidden = false;
364            window.scrollTo({ top: 0, behavior: 'instant' });
365        });
366
367        this.next2Button.addEventListener("click", () => {
368            if (!this.isValid()) {
369                this.showError();
370
371                return;
372            }
373
374            if (!window.location.pathname.startsWith("/edit") || this.premiumButton.classList.contains("ring-4"))
375                this.dispatchEvent(new CustomEvent("premium_selected", { bubbles: true, composed: true }));
376            else
377                this.dispatchEvent(new CustomEvent("free_selected", { bubbles: true, composed: true }));
378        });
379
380        const premiumOptionButtons = document.querySelectorAll('#premium-options button');
381
382        premiumOptionButtons.forEach(button => {
383            button.addEventListener('click', () => {
384                premiumOptionButtons.forEach(option => {
385                    const selected = option === button;
386
387                    option.classList.toggle('ring-4', selected);
388                    option.classList.toggle('ring-emerald-500/20', selected);
389                    option.classList.toggle('border-emerald-500', selected);
390                    option.classList.toggle('bg-emerald-50/30', selected);
391                    option.classList.toggle('border-stone-200', !selected);
392                    option.classList.toggle('bg-stone-50/30', !selected);
393                });
394            });
395        });
396    }
397
398    set(label, subLabel, buttonText) {
399        this.querySelector("#header").textContent = label;
400        this.querySelector("#sub-header").textContent = subLabel;
401
402        if (buttonText != null)
403            this.next2Button.textContent = buttonText;
404    }
405
406    isValid() {
407        return this.baseInformation.isValid();
408    }
409
410    showError() {
411        const missingFields = this.baseInformation.getMissingFields();
412
413        this.errorMessage.setText(`Hoppla! Da fehlen noch ein paar Infos: ${missingFields}`);
414    }
415
416    getData() {
417        const baseInformation = this.baseInformation.getData();
418        const openingHours = this.weekDayEditor.getData();
419        const productCategories = this.productPicker.getData();
420        const features = this.featurePicker.getData();
421
422        return {
423            Name: baseInformation.Name.trim(),
424            ShopType: baseInformation.ShopType,
425            Description: baseInformation.Description.trim(),
426            Website: baseInformation.Website.trim(),
427            Phone1: baseInformation.Phone1.trim(),
428            Street: baseInformation.Street.trim(),
429            ZipCode: baseInformation.ZipCode.trim(),
430            Place: baseInformation.Place.trim(),
431            Country: baseInformation.Country,
432            Latitude: baseInformation.Latitude,
433            Longitude: baseInformation.Longitude,
434            OpeningHours: openingHours,
435            ProductCategories: productCategories,
436            Features: features,
437            Email: this.email.value.trim()
438        }
439    }
440
441    setData(location) {
442        this.reset();
443
444        this.baseInformation.setData(location);
445        this.weekDayEditor.setData(location.OpeningHours);
446        this.productPicker.setData(location.ProductCategories);
447        this.featurePicker.setData(location.Features);
448
449        if (!window.location.pathname.startsWith("/edit") && !location.IsPremium)
450            this.upgradeOption.hidden = false;
451    }
452
453    reset() {
454        this.baseInformation.reset();
455        this.weekDayEditor.reset();
456        this.productPicker.reset();
457        this.featurePicker.reset();
458        this.errorMessage.reset();
459
460        this.premiumButton.className = "group flex h-full items-start gap-4 roun
460ded-2xl border border-stone-200 bg-stone-50/30 p-4 text-left transition-colors hover:border-emerald-500 hover:bg-emerald-50/30 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-emerald-500/20";
461        this.nonPremiumButton.className = "group flex h-full items-start gap-4 rounded-2xl border border-stone-200 bg-stone-50/30 p-4 text-left transition-colors hover:border-emerald-500 hover:bg-emerald-50/30 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-emerald-500/20";
462    }
463
464    show() {
465        this.pricing.hidden = false;
466        this.form.hidden = true;
467        this.spinner.hidden = true;
468    }
469
470    showForm() {
471        this.pricing.hidden = true;
472        this.form.hidden = false;
473        this.spinner.hidden = true;
474    }
475
476    showPremiumOptions() {
477        this.hideSpinner();
478        this.locationContent.hidden = true;
479        this.show(this.baseInformation.getData().Country);
480
481        this.set("Neuer Standort");
482    }
483
484    showSpinner() {
485        this.next2Button.classList.add("opacity-50");
486        this.next2Button.disabled = true;
487        this.spinner.hidden = false;
488    }
489
490    hideSpinner() {
491        this.next2Button.classList.remove("opacity-50");
492        this.next2Button.disabled = false;
493        this.spinner.hidden = true;
494    }
495
496    setCurrency(country) {
497        this.hidden = false;
498
499        if (country == "CH") {
500            this.monthlyRate.textContent = "19 CHF";
501            this.yearlyRate.textContent = "Monatlich kündbar";
502        }
503        else {
504            this.monthlyRate.textContent = "19 EUR";
505            this.yearlyRate.textContent = "Monatlich kündbar";
506        }
507    }
508
509    hide() {
510        this.hidden = true;
511    }
512
513    getPaymentLink(clientReferenceId, country) {
514        const links = {
515            production: {
516                "Schweiz": "https://buy.stripe.com/3cIcN48k65r277s9Zq1440b",
517                "EU": "https://buy.stripe.com/6oU5kC2ZM5r2ajE8Vm1440a"
518            },
519            sandbox: {
520                "Schweiz": "https://buy.stripe.com/test_8x200idEqf1C1N8gnO14405",
521                "EU": "https://buy.stripe.com/test_eVqeVcfMy8DedvQ0oQ1440d"
522            }
523        };
524
525        const env = Utils.isProduction() ? "production" : "sandbox";
526        const paymentLink = links[env][country] || links[env]["EU"];
527
528        return `${paymentLink}?client_reference_id=${clientReferenceId}&locale=de`;
529    }
530}
531
532customElements.define("wc-location-form", LocationForm);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.