(function () {
const TEXT = {
prizeTypesSelected: function ( n ) { return n + ' typer premie valgt'; },
errFillName: 'Fyll inn navn.',
errFillPurpose: 'Fyll inn formål.',
errFillEmail: 'Fyll inn e-postadresse.',
errInvalidEmail: 'Ugyldig e-postadresse.',
errFillPhone: 'Fyll inn mobilnummer.',
errInvalidPhone: 'Mobilnummer må være 8 siffer.',
errFillAccount: 'Fyll inn bankkontonummer.',
errInvalidAccount: 'Ugyldig kontonummer (11 siffer med riktig kontrollsiffer).',
errTicketsRange: 'Antall må være mellom 100 og 10000.',
errMin5Prizes: 'Legg til minst 5 premier.',
errPrizeTitle: 'Fyll inn tittel.',
errLowWinChance: 'For lav vinnersjanse — legg til flere premier eller øk antallet per premie.',
labelStk: ' stk',
labelEstimatedValue: 'Verdi: ',
labelSelectedFile: 'Valgt fil: ',
labelNoLogo: 'Ingen'
};
const STORAGE_KEY = 'klubblodd_campaign_state_v1';
const ENDPOINT_URL = '/api/2026-05/register-campaign';
function byId ( id ) {
return document.getElementById( id );
}
function qs ( sel , root ) {
return ( root || document ).querySelector( sel );
}
function qsa ( sel , root ) {
return Array.prototype.slice.call( ( root || document ).querySelectorAll( sel ) );
}
function onlyDigits ( s ) {
return String( s || '' ).replace( /[^0-9]/g , '' );
}
// Norsk kontonummer: 11 siffer med MOD11-kontrollsiffer.
function validAccount ( acc ) {
acc = onlyDigits( acc );
if ( acc.length !== 11 ) return false;
const w = [ 5, 4, 3, 2, 7, 6, 5, 4, 3, 2 ];
let sum = 0;
for ( let i = 0; i < 10; i++ ) sum += parseInt( acc.charAt( i ) , 10 ) * w[ i ];
const rest = sum % 11;
const ctrl = rest === 0 ? 0 : 11 - rest;
if ( ctrl === 10 ) return false;
return ctrl === parseInt( acc.charAt( 10 ) , 10 );
}
function escapeHtml ( s ) {
return String( s || '' )
.replace( /&/g , '&' )
.replace( //g , '>' )
.replace( /"/g , '"' )
.replace( /'/g , ''' ); /* " */
}
function setError ( id , msg ) {
const out = qs( '.error[data-for="' + id + '"]' );
if ( out ) out.textContent = msg || '';
const el = byId( id );
if ( el ) {
if ( msg ) el.classList.add( 'invalid' );
else el.classList.remove( 'invalid' );
}
}
function safeParseJson ( s , fallback ) {
try {
return JSON.parse( s );
} catch ( err ) {
return fallback;
}
}
function getPrizes () {
const el = byId( 'prizes_json' );
if ( !el ) return [];
return safeParseJson( el.value || '[]' , [] );
}
function setPrizes ( prizes ) {
const el = byId( 'prizes_json' );
if ( el ) el.value = JSON.stringify( prizes || [] );
renderPrizes();
saveStateToStorage();
}
function renderPrizes () {
const prizes = getPrizes();
const list = byId( 'prize_list' );
const count = byId( 'prize_count' );
if ( list ) list.innerHTML = '';
prizes.forEach( function ( p , idx ) {
const row = document.createElement( 'div' );
row.className = 'prize_row';
const left = document.createElement( 'div' );
left.className = 'prize_left';
const title = ( p.title || '' ).trim();
const qty = parseInt( p.qty || 0 , 10 ) || 0;
const value = ( p.value || '' ).trim();
let meta = '';
if ( qty ) meta += qty + TEXT.labelStk.trim();
if ( value ) meta += ( meta ? ' - ca kr ' : 'ca kr ' ) + value + ',-';
left.innerHTML =
'
' + escapeHtml( title ) + '
' +
'' + escapeHtml( meta ) + '
';
const right = document.createElement( 'div' );
right.className = 'prize_right';
const del = document.createElement( 'button' );
del.type = 'button';
del.className = 'mini';
del.textContent = 'Fjern';
del.addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
e.stopPropagation();
prizes.splice( idx , 1 );
setPrizes( prizes );
} , { passive: false } );
right.appendChild( del );
row.appendChild( left );
row.appendChild( right );
if ( list ) list.appendChild( row );
} );
if ( count ) count.textContent = TEXT.prizeTypesSelected( prizes.length );
updateWinChance();
}
// ── Premieforslag ────────────────────────────────────────────────
function renderSuggestions () {
const wrap = byId( 'prize_suggestions' );
if ( !wrap ) return;
const templates = Array.isArray( window.__PRIZE_TEMPLATES ) ? window.__PRIZE_TEMPLATES : [];
wrap.innerHTML = '';
templates.forEach( function ( t ) {
const chip = document.createElement( 'button' );
chip.type = 'button';
chip.className = 'suggest_chip';
chip.textContent = t.name;
if ( t.text ) chip.title = t.text;
chip.addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
addPrizeQuick( t.name );
} , { passive: false } );
wrap.appendChild( chip );
} );
}
function addPrizeQuick ( name ) {
name = String( name || '' ).trim();
if ( !name ) return;
const prizes = getPrizes();
// Finnes premien alt? Øk antallet i stedet for duplikat.
const existing = prizes.filter( function ( p ) { return ( p.title || '' ).toLowerCase() === name.toLowerCase(); } )[ 0 ];
if ( existing ) {
existing.qty = ( parseInt( existing.qty , 10 ) || 0 ) + 1;
} else {
prizes.push( { title: name , qty: 1 , value: '' } );
}
setPrizes( prizes );
}
// ── Vinnersjanse ─────────────────────────────────────────────────
function winRate () {
const tickets = parseInt( onlyDigits( ( byId( 'lottery_tickets' ) || {} ).value || '0' ) , 10 ) || 0;
if ( tickets <= 0 ) return { rate: 0, winners: 0, tickets: 0 };
let winners = getPrizes().reduce( function ( sum , p ) {
return sum + ( parseInt( p.qty , 10 ) || 0 );
} , 0 );
// Hovedpremien teller som én ekstra vinner når tittel er satt
const mainTitle = ( ( byId( 'main_title' ) || {} ).value || '' ).trim();
if ( mainTitle.length >= 2 ) winners += 1;
return { rate: winners / tickets, winners: winners, tickets: tickets };
}
function updateWinChance () {
const fill = byId( 'winchance_fill' );
const text = byId( 'winchance_text' );
if ( !fill || !text ) return;
const cfg = window.__WINCHANCE || { min: 0.10, good: 0.25 };
const w = winRate();
const pct = Math.round( w.rate * 1000 ) / 10; // én desimal
const oneIn = w.winners > 0 ? Math.round( w.tickets / w.winners ) : 0;
// Bredde på måleren (skala 0–good*2, kappet 100%)
const fillPct = Math.max( 0, Math.min( 100, ( w.rate / ( cfg.good * 2 ) ) * 100 ) );
fill.style.width = fillPct + '%';
let cls = 'wc_bad', msg;
if ( w.winners === 0 || w.tickets === 0 ) {
cls = 'wc_bad';
msg = 'Legg til premier for å se vinnersjansen.';
} else if ( w.rate >= cfg.good ) {
cls = 'wc_good';
msg = 'Gode vinnersjanser! ' + pct + ' % vinner (omtrent 1 av ' + oneIn + ' lodd).';
} else if ( w.rate >= cfg.min ) {
cls = 'wc_ok';
msg = 'Ok vinnersjanse: ' + pct + ' % (1 av ' + oneIn + '). Vi anbefaler minst ' + Math.round( cfg.good * 100 ) + ' % — legg gjerne til flere premier.';
} else {
cls = 'wc_bad';
msg = 'For lav vinnersjanse: ' + pct + ' %' + ( oneIn ? ' (1 av ' + oneIn + ')' : '' ) + '. Minst ' + Math.round( cfg.min * 100 ) + ' % kreves — øk antall premier.';
}
const box = byId( 'winchance' );
if ( box ) box.className = 'winchance ' + cls;
text.textContent = msg;
}
function validateStep1 () {
let ok = true;
const name = ( byId( 'org_name' ).value || '' ).trim();
const purpose = ( byId( 'org_purpose' ).value || '' ).trim();
const email = ( byId( 'org_email' ).value || '' ).trim();
const phone = onlyDigits( byId( 'org_phone' ).value || '' );
setError( 'org_name' , '' );
setError( 'org_purpose' , '' );
setError( 'org_email' , '' );
setError( 'org_phone' , '' );
if ( name.length < 2 ) {
setError( 'org_name' , TEXT.errFillName );
ok = false;
}
if ( purpose.length < 2 ) {
setError( 'org_purpose' , TEXT.errFillPurpose );
ok = false;
}
if ( email.length === 0 ) {
setError( 'org_email' , TEXT.errFillEmail );
ok = false;
} else if ( !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test( email ) ) {
setError( 'org_email' , TEXT.errInvalidEmail );
ok = false;
}
if ( phone.length === 0 ) {
setError( 'org_phone' , TEXT.errFillPhone );
ok = false;
} else if ( phone.length !== 8 ) {
setError( 'org_phone' , TEXT.errInvalidPhone );
ok = false;
} else {
byId( 'org_phone' ).value = phone;
}
const account = onlyDigits( ( byId( 'org_account' ) || {} ).value || '' );
setError( 'org_account' , '' );
if ( account.length === 0 ) {
setError( 'org_account' , TEXT.errFillAccount );
ok = false;
} else if ( !validAccount( account ) ) {
setError( 'org_account' , TEXT.errInvalidAccount );
ok = false;
} else if ( byId( 'org_account' ) ) {
byId( 'org_account' ).value = account;
}
return ok;
}
function validateStep2 () {
let ok = true;
setError( 'lottery_tickets' , '' );
if ( byId( 'prize_error' ) ) byId( 'prize_error' ).textContent = '';
const tickets = parseInt( onlyDigits( byId( 'lottery_tickets' ).value || '0' ) , 10 ) || 0;
if ( tickets < 100 || tickets > 10000 ) {
setError( 'lottery_tickets' , TEXT.errTicketsRange );
ok = false;
} else {
byId( 'lottery_tickets' ).value = String( tickets );
}
const prizes = getPrizes();
if ( prizes.length < 5 ) {
if ( byId( 'prize_error' ) ) byId( 'prize_error' ).textContent = TEXT.errMin5Prizes;
ok = false;
}
// Vinnersjanse-sperre — blokker under minimumsterskel
updateWinChance();
const w = winRate();
const cfg = window.__WINCHANCE || { min: 0.10, good: 0.25 };
if ( w.tickets > 0 && w.rate < cfg.min ) {
if ( byId( 'prize_error' ) ) byId( 'prize_error' ).textContent = TEXT.errLowWinChance;
ok = false;
}
return ok;
}
function validateStep3 () {
return true;
}
function readState () {
const prizes = getPrizes();
return {
name: ( byId( 'org_name' ).value || '' ).trim(),
purpose: ( byId( 'org_purpose' ).value || '' ).trim(),
email: ( byId( 'org_email' ).value || '' ).trim(),
phone: onlyDigits( byId( 'org_phone' ).value || '' ),
account: onlyDigits( ( byId( 'org_account' ) || {} ).value || '' ),
tickets: parseInt( onlyDigits( byId( 'lottery_tickets' ).value || '0' ) , 10 ) || 0,
price: parseInt( byId( 'lottery_price' ).value || '0' , 10 ) || 0,
prizes: prizes,
days: parseInt( byId( 'lottery_days' ).value || '0' , 10 ) || 0,
color: byId( 'partner_color' ).value || '',
main_title: ( ( byId( 'main_title' ) || {} ).value || '' ).trim(),
main_value: ( ( byId( 'main_value' ) || {} ).value || '' ).trim(),
logoName: ( byId( 'lottery_logo' ).files && byId( 'lottery_logo' ).files[ 0 ] ) ? byId( 'lottery_logo' ).files[ 0 ].name : ''
};
}
function saveStateToStorage () {
try {
localStorage.setItem( STORAGE_KEY , JSON.stringify( readState() ) );
} catch ( err ) {}
}
function loadStateFromStorage () {
const raw = ( function () {
try { return localStorage.getItem( STORAGE_KEY ); } catch ( err ) { return null; }
} )();
if ( !raw ) return null;
const s = safeParseJson( raw , null );
if ( !s || typeof s !== 'object' ) return null;
return s;
}
function applyStateToForm ( s ) {
if ( !s ) return;
if ( byId( 'org_name' ) && typeof s.name === 'string' ) byId( 'org_name' ).value = s.name;
if ( byId( 'org_purpose' ) && typeof s.purpose === 'string' ) byId( 'org_purpose' ).value = s.purpose;
if ( byId( 'org_email' ) && typeof s.email === 'string' ) byId( 'org_email' ).value = s.email;
if ( byId( 'org_phone' ) && typeof s.phone === 'string' ) byId( 'org_phone' ).value = onlyDigits( s.phone );
if ( byId( 'org_account' ) && typeof s.account === 'string' ) byId( 'org_account' ).value = onlyDigits( s.account );
if ( byId( 'lottery_tickets' ) ) byId( 'lottery_tickets' ).value = s.tickets ? String( parseInt( s.tickets , 10 ) || 0 ) : '';
if ( byId( 'lottery_price' ) ) byId( 'lottery_price' ).value = s.price ? String( parseInt( s.price , 10 ) || 0 ) : '';
if ( byId( 'lottery_days' ) ) byId( 'lottery_days' ).value = s.days ? String( parseInt( s.days , 10 ) || 0 ) : '';
if ( byId( 'partner_color' ) && typeof s.color === 'string' ) byId( 'partner_color' ).value = s.color;
if ( byId( 'main_title' ) && typeof s.main_title === 'string' ) byId( 'main_title' ).value = s.main_title;
if ( byId( 'main_value' ) && typeof s.main_value === 'string' ) byId( 'main_value' ).value = s.main_value;
if ( Array.isArray( s.prizes ) ) {
const cleaned = s.prizes.map( function ( p ) {
return {
title: ( p && p.title ) ? String( p.title ) : '',
qty: ( p && p.qty != null ) ? parseInt( p.qty , 10 ) || 0 : 0,
value: ( p && p.value ) ? String( p.value ) : ''
};
} );
const el = byId( 'prizes_json' );
if ( el ) el.value = JSON.stringify( cleaned );
renderPrizes();
}
if ( byId( 'logo_note' ) && s.logoName ) {
byId( 'logo_note' ).textContent = TEXT.labelSelectedFile + s.logoName;
}
}
function renderPreview () {
const s = readState();
const el = byId( 'preview' );
if ( !el ) return;
const prizeRows = s.prizes.map( function ( p ) {
const t = escapeHtml( p.title || '' );
const q = parseInt( p.qty || 0 , 10 ) || 0;
const v = escapeHtml( p.value || '' );
let meta = '';
if ( q ) meta += q + TEXT.labelStk.trim();
meta += ( meta ? ' ' : '' ) +'( '+ TEXT.labelEstimatedValue + ( v ? 'Kr '+ v +',-' : '-' ) + ' )';
return '' + t + '
' + escapeHtml( meta ) + '
';
} ).join( '' );
el.innerHTML =
'' +
'
Arrangør
' +
'
Navn
' + escapeHtml( s.name ) + '
' +
'
Formål
' + escapeHtml( s.purpose ) + '
' +
'
E-post
' + escapeHtml( s.email ) + '
' +
'
Mobil
' + escapeHtml( s.phone ) + '
' +
'
Konto
' + escapeHtml( s.account || '' ) + '
' +
'
' +
'' +
'
Lodd
' +
'
Antall
' + escapeHtml( String( s.tickets ) ) + '
' +
'
Pris
' + escapeHtml( String( s.price ) ) + ' kr
' +
'
' +
'' +
'
Premier
' +
( s.main_title ? '
🏆 ' + escapeHtml( s.main_title ) + '
Hovedpremie' + ( s.main_value ? ' · ' + escapeHtml( s.main_value ) : '' ) + '
' : '' ) +
( prizeRows || ( s.main_title ? '' : '
Ingen premier lagt til.
' ) ) +
'
' +
'' +
'
Innstillinger
' +
'
Lengde
' + escapeHtml( String( s.days ) ) + ' dager
' +
'
Farge
' + escapeHtml( s.color ) + '
' +
( function () {
var lp = byId( 'logo_preview' );
var lsrc = ( lp && lp.src && lp.src.indexOf( 'data:' ) === 0 ) ? lp.src : '';
return '
Logo
' +
( lsrc ? '

' : ( s.logoName ? escapeHtml( s.logoName ) : TEXT.labelNoLogo ) ) +
'
';
} )() +
'
';
if ( byId( 'payload_json' ) ) byId( 'payload_json' ).value = JSON.stringify( s );
saveStateToStorage();
}
function setStep ( step ) {
const stepNum = parseInt( step || '1' , 10 ) || 1;
qsa( '.step_panel' ).forEach( function ( p ) {
p.classList.remove( 'is_active' );
if ( parseInt( p.getAttribute( 'data-step' ) || '0' , 10 ) === stepNum ) {
p.classList.add( 'is_active' );
}
} );
qsa( '.step_btn' ).forEach( function ( b ) {
b.classList.remove( 'is_active' );
if ( parseInt( b.getAttribute( 'data-step' ) || '0' , 10 ) === stepNum ) {
b.classList.add( 'is_active' );
}
} );
const bar = byId( 'progress_bar' );
if ( bar ) {
const pct = Math.round( ( stepNum - 1 ) / 3 * 100 );
bar.style.width = pct + '%';
}
if ( stepNum === 4 ) renderPreview();
saveStateToStorage();
window.scrollTo( 0 , 0 );
}
function openModal () {
byId( 'prize_modal' ).classList.remove( 'is_hidden' );
byId( 'prize_title' ).value = '';
byId( 'prize_qty' ).value = '1';
byId( 'prize_value' ).value = '';
setError( 'prize_title' , '' );
byId( 'prize_title' ).focus();
}
function closeModal () {
byId( 'prize_modal' ).classList.add( 'is_hidden' );
}
function addPrizeFromModal () {
const title = ( byId( 'prize_title' ).value || '' ).trim();
setError( 'prize_title' , '' );
if ( title.length < 2 ) {
setError( 'prize_title' , TEXT.errPrizeTitle );
byId( 'prize_title' ).focus();
return;
}
const qty = Math.max( 1, parseInt( onlyDigits( byId( 'prize_qty' ).value || '1' ) , 10 ) || 1 );
const value = ( byId( 'prize_value' ).value || '' ).trim();
const prizes = getPrizes();
prizes.push( { title: title , qty: qty , value: value } );
setPrizes( prizes );
closeModal();
}
function sendFinalStateToEndpoint () {
const s = readState();
const payload = JSON.stringify( s );
try {
localStorage.setItem( STORAGE_KEY , payload );
} catch ( err ) {}
const form = byId( 'campaign_form' );
const fd = new FormData( form || undefined );
fd.set( 'payload_json' , payload );
function setDialogStatus ( ok , msg , onClose , details ) {
const dlg = document.querySelector( 'dialog[data-sent-flag]' );
if ( !dlg || typeof dlg.showModal !== 'function' ) return;
const statusEl = dlg.querySelector( '[data-status]' );
const msgEl = dlg.querySelector( '[data-message]' );
if ( statusEl ) statusEl.textContent = ok ? 'Lagret!' : 'Noe gikk galt';
if ( msgEl ){
msgEl.innerHTML = '';
if ( msg ){
const p = document.createElement( 'p' );
p.textContent = msg;
msgEl.appendChild( p );
} else if ( !ok ){
const p = document.createElement( 'p' );
p.textContent = 'Kunne ikke lagre.';
msgEl.appendChild( p );
}
if ( !ok && Array.isArray( details ) && details.length ){
const ul = document.createElement( 'ul' );
ul.style.marginTop = '8px';
ul.style.paddingLeft = '20px';
details.forEach( function ( d ){
const li = document.createElement( 'li' );
li.textContent = d;
ul.appendChild( li );
} );
msgEl.appendChild( ul );
}
}
dlg.setAttribute( 'data-ok' , ok ? '1' : '0' );
if ( typeof onClose === 'function' ) {
dlg.addEventListener( 'close', function () { onClose(); }, { once: true } );
}
if ( !dlg.open ) dlg.showModal();
}
try {
fetch( ENDPOINT_URL , {
method: 'POST',
body: fd,
credentials: 'same-origin',
keepalive: true,
headers: { 'X-Requested-With': 'XMLHttpRequest' }
} )
.then( function ( res ) {
return res.json().then( function ( j ) {
if ( j && j.status && j.status.code === 200 ) {
// Success — server returns next URL for confirmation step
try {
localStorage.removeItem( STORAGE_KEY );
} catch ( err ) {}
const next = ( j.data && j.data.next ) || '/';
setDialogStatus( true , 'Vi har sendt en bekreftelseskode til e-posten din.' , function () {
window.location.href = next;
} );
} else {
const m = ( j && j.status && j.status.message ) ? String( j.status.message ) : 'Kunne ikke lagre.';
const det = ( j && j.data && Array.isArray( j.data.details ) ) ? j.data.details : null;
setDialogStatus( false , m , null , det );
}
return null;
} ).catch( function () {
setDialogStatus( false , 'Ugyldig svar fra server.' );
return null;
} );
} )
.catch( function () {
setDialogStatus( false , 'Nettverksfeil.' );
} );
} catch ( err ) {
setDialogStatus( false , 'Teknisk feil.' );
}
}
function bindAutoSave () {
const ids = [
'org_name',
'org_purpose',
'org_email',
'org_phone',
'org_account',
'lottery_tickets',
'lottery_price',
'lottery_days',
'partner_color',
'main_title',
'main_value'
];
ids.forEach( function ( id ) {
const el = byId( id );
if ( !el ) return;
el.addEventListener( 'input' , function () {
saveStateToStorage();
} );
el.addEventListener( 'change' , function () {
saveStateToStorage();
} );
} );
}
// ── Bilde-opplasting (generisk dropzone + forhåndsvisning) ───────
function setupDropzone ( opts ) {
const inp = byId( opts.input );
const dz = byId( opts.drop );
const img = byId( opts.preview );
const ph = byId( opts.placeholder );
const clr = byId( opts.clear );
const note = opts.note ? byId( opts.note ) : null;
if ( !inp || !dz ) return;
function showPreview ( file ) {
if ( !img || !file ) return;
if ( !/^image\//.test( file.type || '' ) ) { clearIt(); return; }
const reader = new FileReader();
reader.onload = function ( e ) {
img.src = e.target.result;
img.hidden = false;
if ( ph ) ph.hidden = true;
if ( clr ) clr.hidden = false;
dz.classList.add( 'has_file' );
};
reader.readAsDataURL( file );
if ( note ) note.textContent = TEXT.labelSelectedFile + file.name;
}
function clearIt () {
inp.value = '';
if ( img ) { img.src = ''; img.hidden = true; }
if ( ph ) ph.hidden = false;
if ( clr ) clr.hidden = true;
dz.classList.remove( 'has_file' );
if ( note ) note.textContent = '';
saveStateToStorage();
}
inp.addEventListener( 'change' , function () {
const f = ( inp.files && inp.files[ 0 ] ) ? inp.files[ 0 ] : null;
if ( f ) showPreview( f ); else clearIt();
saveStateToStorage();
} );
[ 'dragenter' , 'dragover' ].forEach( function ( ev ) {
dz.addEventListener( ev , function ( e ) { e.preventDefault(); dz.classList.add( 'is_drag' ); } );
} );
[ 'dragleave' , 'dragend' ].forEach( function ( ev ) {
dz.addEventListener( ev , function () { dz.classList.remove( 'is_drag' ); } );
} );
dz.addEventListener( 'drop' , function ( e ) {
e.preventDefault();
dz.classList.remove( 'is_drag' );
const files = e.dataTransfer && e.dataTransfer.files;
if ( files && files.length ) {
try { inp.files = files; } catch ( err ) {}
showPreview( files[ 0 ] );
saveStateToStorage();
}
} );
if ( clr ) {
clr.addEventListener( 'click' , function ( e ) {
e.preventDefault();
e.stopPropagation();
clearIt();
} );
}
}
// ⚠️ TEST ONLY — REMOVE BEFORE PROD — START
function fillWithTestData () {
var orgs = [
{ name: 'Berglia Idrettslag', purpose: 'Ny drakter til juniorlaget', email: 'test1@example.com', phone: '40000001', account: '12345678903' },
{ name: 'Frogner Fotballklubb', purpose: 'Reise til sommerturneringen', email: 'test2@example.com', phone: '92345678', account: '98765432103' },
{ name: 'Åsly Musikkorps', purpose: 'Nytt instrument til korpset', email: 'test3@example.com', phone: '41234567', account: '15065431006' },
{ name: 'Skansen Barnehage', purpose: 'Dugnadsmidler til lekeplassen', email: 'test4@example.com', phone: '99887766', account: '80005000002' },
{ name: 'Nordvik Svømmeklubb', purpose: 'Utstyr til høstsesongen', email: 'test5@example.com', phone: '47000001', account: '12001200125' }
];
var prizeSets = [
[ { title: 'Gavekort', qty: 5, value: '250' }, { title: 'Termos', qty: 10, value: '180' }, { title: 'Sjokolade', qty: 20, value: '45' }, { title: 'Caps', qty: 8, value: '130' }, { title: 'Kaffekopp', qty: 15, value: '75' }, { title: 'Nøkkelring', qty: 25, value: '30' } ],
[ { title: 'Treningsvest', qty: 3, value: '280' }, { title: 'Vannflaske', qty: 12, value: '140' }, { title: 'T-skjorte', qty: 6, value: '190' }, { title: 'Lue', qty: 10, value: '110' }, { title: 'Badesvamp', qty: 20, value: '35' }, { title: 'Munnbind', qty: 30, value: '20' } ]
];
var org = orgs[ Math.floor( Math.random() * orgs.length ) ];
var prizes = prizeSets[ Math.floor( Math.random() * prizeSets.length ) ];
applyStateToForm( {
name: org.name,
purpose: org.purpose,
email: org.email,
phone: org.phone,
account: org.account,
tickets: 500,
price: 25,
prizes: prizes,
days: 30,
color: 'RED',
main_title: 'Signert klubbdrakt',
main_value: '290'
} );
updateWinChance();
saveStateToStorage();
}
// ⚠️ TEST ONLY — REMOVE BEFORE PROD — END
function bind () {
const stored = loadStateFromStorage();
if ( stored ) {
applyStateToForm( stored );
} else {
setPrizes( [] );
}
setStep( 1 );
// ⚠️ TEST ONLY — REMOVE BEFORE PROD — START
var titleEl = qs( '.title' );
if ( titleEl ) titleEl.addEventListener( 'dblclick' , fillWithTestData );
// ⚠️ TEST ONLY — REMOVE BEFORE PROD — END
bindAutoSave();
renderSuggestions();
updateWinChance();
qsa( '[data-next]' ).forEach( function ( btn ) {
btn.addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
const next = parseInt( btn.getAttribute( 'data-next' ) || '1' , 10 ) || 1;
if ( next === 2 && !validateStep1() ) return;
if ( next === 3 && !validateStep2() ) return;
if ( next === 4 && !validateStep3() ) return;
setStep( next );
} , { passive: false } );
} );
qsa( '[data-prev]' ).forEach( function ( btn ) {
btn.addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
const prev = parseInt( btn.getAttribute( 'data-prev' ) || '1' , 10 ) || 1;
setStep( prev );
} , { passive: false } );
} );
qsa( '.step_btn' ).forEach( function ( btn ) {
btn.addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
const target = parseInt( btn.getAttribute( 'data-step' ) || '1' , 10 ) || 1;
if ( target === 2 && !validateStep1() ) return;
if ( target === 3 && ( !validateStep1() || !validateStep2() ) ) return;
if ( target === 4 && ( !validateStep1() || !validateStep2() || !validateStep3() ) ) return;
setStep( target );
} , { passive: false } );
} );
byId( 'btn_add_prize' ).addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
openModal();
} , { passive: false } );
byId( 'btn_modal_cancel' ).addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
closeModal();
} , { passive: false } );
byId( 'btn_modal_add' ).addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
addPrizeFromModal();
} , { passive: false } );
byId( 'modal_backdrop' ).addEventListener( 'pointerdown' , function ( e ) {
e.preventDefault();
closeModal();
} , { passive: false } );
byId( 'org_phone' ).addEventListener( 'input' , function () {
byId( 'org_phone' ).value = onlyDigits( byId( 'org_phone' ).value );
saveStateToStorage();
} );
if ( byId( 'org_account' ) ) {
byId( 'org_account' ).addEventListener( 'input' , function () {
byId( 'org_account' ).value = onlyDigits( byId( 'org_account' ).value );
saveStateToStorage();
} );
}
byId( 'lottery_tickets' ).addEventListener( 'input' , function () {
byId( 'lottery_tickets' ).value = onlyDigits( byId( 'lottery_tickets' ).value );
updateWinChance();
saveStateToStorage();
} );
setupDropzone( { input:'lottery_logo', drop:'logo_drop', preview:'logo_preview', placeholder:'logo_placeholder', clear:'logo_clear', note:'logo_note' } );
setupDropzone( { input:'main_prize_image', drop:'mainimg_drop', preview:'mainimg_preview', placeholder:'mainimg_placeholder', clear:'mainimg_clear' } );
if ( byId( 'main_title' ) ) {
byId( 'main_title' ).addEventListener( 'input' , updateWinChance );
}
byId( 'campaign_form' ).addEventListener( 'submit' , function ( e ) {
e.preventDefault();
renderPreview();
if ( byId( 'payload_json' ) ) byId( 'payload_json' ).value = JSON.stringify( readState() );
saveStateToStorage();
sendFinalStateToEndpoint();
} );
}
if ( document.readyState === 'loading' ) {
document.addEventListener( 'DOMContentLoaded' , bind );
} else {
bind();
}
})();