This is a custom code placeholder.
Switch to Preview or publish the page
to see how your code works.
Double-click to edit
<!-- Softinet – Formularz: Konferencja IT&SEC Camp 2026 (Worker JSON) -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<div id="softinet-form-wrapper">
<style>
#softinet-form-wrapper { font-family:'Poppins',system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif; color:#111; }
#softinet-form { max-width:720px; margin:0 auto; padding:0 8px; }
.field { display:flex; flex-direction:column; gap:6px; margin:14px 0; }
label { font-size:14px; line-height:1.3; color:#111; }
.req { color:#d11; margin-left:4px; }
input[type="text"], input[type="email"], input[type="tel"]{
border:1px solid #d7d7d7; border-radius:10px; padding:12px 12px;
font-size:15px; outline:none; background:#fff;
}
input[type="text"]:focus, input[type="email"]:focus, input[type="tel"]:focus{
border-color:#048fcc; box-shadow:0 0 0 3px rgba(4,143,204,.12);
}
.radio-group, .checkbox-group { display:flex; flex-direction:column; gap:8px; }
.option { display:flex; align-items:flex-start; gap:10px; font-size:14px; color:#111; }
.option input { margin-top:2px; }
.note { font-size:12.5px; color:#b00020; line-height:1.35; margin-top:8px; }
.info { font-size:12.5px; color:#6b6b6b; line-height:1.35; margin-top:8px; }
.error { display:none; font-size:12.5px; color:#b00020; margin-top:6px; }
.show-error { display:block; }
.actions { display:flex; justify-content:center; margin:22px 0 10px; }
.btn {
background:#6f8791; color:#fff; border:none; border-radius:999px;
padding:14px 26px; font-size:15px; font-weight:600; cursor:pointer;
min-width:260px;
}
.btn:disabled { opacity:.6; cursor:not-allowed; }
.phone-row { display:grid; grid-template-columns:110px 1fr; gap:10px; align-items:center; }
.phone-prefix {
border:1px solid #d7d7d7; border-radius:10px; padding:12px 12px; background:#fff;
font-size:15px; display:flex; align-items:center; justify-content:center;
}
.hp { position:absolute; left:-9999px; top:auto; width:1px; height:1px; overflow:hidden; }
.spacer { margin:18px 0; }
.checkbox-left{
display:flex;
align-items:flex-start;
gap:10px;
font-size:14px;
line-height:1.4;
}
.checkbox-left input{
margin-top:3px;
}
.checkbox-left label{
font-weight:400;
}
/* Linki w treści formularza */
#softinet-form-wrapper a {
color:#111;
text-decoration:none;
transition:text-decoration .2s ease, color .2s ease;
}
#softinet-form-wrapper a:hover {
text-decoration:underline;
}
/* Nowocześniejsze checkboxy i radio */
#softinet-form-wrapper input[type="checkbox"],
#softinet-form-wrapper input[type="radio"]{
appearance:none;
-webkit-appearance:none;
width:18px;
height:18px;
min-width:18px;
border:1.5px solid #8f9aa3;
background:#fff;
margin:0;
position:relative;
cursor:pointer;
transition:all .2s ease;
}
#softinet-form-wrapper input[type="checkbox"]{
border-radius:4px;
}
#softinet-form-wrapper input[type="radio"]{
border-radius:50%;
}
#softinet-form-wrapper input[type="checkbox"]:hover,
#softinet-form-wrapper input[type="radio"]:hover{
border-color:#048fcc;
box-shadow:0 0 0 3px rgba(4,143,204,.10);
}
#softinet-form-wrapper input[type="checkbox"]:checked,
#softinet-form-wrapper input[type="radio"]:checked{
border-color:#048fcc;
background:#048fcc;
}
#softinet-form-wrapper input[type="checkbox"]:checked::after{
content:"";
position:absolute;
left:5px;
top:1px;
width:4px;
height:9px;
border:solid #fff;
border-width:0 2px 2px 0;
transform:rotate(45deg);
}
#softinet-form-wrapper input[type="radio"]:checked::after{
content:"";
position:absolute;
left:4px;
top:4px;
width:8px;
height:8px;
border-radius:50%;
background:#fff;
}
#softinet-form-wrapper input[type="checkbox"]:focus,
#softinet-form-wrapper input[type="radio"]:focus{
outline:none;
box-shadow:0 0 0 3px rgba(4,143,204,.18);
}
/* Checkbox zgody regulaminowej – wyrównanie do lewej */
.checkbox-left{
display:flex;
align-items:flex-start;
gap:10px;
font-size:14px;
line-height:1.4;
}
.checkbox-left input{
margin-top:3px;
}
.checkbox-left label{
font-weight:400;
}
/* Lepsze wyrównanie zwykłych opcji */
.option{
display:flex;
align-items:flex-start;
gap:10px;
font-size:14px;
color:#111;
line-height:1.4;
}
.option input{
margin-top:2px;
}
</style>
<form id="softinet-form" novalidate method="post">
<!-- Honeypot -->
<div class="hp">
<label>Website</label>
<input type="text" name="website" autocomplete="off" tabindex="-1">
</div>
<!-- Dane podstawowe -->
<div class="field">
<label for="first_name">Imię<span class="req">*</span></label>
<input id="first_name" name="first_name" type="text" required>
<div class="error" id="err_first_name">Uzupełnij imię.</div>
</div>
<div class="field">
<label for="last_name">Nazwisko<span class="req">*</span></label>
<input id="last_name" name="last_name" type="text" required>
<div class="error" id="err_last_name">Uzupełnij nazwisko.</div>
</div>
<div class="field">
<label for="company">Firma<span class="req">*</span></label>
<input id="company" name="company" type="text" required>
<div class="error" id="err_company">Uzupełnij firmę.</div>
</div>
<div class="field">
<label for="job_title">Stanowisko<span class="req">*</span></label>
<input id="job_title" name="job_title" type="text" required>
<div class="error" id="err_job_title">Uzupełnij stanowisko.</div>
</div>
<div class="field">
<label for="email">Służbowy adres e-mail<span class="req">*</span></label>
<input id="email" name="email" type="email" required>
<div class="error" id="err_email">Podaj poprawny adres e-mail.</div>
</div>
<div class="field">
<label for="phone">Numer telefonu<span class="req">*</span></label>
<div class="phone-row">
<div class="phone-prefix">🇵🇱 +48</div>
<input id="phone" name="phone" type="tel" inputmode="tel" placeholder="np. 501 234 567" required>
</div>
<div class="error" id="err_phone">Podaj poprawny numer telefonu.</div>
</div>
<div class="spacer"></div>
<!-- Transport -->
<div class="field">
<label>Skorzystam z transportu do/z miejsca konferencyjnego (zapewniony przez organizatora wydarzenia)</label>
<div class="radio-group" role="radiogroup" aria-label="Transport">
<label class="option"><input type="radio" name="transport" value="yes"> Tak</label>
<label class="option"><input type="radio" name="transport" value="no"> Nie</label>
</div>
</div>
<!-- Nocleg -->
<div class="field">
<label>Skorzystam z noclegu w dniu 12/13 maja 2026 (pokój dwuosobowy ze śniadaniem)</label>
<div class="radio-group" role="radiogroup" aria-label="Nocleg">
<label class="option"><input type="radio" name="accommodation" value="yes"> Tak</label>
<label class="option"><input type="radio" name="accommodation" value="no"> Nie</label>
</div>
</div>
<!-- Warsztaty (NA RAZIE WYŁĄCZONE) -->
<!--
<div class="field">
<label>Chcę wziąć udział w warsztacie:</label>
<div class="checkbox-group">
<label class="option"><input type="checkbox" name="workshops" value="CrowdStrike"> CrowdStrike</label>
<label class="option"><input type="checkbox" name="workshops" value="Fortinet"> Fortinet</label>
<label class="option"><input type="checkbox" name="workshops" value="Greycortex"> Greycortex</label>
<label class="option"><input type="checkbox" name="workshops" value="Huawei"> Huawei</label>
<label class="option"><input type="checkbox" name="workshops" value="Check Point"> Check Point</label>
</div>
<div class="note">
Uwaga: warsztaty będą odbywały się po sobie. Twoja deklaracja jest dla nas ważna ze względu na odpowiednie przygotowanie przestrzeni warsztatowej. Możesz wziąć udział w każdym z warsztatów.
</div>
</div>
-->
<div class="spacer"></div>
<!-- Zgody marketingowe – wymagany min. 1 kanał -->
<div class="field">
<label style="font-weight:600;">
Chcę otrzymywać od Softinet Sp. z o.o. z siedzibą w Warszawie informacje o ofercie, nowościach i promocjach dotyczących tej spółki oraz I Know IT Szymański Bojar sp. k. z siedzibą w Warszawie:
</label>
<div class="checkbox-group" style="margin-top:8px;">
<label class="option">
<input type="checkbox" id="consent_email_marketing">
Emailem
</label>
<label class="option">
<input type="checkbox" id="consent_phone_marketing">
Telefonicznie
</label>
</div>
<div class="error" id="err_channels">
Zaznacz przynajmniej jeden kanał kontaktu: e-mail lub telefon.
</div>
</div>
<!-- Informacja – bez checkboxa -->
<div class="field">
<div class="info">
Wypełniając formularz zgadzasz się na kontakt telefoniczny i mailowy w celu realizacji wydarzenia. Administratorem Twoich danych osobowych jest Softinet Sp. z o.o. z siedzibą w Warszawie. Przeczytaj w naszej <a href="https://softinet.com.pl/polityka-prywatnosci/" target="_blank" rel="noopener">Polityce prywatności i cookies</a>, jak przetwarzamy Twoje dane.
</div>
</div>
<!-- Jedyna zgoda regulaminowa (wymagana) -->
<div class="field">
<div class="checkbox-left">
<input type="checkbox" id="consent_event_regulations" required>
<label for="consent_event_regulations">
Akceptuję <a href="https://softinet.com.pl/wp-content/uploads/Regulamin_konferencji_Softinet_ITandSEC_Camp_2026.pdf" target="_blank" rel="noopener">
regulamin uczestnictwa w konferencji Softinet IT&SEC Camp 2026
</a> oraz wyrażam zgodę na przekazanie moich danych osobowych Partnerom wydarzenia.
<span class="req">*</span>
</label>
</div>
<div class="error" id="err_consent_event_regulations">
Wymagana akceptacja regulaminu uczestnictwa w konferencji.
</div>
<div class="note" style="margin-top:10px;">
Ze względu na duże zainteresowanie wydarzeniem oraz ograniczoną liczbę miejsc prosimy o rejestrację maksymalnie dwóch przedstawicieli danej organizacji.<br>
Udział zarejestrowanych osób będziemy potwierdzać w oddzielnej wiadomości e-mail.
</div>
</div>
<div class="actions">
<button class="btn" id="submitBtn" type="submit">Zarezerwuj swoje miejsce</button>
</div>
<div class="error" id="err_general">Nie udało się wysłać formularza. Spróbuj ponownie za chwilę.</div>
</form>
<script>
(function(){
const ENDPOINT = "https://softinet-gr-forms.a-grabinski.workers.dev/gr/subscribe";
const THANK_YOU_URL = "https://itandsec.softinet.com.pl/thank_you.html";
const form = document.getElementById("softinet-form");
const btn = document.getElementById("submitBtn");
const errGeneral = document.getElementById("err_general");
const el = (id) => document.getElementById(id);
const show = (id, on) => el(id).classList.toggle("show-error", !!on);
const phoneInput = el("phone");
const isEmail = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(String(v || "").trim());
const normPhone = (v) => String(v || "").replace(/\s+/g, "").replace(/^\+48/, "").replace(/^48/, "").trim();
const isPhonePL = (v) => /^\d{9}$/.test(normPhone(v));
function formatPhonePL(v){
const digits = normPhone(v).replace(/\D/g, "").slice(0, 9);
return digits.replace(/(\d{3})(\d{0,3})(\d{0,3})/, (_, a, b, c) => {
return [a, b, c].filter(Boolean).join(" ");
});
}
function getRadio(name){
const checked = form.querySelector(`input[name="${name}"]:checked`);
return checked ? checked.value : "";
}
// Warsztaty – NA RAZIE WYŁĄCZONE
/*
function getWorkshops(){
return Array.from(form.querySelectorAll('input[name="workshops"]:checked')).map(x => x.value);
}
*/
function setBusy(on){
btn.disabled = !!on;
btn.textContent = on ? "Wysyłam..." : "Zarezerwuj swoje miejsce";
}
phoneInput.addEventListener("input", () => {
phoneInput.value = formatPhonePL(phoneInput.value);
});
form.addEventListener("submit", async (e) => {
e.preventDefault();
errGeneral.classList.remove("show-error");
const first_name = el("first_name").value.trim();
const last_name = el("last_name").value.trim();
const company = el("company").value.trim();
const job_title = el("job_title").value.trim();
const email = el("email").value.trim().toLowerCase();
const phoneRaw = el("phone").value;
const phone = normPhone(phoneRaw);
// Zgody marketingowe – wymagany min. 1 kanał
const consent_email_marketing = el("consent_email_marketing").checked;
const consent_phone_marketing = el("consent_phone_marketing").checked;
const atLeastOneChannel = consent_email_marketing || consent_phone_marketing;
// Zgoda regulaminowa (wymagana)
const consentEvent = el("consent_event_regulations").checked;
// Walidacja UI
const fnEmpty = !first_name;
const lnEmpty = !last_name;
const coEmpty = !company;
const jobEmpty = !job_title;
const emBad = !isEmail(email);
const phoneBad = !isPhonePL(phone);
show("err_first_name", fnEmpty);
show("err_last_name", lnEmpty);
show("err_company", coEmpty);
show("err_job_title", jobEmpty);
show("err_email", emBad);
show("err_phone", phoneBad);
if (fnEmpty || lnEmpty || coEmpty || jobEmpty || emBad || phoneBad || !atLeastOneChannel || !consentEvent) {
return;
}
// Dane eventowe
const transport = getRadio("transport"); // yes/no/""
const accommodation = getRadio("accommodation"); // yes/no/""
// Warsztaty – NA RAZIE WYŁĄCZONE
// const workshops = getWorkshops();
// Honeypot
const website = (form.querySelector('input[name="website"]').value || "").trim();
const payload = {
email,
first_name,
last_name,
phone: "+48" + phone,
company,
job_title,
registration_source: "konferencja_camp_2026",
// Zgody marketingowe – Worker je rozumie
consent_email_marketing,
consent_phone_marketing,
// Zgody eventowe – na razie informacyjnie
consent_regulations: true,
consent_partners: true,
page_url: window.location.href,
consent_text_version: "camp_2026_v1",
crm_campaign_name: "Konferencja IT&SEC Camp 2026 - rejestracje",
// custom fields do mapowania w Workerze (jeśli dodasz ID pól)
transport,
accommodation,
// workshops,
website
};
try {
setBusy(true);
const res = await fetch(ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
const txt = await res.text();
let json;
try { json = JSON.parse(txt); } catch { json = null; }
if (!res.ok || (json && json.ok === false)) {
console.log("Worker error:", res.status, txt);
errGeneral.classList.add("show-error");
return;
}
window.location.href = THANK_YOU_URL;
} catch (err) {
console.log("Network error:", err);
errGeneral.classList.add("show-error");
} finally {
setBusy(false);
}
});
})();
</script>
</div>