Iniciar sesión

Crear cuenta

Tema

Catálogo de paquetes

Busca y filtra paquetes según tus necesidades. Precios en CLP.

Detalles

Imagen base Imagen editada

Comparador de luz: arrastra para ver antes/después.

Stock: | Categoría:

rk:text-neutral-300 text-xs">#${t}`).join('')}`; const tagSpan = document.getElementById('detailTags'); tagSpan.innerHTML = tagsUl; const stockTxt = item.category==='package' ? '예약 가능' : (item.stock>0 ? `재고 ${item.stock}` : '품절'); document.getElementById('detailStock').innerHTML = `${stockTxt}`; const favBtn=document.getElementById('detailFav'); const cartBtn=document.getElementById('detailCart'); const inqBtn=document.getElementById('detailInquiry'); favBtn.textContent = isFav(item.id)?'즐겨찾기 해제':'즐겨찾기'; favBtn.onclick=()=>{ saveFav(item.id); favBtn.textContent = isFav(item.id)?'즐겨찾기 해제':'즐겨찾기'; render(); }; cartBtn.onclick=()=>addCart(item.id); inqBtn.onclick=()=>{ document.getElementById('inquiryItemId').value=item.id; openModal('modalInquiry'); }; const thumbs = document.getElementById('detailThumbs'); thumbs.innerHTML = (item.images||[]).map((src,idx)=>``).join(''); thumbs.querySelectorAll('[data-goto]').forEach(btn=>btn.addEventListener('click', ev=>{ const idx=parseInt(ev.currentTarget.dataset.goto,10); state.galleryIndex=idx; document.getElementById('detailImg').src=item.images[idx]; thumbs.querySelectorAll('[data-goto]').forEach(b=>b.classList.remove('ring-black','dark:ring-white')); ev.currentTarget.classList.add('ring-black'); ev.currentTarget.classList.add('dark:ring-white'); })); document.getElementById('detailPrev').onclick=()=>{ state.galleryIndex=(state.galleryIndex-1+item.images.length)%item.images.length; document.getElementById('detailImg').src=item.images[state.galleryIndex]; thumbs.querySelectorAll('[data-goto]').forEach((b,i)=>{ b.classList.toggle('ring-black', i===state.galleryIndex); b.classList.toggle('dark:ring-white', i===state.galleryIndex); }); }; document.getElementById('detailNext').onclick=()=>{ state.galleryIndex=(state.galleryIndex+1)%item.images.length; document.getElementById('detailImg').src=item.images[state.galleryIndex]; thumbs.querySelectorAll('[data-goto]').forEach((b,i)=>{ b.classList.toggle('ring-black', i===state.galleryIndex); b.classList.toggle('dark:ring-white', i===state.galleryIndex); }); }; openModal('modalDetail'); } })); } function startDealTimer(){ const el=document.getElementById('timerDeal'); function nextMidnight(){ const d=new Date(); d.setDate(d.getDate()+1); d.setHours(23,59,59,999); return d; } let end=nextMidnight(); function tick(){ const now=new Date(); if(now>=end){ end=nextMidnight(); } let diff = end - now; const h=String(Math.floor(diff/3600000)).padStart(2,'0'); diff%=3600000; const m=String(Math.floor(diff/60000)).padStart(2,'0'); diff%=60000; const s=String(Math.floor(diff/1000)).padStart(2,'0'); el.textContent=`${h}:${m}:${s}`; } tick(); setInterval(tick, 1000); } function setupCookieBanner(){ const key='cookieConsent'; const val=localStorage.getItem(key); const wrap=document.getElementById('cookieBanner'); if(!val){ wrap.classList.remove('hidden'); } document.getElementById('cookieAccept').addEventListener('click', ()=>{ localStorage.setItem(key, JSON.stringify({value:'yes', ts: Date.now()})); wrap.classList.add('hidden'); }); document.getElementById('cookieDecline').addEventListener('click', ()=>{ localStorage.setItem(key, JSON.stringify({value:'no', ts: Date.now()})); wrap.classList.add('hidden'); }); } function setupThemeToggle(){ const btn=document.getElementById('themeToggle'); function label(){ const d=document.documentElement.classList.contains('dark'); btn.textContent = d ? '라이트' : '다크'; } btn.addEventListener('click', ()=>{ const root=document.documentElement; if(root.classList.contains('dark')){ root.classList.remove('dark'); localStorage.setItem('theme','light'); } else { root.classList.add('dark'); localStorage.setItem('theme','dark'); } label(); }); label(); } function setupInquiryForm(){ const form=document.getElementById('inquiryForm'); const nameEl=document.getElementById('inqName'); const emailEl=document.getElementById('inqEmail'); const phoneEl=document.getElementById('inqPhone'); const msgEl=document.getElementById('inqMsg'); const errName=document.getElementById('errName'); const errEmail=document.getElementById('errEmail'); const errPhone=document.getElementById('errPhone'); const errMsg=document.getElementById('errMsg'); function validate(){ let ok=true; if(!nameEl.value.trim()){ errName.classList.remove('hidden'); ok=false; } else errName.classList.add('hidden'); const emailOk=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailEl.value.trim()); if(!emailOk){ errEmail.classList.remove('hidden'); ok=false; } else errEmail.classList.add('hidden'); const phoneOk=/^01[016789]-\d{3,4}-\d{4}$/.test(phoneEl.value.trim()); if(!phoneOk){ errPhone.classList.remove('hidden'); ok=false; } else errPhone.classList.add('hidden'); if(!msgEl.value.trim()){ errMsg.classList.remove('hidden'); ok=false; } else errMsg.classList.add('hidden'); return ok; } [nameEl,emailEl,phoneEl,msgEl].forEach(el=> el.addEventListener('input', validate)); form.addEventListener('submit', (e)=>{ e.preventDefault(); if(!validate()) return; const data={ id: crypto.randomUUID ? crypto.randomUUID() : String(Date.now()), itemId: document.getElementById('inquiryItemId').value, name: nameEl.value.trim(), email: emailEl.value.trim(), phone: phoneEl.value.trim(), message: msgEl.value.trim(), createdAt: new Date().toISOString() }; const key='inquiries'; const arr=JSON.parse(localStorage.getItem(key)||'[]'); arr.push(data); localStorage.setItem(key, JSON.stringify(arr)); form.reset(); closeModal('modalInquiry'); const okToast=document.createElement('div'); okToast.className='fixed bottom-20 left-1/2 -translate-x-1/2 px-4 py-2 rounded-xl bg-black text-white dark:bg-white dark:text-black z-50'; okToast.textContent='상담 요청이 접수되었습니다.'; document.body.appendChild(okToast); setTimeout(()=>{ okToast.remove(); }, 2500); }); } document.addEventListener('DOMContentLoaded', async () => { await inject('header','./header.html'); await inject('footer','./footer.html'); document.getElementById('q').addEventListener('input', e=>{ state.q=e.target.value; state.page=1; render(); }); document.getElementById('cat').addEventListener('change', e=>{ state.cat=e.target.value; state.page=1; render(); }); document.getElementById('max').addEventListener('input', e=>{ state.max = e.target.value ? parseInt(e.target.value,10) : null; state.page=1; render(); }); document.getElementById('sort').addEventListener('change', e=>{ state.sort=e.target.value; render(); }); document.getElementById('favOnly').addEventListener('change', e=>{ state.favOnly=e.target.checked; state.page=1; render(); }); document.getElementById('reset').addEventListener('click', ()=>{ document.getElementById('q').value=''; document.getElementById('cat').value=''; document.getElementById('max').value=''; document.getElementById('sort').value='reco'; document.getElementById('favOnly').checked=false; state.q=''; state.cat=''; state.max=null; state.sort='reco'; state.page=1; state.favOnly=false; render(); }); try{ const res=await fetch('./catalog.json'); state.data=await res.json(); }catch(e){ state.data=[]; } render(); startDealTimer(); setupCookieBanner(); setupThemeToggle(); setupInquiryForm(); });