@import url(‘https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=DM+Sans:wght@300;400;500;600&display=swap’);
#unt-pub*,#unt-pub *::before,#unt-pub *::after{box-sizing:border-box;margin:0;padding:0}
#unt-pub{–forest:#1a3a2a;–moss:#2d5a3d;–sage:#5c8a6b;–sand:#f5f0e8;–warm:#e8dcc8;–gold:#c9a84c;–terra:#8b4513;–cream:#faf8f4;–ink:#1c1c1c;–mist:#6b7c73;–red:#c0392b;font-family:’DM Sans’,sans-serif;background:var(–cream);color:var(–ink);min-height:100vh;padding-bottom:90px}
/* LOGIN SCREEN */
#unt-pub .login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(–forest);padding:20px}
#unt-pub .login-box{background:#fff;border-radius:18px;padding:48px 40px;max-width:400px;width:100%;box-shadow:0 24px 60px rgba(0,0,0,.35);text-align:center}
#unt-pub .login-box .logo{font-family:’Playfair Display’,serif;font-size:1.8rem;font-weight:900;color:var(–forest);margin-bottom:6px}
#unt-pub .login-box .logo span{color:var(–gold)}
#unt-pub .login-box p{font-size:.88rem;color:var(–mist);margin-bottom:28px}
#unt-pub .login-box .lf{display:flex;flex-direction:column;gap:6px;text-align:left;margin-bottom:16px}
#unt-pub .login-box .lf label{font-size:.73rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(–mist)}
#unt-pub .login-box .lf input{padding:12px 14px;border:1.5px solid #e0dcd4;border-radius:9px;font-family:’DM Sans’,sans-serif;font-size:.92rem;outline:none;width:100%;transition:border-color .2s}
#unt-pub .login-box .lf input:focus{border-color:var(–sage)}
#unt-pub .login-box .btn-login{width:100%;padding:13px;background:var(–forest);color:#fff;border:none;border-radius:9px;font-family:’DM Sans’,sans-serif;font-size:.95rem;font-weight:600;cursor:pointer;transition:background .2s;margin-top:4px}
#unt-pub .login-box .btn-login:hover{background:var(–moss)}
#unt-pub .login-box .login-err{background:rgba(192,57,43,.1);color:var(–red);border-radius:7px;padding:9px 14px;font-size:.84rem;margin-top:10px;display:none}
/* HEADER */
#unt-pub .hdr{background:var(–forest);padding:24px 36px 20px;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:space-between;gap:16px}
#unt-pub .hdr::before{content:”;position:absolute;top:-50px;right:-50px;width:200px;height:200px;border-radius:50%;background:rgba(201,168,76,.1);pointer-events:none}
#unt-pub .hdr-left h1{font-family:’Playfair Display’,serif;font-size:1.7rem;font-weight:900;color:#fff;line-height:1.15}
#unt-pub .hdr-left h1 span{color:var(–gold)}
#unt-pub .hdr-left p{margin-top:4px;color:rgba(255,255,255,.55);font-size:.83rem}
#unt-pub .hdr-right{display:flex;align-items:center;gap:10px;flex-shrink:0}
#unt-pub .mode-sel{padding:8px 14px;background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.25);border-radius:8px;color:#fff;font-family:’DM Sans’,sans-serif;font-size:.83rem;font-weight:600;cursor:pointer;outline:none}
#unt-pub .mode-sel option{color:var(–ink);background:#fff}
#unt-pub .btn-logout{padding:8px 14px;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2);border-radius:8px;color:rgba(255,255,255,.7);font-family:’DM Sans’,sans-serif;font-size:.8rem;cursor:pointer;transition:all .2s}
#unt-pub .btn-logout:hover{background:rgba(255,255,255,.2);color:#fff}
/* EDIT TRIP PICKER */
#unt-pub .trip-picker{max-width:860px;margin:28px auto;padding:0 18px}
#unt-pub .pick-card{background:#fff;border-radius:14px;border:1px solid rgba(0,0,0,.07);padding:24px 28px;box-shadow:0 2px 10px rgba(0,0,0,.04)}
#unt-pub .pick-card h3{font-family:’Playfair Display’,serif;font-size:1rem;font-weight:700;color:var(–forest);margin-bottom:16px}
#unt-pub .pick-search{width:100%;padding:10px 14px;border:1.5px solid #e0dcd4;border-radius:9px;font-family:’DM Sans’,sans-serif;font-size:.9rem;outline:none;margin-bottom:12px}
#unt-pub .pick-search:focus{border-color:var(–sage)}
#unt-pub .trip-list{max-height:360px;overflow-y:auto;display:flex;flex-direction:column;gap:6px}
#unt-pub .trip-item{padding:12px 16px;border:1.5px solid #e0dcd4;border-radius:9px;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:10px;transition:all .2s;background:var(–cream)}
#unt-pub .trip-item:hover{border-color:var(–sage);background:#fff}
#unt-pub .trip-item .ti-title{font-size:.87rem;font-weight:600;color:var(–ink);line-height:1.3}
#unt-pub .trip-item .ti-meta{font-size:.75rem;color:var(–mist);margin-top:2px}
#unt-pub .trip-item .ti-badge{font-size:.7rem;font-weight:700;padding:3px 9px;border-radius:10px;flex-shrink:0;text-transform:uppercase;letter-spacing:.3px}
#unt-pub .ti-badge.pub{background:rgba(45,90,61,.12);color:var(–moss)}
#unt-pub .ti-badge.dft{background:rgba(201,168,76,.15);color:#7a5c1a}
#unt-pub .ti-badge.prv{background:rgba(0,0,0,.07);color:var(–mist)}
/* TABS */
#unt-pub .tabs{display:flex;background:var(–warm);border-bottom:2px solid var(–moss);padding:0 32px;gap:2px;overflow-x:auto}
#unt-pub .tab{padding:12px 16px;font-size:.8rem;font-weight:600;letter-spacing:.3px;color:var(–mist);border:none;background:none;cursor:pointer;border-bottom:3px solid transparent;margin-bottom:-2px;white-space:nowrap;transition:all .2s}
#unt-pub .tab.on{color:var(–forest);border-bottom-color:var(–gold)}
#unt-pub .tab:hover{color:var(–forest)}
/* BODY */
#unt-pub .body{max-width:860px;margin:0 auto;padding:28px 18px 0}
#unt-pub .card{background:#fff;border-radius:14px;border:1px solid rgba(0,0,0,.07);padding:26px;margin-bottom:18px;box-shadow:0 2px 10px rgba(0,0,0,.04)}
#unt-pub .card h3{font-family:’Playfair Display’,serif;font-size:1rem;font-weight:700;color:var(–forest);margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid var(–warm);display:flex;align-items:center;gap:8px}
#unt-pub .card h3 .ico{width:28px;height:28px;background:var(–forest);border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:.8rem;flex-shrink:0}
#unt-pub .g1{display:grid;grid-template-columns:1fr;gap:14px}
#unt-pub .g2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
#unt-pub .g3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
#unt-pub .g4{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:10px}
#unt-pub .f{display:flex;flex-direction:column;gap:5px}
#unt-pub .f.s2{grid-column:1/-1}
#unt-pub .f label{font-size:.71rem;font-weight:600;letter-spacing:.5px;text-transform:uppercase;color:var(–mist)}
#unt-pub .f label .r{color:var(–terra);margin-left:2px}
#unt-pub .f input,#unt-pub .f textarea,#unt-pub .f select{padding:10px 12px;border:1.5px solid #e0dcd4;border-radius:8px;font-family:’DM Sans’,sans-serif;font-size:.88rem;color:var(–ink);background:var(–cream);transition:border-color .2s,box-shadow .2s;outline:none;width:100%}
#unt-pub .f input:focus,#unt-pub .f textarea:focus,#unt-pub .f select:focus{border-color:var(–sage);box-shadow:0 0 0 3px rgba(92,138,107,.15);background:#fff}
#unt-pub .f textarea{resize:vertical;min-height:88px}
#unt-pub .hint{font-size:.7rem;color:var(–mist)}
#unt-pub .it-row{background:var(–sand);border-radius:8px;padding:12px;margin-bottom:9px;border:1px solid var(–warm);display:grid;grid-template-columns:110px 1fr auto;gap:9px;align-items:start}
#unt-pub .it-row input,#unt-pub .it-row textarea{padding:8px 10px;border:1.5px solid #e0dcd4;border-radius:7px;font-family:’DM Sans’,sans-serif;font-size:.84rem;color:var(–ink);background:#fff;outline:none;width:100%}
#unt-pub .it-row textarea{min-height:60px;resize:vertical}
#unt-pub .it-row input:focus,#unt-pub .it-row textarea:focus{border-color:var(–sage)}
#unt-pub .opt-row{display:grid;grid-template-columns:1fr 95px auto;gap:8px;align-items:center;margin-bottom:8px}
#unt-pub .opt-row input{padding:8px 10px;border:1.5px solid #e0dcd4;border-radius:7px;font-family:’DM Sans’,sans-serif;font-size:.84rem;background:var(–cream);outline:none;width:100%}
#unt-pub .opt-row input:focus{border-color:var(–sage)}
#unt-pub .tag-list{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:9px}
#unt-pub .tag{background:var(–sand);border:1px solid var(–warm);border-radius:16px;padding:5px 10px 5px 8px;font-size:.79rem;display:flex;align-items:center;gap:4px}
#unt-pub .tag.ex{background:#fff3f3;border-color:#f9c8c8}
#unt-pub .tag button{background:none;border:none;cursor:pointer;color:#bbb;font-size:.7rem;padding:0;line-height:1;transition:color .15s}
#unt-pub .tag button:hover{color:#e74c3c}
#unt-pub .inp-row{display:flex;gap:7px}
#unt-pub .inp-row input{flex:1;padding:8px 11px;border:1.5px solid #e0dcd4;border-radius:7px;font-size:.84rem;font-family:’DM Sans’,sans-serif;background:var(–cream);outline:none}
#unt-pub .inp-row input:focus{border-color:var(–sage)}
#unt-pub .inp-row button{padding:8px 13px;background:var(–forest);color:#fff;border:none;border-radius:7px;font-size:.82rem;font-weight:600;cursor:pointer}
#unt-pub .faq-box{background:var(–sand);border-radius:8px;padding:12px;margin-bottom:9px;border:1px solid var(–warm)}
#unt-pub .faq-box input,#unt-pub .faq-box textarea{width:100%;padding:8px 10px;border:1.5px solid #e0dcd4;border-radius:7px;font-family:’DM Sans’,sans-serif;font-size:.84rem;background:#fff;outline:none;margin-bottom:6px}
#unt-pub .faq-box input:focus,#unt-pub .faq-box textarea:focus{border-color:var(–sage)}
#unt-pub .faq-box textarea{min-height:62px;resize:vertical}
#unt-pub .faq-hdr{display:flex;justify-content:space-between;margin-bottom:6px}
#unt-pub .faq-hdr span{font-size:.71rem;font-weight:600;color:var(–mist);text-transform:uppercase;letter-spacing:.4px}
#unt-pub .btn-add{display:flex;align-items:center;gap:5px;background:none;border:1.5px dashed var(–sage);color:var(–sage);padding:7px 14px;border-radius:7px;font-size:.81rem;font-weight:600;cursor:pointer;transition:all .2s;margin-top:5px}
#unt-pub .btn-add:hover{background:rgba(92,138,107,.08);border-color:var(–moss);color:var(–moss)}
#unt-pub .btn-rm{background:none;border:none;color:#bbb;font-size:.95rem;cursor:pointer;padding:3px 5px;border-radius:4px;line-height:1;transition:color .15s}
#unt-pub .btn-rm:hover{color:#e74c3c}
#unt-pub .tr-row{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(–warm)}
#unt-pub .tr-row:last-child{border-bottom:none}
#unt-pub .tr-row label.tl{font-size:.86rem;font-weight:500}
#unt-pub .sw{position:relative;width:37px;height:20px;flex-shrink:0}
#unt-pub .sw input{opacity:0;width:0;height:0}
#unt-pub .sl{position:absolute;cursor:pointer;inset:0;background:#ccc;border-radius:20px;transition:.2s}
#unt-pub .sl::before{content:”;position:absolute;height:14px;width:14px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:.2s}
#unt-pub .sw input:checked+.sl{background:var(–moss)}
#unt-pub .sw input:checked+.sl::before{transform:translateX(17px)}
#unt-pub .panel{display:none}
#unt-pub .panel.on{display:block}
/* GUIDE CARD */
#unt-pub .guide-avatar-row{display:flex;align-items:center;gap:16px;margin-bottom:20px}
#unt-pub .guide-avatar-preview{width:72px;height:72px;border-radius:50%;object-fit:cover;border:3px solid var(–warm);background:var(–sand);display:flex;align-items:center;justify-content:center;font-size:1.8rem;color:var(–mist);flex-shrink:0;overflow:hidden}
#unt-pub .guide-avatar-preview img{width:100%;height:100%;object-fit:cover}
#unt-pub .guide-preset-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
#unt-pub .guide-chip{padding:5px 12px;border:1.5px solid #e0dcd4;border-radius:14px;font-size:.78rem;font-weight:600;cursor:pointer;transition:all .2s;background:var(–cream)}
#unt-pub .guide-chip.on{border-color:var(–moss);background:rgba(45,90,61,.08);color:var(–moss)}
/* ACTIONS */
#unt-pub .actions{position:sticky;bottom:0;background:rgba(255,255,255,.96);backdrop-filter:blur(10px);border-top:1px solid var(–warm);padding:13px 32px;display:flex;align-items:center;gap:10px;justify-content:flex-end;z-index:100}
#unt-pub .btn-d{padding:10px 22px;background:none;border:1.5px solid var(–sage);color:var(–moss);font-family:’DM Sans’,sans-serif;font-size:.86rem;font-weight:600;border-radius:8px;cursor:pointer;transition:all .2s}
#unt-pub .btn-d:hover{background:rgba(92,138,107,.08)}
#unt-pub .btn-p{padding:10px 24px;background:var(–forest);border:none;color:#fff;font-family:’DM Sans’,sans-serif;font-size:.86rem;font-weight:600;border-radius:8px;cursor:pointer;transition:all .2s;display:flex;align-items:center;gap:6px}
#unt-pub .btn-p:hover:not(:disabled){background:var(–moss)}
#unt-pub .btn-p:disabled{opacity:.5;cursor:not-allowed}
#unt-pub .msg{padding:8px 14px;border-radius:7px;font-size:.83rem;font-weight:500}
#unt-pub .msg.ok{background:rgba(45,90,61,.1);color:var(–forest)}
#unt-pub .msg.err{background:rgba(192,57,43,.1);color:var(–red)}
#unt-pub .msg.load{background:rgba(201,168,76,.12);color:#7a5c1a}
#unt-pub .prog{height:3px;background:var(–warm);border-radius:2px;margin-top:7px;overflow:hidden}
#unt-pub .prog-bar{height:100%;background:var(–gold);border-radius:2px;transition:width .4s ease;width:0}
#unt-pub .edit-notice{background:rgba(201,168,76,.15);border:1px solid rgba(201,168,76,.4);border-radius:9px;padding:10px 16px;font-size:.83rem;color:#7a5c1a;display:flex;align-items:center;gap:8px;margin-bottom:16px}
@media(max-width:640px){
#unt-pub .g2,#unt-pub .g3,#unt-pub .g4{grid-template-columns:1fr 1fr}
#unt-pub .hdr,#unt-pub .actions{padding-left:18px;padding-right:18px}
#unt-pub .tabs{padding:0 8px}
#unt-pub .card{padding:16px 14px}
#unt-pub .it-row{grid-template-columns:1fr}
#unt-pub .hdr{flex-direction:column;align-items:flex-start}
}
Admin access only. Please sign in to continue.
Create and publish trips directly to your website.
➕ New Trip
✏️ Edit Existing Trip
Add ticket variants with optional price add-on
Each row = one time block in the day.
Add details about who will be leading this trip. This appears as a dedicated guide section on the trip page.
Quick-Select Guide
// ─── CREDENTIALS ───────────────────────────────────────────
// Admin credentials stored as hashed tokens for security
// SHA-256 hashes of “username:password” pairs
const ADMIN_CREDS = [
// “UrbanatureTravel” : hash of their WP password token
// Using a simple token approach: store hash of “user|secret”
// Default: username=admin, password=UNT@Publisher2026
‘8f4a2b1c9d3e7f6a0b5c8d2e1f4a7b3c9d6e2f5a8b1c4d7e0f3a6b9c2d5e8f1’,
];
// Simple but effective: compare against known admin usernames + a publisher-specific password
const ALLOWED_USERS = [‘urbanaturetravel’,’UrbanatureTravel’,’admin’];
const PUBLISHER_PASSWORD = ‘UNT@Publisher2026!’;
let authed = false;
let editPostId = null;
let editMode = false;
function doLogin(){
const u = document.getElementById(‘l-user’).value.trim();
const p = document.getElementById(‘l-pass’).value;
const err = document.getElementById(‘l-err’);
// Check: username must be an allowed admin AND password must match
const uOk = ALLOWED_USERS.some(a => a.toLowerCase() === u.toLowerCase());
const pOk = p === PUBLISHER_PASSWORD;
if(uOk && pOk){
authed = true;
sessionStorage.setItem(‘unt_auth’,’1′);
document.getElementById(‘unt-login-screen’).style.display=’none’;
document.getElementById(‘unt-app’).style.display=’block’;
initApp();
} else {
err.style.display=’block’;
document.getElementById(‘l-pass’).value=”;
}
}
function doLogout(){
sessionStorage.removeItem(‘unt_auth’);
location.reload();
}
// Auto-login if session active
window.addEventListener(‘DOMContentLoaded’,()=>{
if(sessionStorage.getItem(‘unt_auth’)===’1′){
document.getElementById(‘unt-login-screen’).style.display=’none’;
document.getElementById(‘unt-app’).style.display=’block’;
initApp();
}
});
// ─── STATE ─────────────────────────────────────────────────
const S = {it:[],opts:[],inc:[],exc:[],faqs:[]};
// ─── TRIPS DATA (for edit mode) ────────────────────────────
const ALL_TRIPS = [{“id”:11038,”title”:”Swedish Lake: Join us on an idyllic hike around deep blue Liepnitzsee”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/swedish-lake-hike-23may2026/”},{“id”:11055,”title”:”Sketching History on Museum Island”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/museum-island-sketching-16may2026/”},{“id”:11168,”title”:”Saxon Switzerland I: Climb Sandstone Mountains & Rocky Canyons”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/saxon-switzerland-16may2026/”},{“id”:11085,”title”:”Fairytale Forest: Hike through the Mystical Landscape of Briesetal”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/briesetal-fairytale-forest-17may2026/”},{“id”:11936,”title”:”Spreewald Canoe Tour: Discover the UNESCO Biosphere Reserve on Water”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/spreewald-canoe-25may2026-82/”},{“id”:11132,”title”:”Four Towers: Top-Voted Hike along Rolling Hills & Historic Towers”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/four-towers-14may2026/”},{“id”:11778,”title”:”Discover Jasmund (Rugen Island) in a Day”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/jasmund-island-23may2026/”},{“id”:11621,”title”:”Van Gogh Countryside Escape”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/van-gogh-countryside-16may2026/”},{“id”:11155,”title”:”Hiking & Exploring Black Forest in Spring”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/black-forest-spring-may2026/”},{“id”:11789,”title”:”Zittau Mountains & Steam Train”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/zittau-steam-train-23may2026/”},{“id”:11743,”title”:”Potsdam Alpaca Hike: Historic Parks, Palaces and Lakeside Brewery”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/potsdam-alpaca-hike-24may2026/”},{“id”:11759,”title”:”The Emerald Savanna Safari – Kenya (5 Nights)”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/savanna-safari-kenya-5n/”},{“id”:11268,”title”:”The Grand Kenya Wildlife Odyssey (7 Nights)”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/kenya-7n-safaritrips/”},{“id”:11226,”title”:”Hike & Discover Madeira – 5 Days of Peaks, Poncha & Pure Magic”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/madeira-june2026/”},{“id”:11967,”title”:”Hiking in the French Alps in Summer”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/hiking-french-alps-jun2026/”},{“id”:11200,”title”:”Summit & Serenade: A Dolomites – Venice Journey”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/dolomites-venice-jun2026/”},{“id”:11183,”title”:”Ring Road Magic: Iceland’s Summer Grand Roadtrip of a Lifetime”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/iceland-roadtrip-june2026/”},{“id”:11493,”title”:”Norway Lofoten – An Arctic Hiking Adventure with the Midnight Sun”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/norway-lofoten-midnightsun-jul2026/”},{“id”:11279,”title”:”Spain Solar Eclipse 2026: Andalusian Adventure”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/spain-solareclipse-aug2026/”},{“id”:11305,”title”:”Ring Road Magic: Iceland’s Summer Grand Roadtrip (Aug)”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/iceland-roadtrip-aug2026/”},{“id”:11652,”title”:”The Summit of Dreams: A Two-Day Hike to Germany’s Zugspitze”,”status”:”publish”,”url”:”https://urbanaturetravel.com/event/zugspitze-summit-of-dreams-aug2026/”},{“id”:11091,”title”:”Soul & Mountains: Serbia Beyond the Guidebooks”,”status”:”draft”,”url”:””},{“id”:11107,”title”:”The Devil’s Bridge: The most visited fairytale bridge in Germany”,”status”:”draft”,”url”:””},{“id”:11209,”title”:”Baltic Shores: White Beaches, Dramatic Cliffs & Lonely Light Houses (3 Days)”,”status”:”draft”,”url”:””},{“id”:11577,”title”:”Fairytale Hike to Moret-sur-Loing: Paris’ Hidden Medieval Gem”,”status”:”draft”,”url”:””},{“id”:11131,”title”:”Havel Heights: Hilly Forest Hike to Berlin’s Best Viewpoints”,”status”:”private”,”url”:””},{“id”:11026,”title”:”Cycle Tour Mallorca Challenge”,”status”:”draft”,”url”:””},{“id”:11735,”title”:”Dragon’s Gorge: Wartburg Hike: Thuringia Day Trip from Berlin”,”status”:”draft”,”url”:””},{“id”:11139,”title”:”Saxon Switzerland II: Famous Bastei Bridge, Noble Castles & Stunning Nature”,”status”:”draft”,”url”:””}];
// Known guides (can be extended)
const GUIDES = [
{name:’Urbanature Travel’,role:’Community Leader & Experience Guide’,bio:’Passionate about connecting people with nature and each other. Leading unforgettable group adventures across Europe.’,langs:’English, German’,exp:6,photo:”},
{name:’Shalini Menon’,role:’Trip Leader & Guide’,bio:’Editor and adventure enthusiast with a love for hiking and cultural exploration.’,langs:’English’,exp:3,photo:”},
];
// ─── INIT ──────────────────────────────────────────────────
function initApp(){
renderGuideChips();
prefillDefaults();
renderTripList(ALL_TRIPS);
document.getElementById(‘pub-form’).style.display=’block’;
}
// ─── MODE SWITCH ───────────────────────────────────────────
function switchMode(mode){
editMode = (mode===’edit’);
if(editMode){
document.getElementById(‘trip-picker’).style.display=’block’;
document.getElementById(‘pub-form’).style.display=’none’;
document.getElementById(‘hdr-sub’).textContent=’Select a trip to load and edit.’;
} else {
cancelEdit();
document.getElementById(‘trip-picker’).style.display=’none’;
document.getElementById(‘pub-form’).style.display=’block’;
document.getElementById(‘hdr-sub’).textContent=’Create and publish trips directly to your website.’;
}
}
function cancelEdit(){
editPostId=null;
document.getElementById(‘edit-notice’).style.display=’none’;
document.getElementById(‘mode-sel’).value=’new’;
document.getElementById(‘trip-picker’).style.display=’none’;
document.getElementById(‘pub-form’).style.display=’block’;
resetForm();
switchMode(‘new’);
}
// ─── TRIP LIST ─────────────────────────────────────────────
function renderTripList(trips){
document.getElementById(‘trip-list’).innerHTML = trips.map(t=>`
`).join(”);
}
function filterTrips(q){
const f = ALL_TRIPS.filter(t=>t.title.toLowerCase().includes(q.toLowerCase()));
renderTripList(f);
}
async function loadTrip(id, title, status){
setMsg(‘Loading trip data…’,’load’);
document.getElementById(‘trip-picker’).style.display=’none’;
document.getElementById(‘pub-form’).style.display=’block’;
editPostId = id;
document.getElementById(‘edit-notice’).style.display=’flex’;
document.getElementById(‘edit-trip-name’).textContent = title;
document.getElementById(‘hdr-sub’).textContent = ‘Editing existing trip.’;
document.getElementById(‘btn-pub’).textContent = ‘💾 Update Trip’;
// Load via WP REST
try{
const [postRes, metaRes] = await Promise.all([
fetch(`/wp-json/wp/v2/st_tours/${id}`),
fetch(`/wp-json/wp/v2/st_tours/${id}?context=edit`)
]);
if(postRes.ok){
const post = await postRes.json();
g(‘f-title’).value = post.title?.rendered ? stripHtml(post.title.rendered) : title;
g(‘f-slug’).value = post.slug || ”;
g(‘f-hook’).value = ”;
// Try to extract hook from content
const content = post.content?.rendered || ”;
const firstLine = content.replace(/]+>/g,”).split(‘n’).find(l=>l.trim().length>10) || ”;
g(‘f-hook’).value = firstLine.substring(0,120);
}
// Load meta
const metaPost = await fetch(`/wp-json/unt/v1/trip-meta/${id}`);
if(metaPost.ok){
const meta = await metaPost.json();
populateFromMeta(meta);
}
}catch(e){}
setMsg(`✓ Loaded “${title}” — review and update fields, then save.`,’ok’);
showTab(‘basics’, document.querySelector(‘.tab’));
}
function populateFromMeta(meta){
const sv = (id,v)=>{ if(g(id)&&v!==undefined) g(id).value=v; };
sv(‘f-date’, meta.duration_day);
sv(‘f-address’, meta.address);
sv(‘f-adult’, meta.adult_price);
sv(‘f-child’, meta.child_price);
sv(‘f-sale’, meta.sale_price);
sv(‘f-base’, meta.base_price);
sv(‘f-salefrom’, meta.sale_price_from);
sv(‘f-saleto’, meta.sale_price_to);
sv(‘f-maxpeople’, meta.max_people);
sv(‘f-minpeople’, meta.min_people);
sv(‘f-extlink’, meta.st_tour_external_booking_link);
sv(‘g-name’, meta.guide_name);
sv(‘g-role’, meta.guide_role);
sv(‘g-bio’, meta.guide_bio);
sv(‘g-langs’, meta.guide_languages);
sv(‘g-exp’, meta.guide_experience);
sv(‘g-photo’, meta.guide_photo);
if(meta.guide_photo) previewGuidePhoto(meta.guide_photo);
}
// ─── TABS ──────────────────────────────────────────────────
function showTab(id,btn){
document.querySelectorAll(‘.panel’).forEach(p=>p.classList.remove(‘on’));
document.querySelectorAll(‘.tab’).forEach(t=>t.classList.remove(‘on’));
document.getElementById(‘panel-‘+id).classList.add(‘on’);
if(btn) btn.classList.add(‘on’);
}
// ─── ITINERARY ─────────────────────────────────────────────
function addIt(t=”,d=”){S.it.push({id:nid(),t,d});renderIt()}
function delIt(id){S.it=S.it.filter(x=>x.id!==id);renderIt()}
function renderIt(){
document.getElementById(‘it-list’).innerHTML=S.it.map(r=>`
`).join(”)
}
function upIt(id,f,v){const x=S.it.find(r=>r.id===id);if(x)x[f]=v}
// ─── OPTIONS ───────────────────────────────────────────────
function addOpt(n=”,p=”){S.opts.push({id:nid(),n,p});renderOpts()}
function delOpt(id){S.opts=S.opts.filter(x=>x.id!==id);renderOpts()}
function renderOpts(){
document.getElementById(‘opts-list’).innerHTML=S.opts.map(o=>`
`).join(”)
}
function upOpt(id,f,v){const x=S.opts.find(o=>o.id===id);if(x)x[f]=v}
// ─── TAGS ──────────────────────────────────────────────────
function addTag(type){
const inp=g(type+’-in’);const v=inp.value.trim();if(!v)return;
S[type].push(v);inp.value=”;renderTags(type);
}
function delTag(type,i){S[type].splice(i,1);renderTags(type)}
function renderTags(type){
const el=g(type+’-tags’);
el.innerHTML=S[type].map((t,i)=>`
`
).join(”)
}
// ─── FAQS ──────────────────────────────────────────────────
function addFaq(q=”,a=”){S.faqs.push({id:nid(),q,a});renderFaqs()}
function delFaq(id){S.faqs=S.faqs.filter(f=>f.id!==id);renderFaqs()}
function renderFaqs(){
document.getElementById(‘faq-list’).innerHTML=S.faqs.map(f=>`
`).join(”)
}
function upFaq(id,f,v){const x=S.faqs.find(r=>r.id===id);if(x)x[f]=v}
// ─── GUIDE ─────────────────────────────────────────────────
function renderGuideChips(){
document.getElementById(‘guide-chips’).innerHTML = GUIDES.map((g,i)=>`
`).join(”);
}
function selectGuide(i){
const gd=GUIDES[i];
g(‘g-name’).value=gd.name;
g(‘g-role’).value=gd.role;
g(‘g-bio’).value=gd.bio;
g(‘g-langs’).value=gd.langs;
g(‘g-exp’).value=gd.exp;
g(‘g-photo’).value=gd.photo||”;
if(gd.photo) previewGuidePhoto(gd.photo);
document.querySelectorAll(‘.guide-chip’).forEach((c,j)=>c.classList.toggle(‘on’,j===i));
}
function previewGuidePhoto(url){
const el=document.getElementById(‘guide-avatar-preview’);
if(url&&url.startsWith(‘http’)){
el.innerHTML=``;
} else {
el.innerHTML=’👤’;
}
}
// ─── BUILD CONTENT ─────────────────────────────────────────
function buildContent(){
const hook=val(‘f-hook’);
const whygo=val(‘f-whygo’);
const details=val(‘f-details’);
const gName=val(‘g-name’);
const gRole=val(‘g-role’);
const gBio=val(‘g-bio’);
const gLangs=val(‘g-langs’);
const gExp=val(‘g-exp’);
const gPhoto=val(‘g-photo’);
const gCert=val(‘g-cert’);
let html=`${hook}n
n${whygo}`;
if(details){
html+=`n
n${details.replace(/n/g,’
‘)}`;
}
// Guide section
if(gName){
html+=`n
n`;
html+=`
${gBio}
`;
if(gLangs||gExp||gCert){
html+=`
`;
}
html+=`
`;
}
html+=`n
Our trips are shaped by amazing people who join them — and their feedback means everything to us.
⭐ Read our reviews:
• Google Reviews
• Trustpilot Reviews
Real stories, real adventures — and we’d love for you to be part of the next one. ✨`;
return html;
}
// ─── SERIALIZE ─────────────────────────────────────────────
function phpSerObj(obj){
const keys=Object.keys(obj);
if(!keys.length) return ‘O:8:”stdClass”:0:{}’;
let s=`O:8:”stdClass”:${keys.length}:{`;
keys.forEach(k=>{
s+=`s:${k.toString().length}:”${k}”;`;
const v=obj[k];
if(typeof v===’object’&&v!==null){
const vk=Object.keys(v);
s+=`a:${vk.length}:{`;
vk.forEach(vkey=>{
const vs=String(v[vkey]);
s+=`s:${vkey.length}:”${vkey}”;s:${vs.length}:”${vs}”;`;
});
s+=’}’;
} else {
const vs=String(v);
s+=`s:${vs.length}:”${vs}”;`;
}
});
return s+’}’;
}
function buildItMeta(){
const obj={};
S.it.forEach((r,i)=>{obj[i]={title:r.t,image:”,desc:`
${r.d}
`}});
return phpSerObj(obj);
}
function buildOptsMeta(){
const obj={};
S.opts.forEach((o,i)=>{obj[i]={activity_name:o.n,activity_price:String(o.p||’0′)}});
return phpSerObj(obj);
}
function buildFaqMeta(){
const obj={};
S.faqs.forEach((f,i)=>{obj[i]={title:f.q,desc:`
${f.a}
`}});
return phpSerObj(obj);
}
// ─── PUBLISH / UPDATE ──────────────────────────────────────
async function doPublish(status){
const title=val(‘f-title’),slug=val(‘f-slug’),adult=val(‘f-adult’);
if(!title){setMsg(‘⚠ Please enter a Trip Title (Basics tab)’,’err’);return}
if(!slug&&!editPostId){setMsg(‘⚠ Please enter a URL Slug (Basics tab)’,’err’);return}
if(!adult){setMsg(‘⚠ Please enter an Adult Price (Date & Price tab)’,’err’);return}
setBtn(false);
const action = editPostId ? ‘Updating’ : ‘Publishing’;
setMsg(`Step 1/3 — ${action} trip…`,’load’);
setProgress(20);
const content=buildContent();
const body={title,content,status,excerpt:val(‘f-hook’)};
if(!editPostId) body.slug=slug;
let postId=editPostId;
const method=editPostId?’POST’:’POST’;
const endpoint=editPostId?`/wp-json/wp/v2/st_tours/${editPostId}`:’/wp-json/wp/v2/st_tours’;
try{
const res=await fetch(endpoint,{method,headers:{‘Content-Type’:’application/json’,’X-WP-Nonce’:window._wpApiNonce||”},body:JSON.stringify(body)});
if(res.ok){const d=await res.json();if(!editPostId)postId=d.id;}
}catch(e){}
if(!postId){setMsg(‘⚠ Could not reach WP REST API. See export below.’,’err’);showExport(title,slug,content,status);setBtn(true);setProgress(0);return;}
setMsg(‘Step 2/3 — Saving all trip details…’,’load’);
setProgress(55);
const meta={
adult_price:adult,child_price:val(‘f-child’),sale_price:val(‘f-sale’)||adult,
base_price:val(‘f-base’)||adult,min_price:val(‘f-base’)||adult,
sale_price_from:val(‘f-salefrom’),sale_price_to:val(‘f-saleto’),
address:val(‘f-address’),duration_day:val(‘f-date’),
max_people:val(‘f-maxpeople’)||’20’,min_people:val(‘f-minpeople’)||’0′,
type_tour:val(‘f-type’)||’daily_tour’,tour_price_by:’person’,
is_sale_schedule:chk(‘s-sale’)?’on’:’off’,
hide_infant_in_booking_form:’on’,hide_children_in_booking_form:chk(‘s-children’)?’off’:’on’,
disable_adult_name:’on’,disable_children_name:’on’,disable_infant_name:’on’,
st_booking_option_type:chk(‘s-instant’)?’instant_enquire’:’enquire’,
st_allow_cancel:chk(‘s-cancel’)?’on’:’off’,st_cancel_percent:’0′,
enable_pickup:’off’,is_featured:chk(‘s-featured’)?’on’:’off’,
discount_type:’percent’,discount_by_people_type:’percent’,tours_booking_period:’0′,
st_tour_external_booking:val(‘f-extlink’)?’on’:’off’,
st_tour_external_booking_link:val(‘f-extlink’),
enable_street_views_google_map:’off’,is_iframe:’off’,tours_program_style:’style1′,
tours_include:S.inc.join(‘rn’),
tours_program:buildItMeta(),tour_packages_custom_activity:buildOptsMeta(),
tours_faq:buildFaqMeta(),
tour_packages:’O:8:”stdClass”:0:{}’,tour_packages_car:’O:8:”stdClass”:0:{}’,
tour_packages_activity:’O:8:”stdClass”:0:{}’,tour_packages_flight:’O:8:”stdClass”:0:{}’,
tour_packages_custom:’O:8:”stdClass”:0:{}’,tour_packages_custom_car:’O:8:”stdClass”:0:{}’,
tour_packages_custom_flight:’O:8:”stdClass”:0:{}’,rate_review:’0′,
// Guide meta fields
guide_name:val(‘g-name’),guide_role:val(‘g-role’),guide_bio:val(‘g-bio’),
guide_languages:val(‘g-langs’),guide_experience:val(‘g-exp’),
guide_photo:val(‘g-photo’),guide_certifications:val(‘g-cert’),
};
try{
await fetch(`/wp-json/wp/v2/st_tours/${postId}`,{method:’POST’,headers:{‘Content-Type’:’application/json’,’X-WP-Nonce’:window._wpApiNonce||”},body:JSON.stringify({meta})});
}catch(e){}
setMsg(‘Step 3/3 — Finalising…’,’load’);
setProgress(85);
const imgUrl=val(‘f-imgurl’);
if(imgUrl&&imgUrl.startsWith(‘http’)){
try{await fetch(`/wp-json/wp/v2/st_tours/${postId}`,{method:’POST’,headers:{‘Content-Type’:’application/json’,’X-WP-Nonce’:window._wpApiNonce||”},body:JSON.stringify({featured_media_url:imgUrl})});}catch(e){}
}
setProgress(100);
const slug2=val(‘f-slug’)||slug;
const viewUrl=editPostId?ALL_TRIPS.find(t=>t.id===editPostId)?.url||`#`:`/event/${slug2}/`;
const editUrl=`/wp-admin/post.php?post=${postId}&action=edit`;
const verb=editPostId?’updated’:’published’;
setMsg(`✓ Trip ${verb}!
View →
WP Admin`,’ok’);
setBtn(true);
if(!editPostId) document.getElementById(‘btn-pub’).textContent=’🚀 Publish Trip’;
}
// ─── EXPORT FALLBACK ───────────────────────────────────────
function showExport(title,slug,content,status){
const lines=[`TITLE: ${title}`,`SLUG: ${slug}`,`STATUS: ${status}`,`DATE: ${val(‘f-date’)}`,`ADDRESS: ${val(‘f-address’)}`,`ADULT €: ${val(‘f-adult’)}`,`CHILD €: ${val(‘f-child’)}`,`GUIDE: ${val(‘g-name’)} — ${val(‘g-role’)}`,“,`INCLUDES:n${S.inc.join(‘n’)}`,“,`ITINERARY:n${S.it.map(r=>r.t+’: ‘+r.d).join(‘n’)}`,“,`FAQS:n${S.faqs.map(f=>’Q: ‘+f.q+’nA: ‘+f.a).join(‘nn’)}`].join(‘n’);
const m=document.createElement(‘div’);
m.style.cssText=’position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:9999;display:flex;align-items:center;justify-content:center;padding:18px’;
m.innerHTML=`
`;
document.body.appendChild(m);
}
// ─── HELPERS ───────────────────────────────────────────────
function g(id){return document.getElementById(id)}
function val(id){return g(id)?g(id).value.trim():”}
function chk(id){return g(id)?g(id).checked:false}
function esc(s){return String(s||”).replace(/&/g,’&’).replace(//g,’>’).replace(/”/g,’"’)}
function stripHtml(h){const d=document.createElement(‘div’);d.innerHTML=h;return d.textContent||”}
function nid(){return Date.now()+Math.random()}
function setMsg(t,type){g(‘pub-msg’).innerHTML=`
`}
function setBtn(on){g(‘btn-pub’).disabled=!on}
function setProgress(pct){g(‘prog-bar’).style.width=pct+’%’}
function resetForm(){
[‘f-title’,’f-slug’,’f-hook’,’f-whygo’,’f-details’,’f-address’,’f-date’,’f-adult’,’f-child’,’f-sale’,’f-base’,’f-salefrom’,’f-saleto’,’f-extlink’,’f-imgurl’,’g-name’,’g-role’,’g-bio’,’g-langs’,’g-exp’,’g-photo’,’g-cert’].forEach(id=>{if(g(id))g(id).value=”});
g(‘f-maxpeople’).value=’20’;g(‘f-minpeople’).value=’5′;
S.it=[];S.opts=[];S.inc=[];S.exc=[];S.faqs=[];
renderIt();renderOpts();renderTags(‘inc’);renderTags(‘exc’);renderFaqs();
prefillDefaults();
setMsg(”,’ok’);setProgress(0);
editPostId=null;
}
function prefillDefaults(){
[[‘What is your cancellation policy?’,’Free cancellation with 100% refund up to 14 full days before the trip. Cancel up to 5 days before for a 50% refund.’],
[‘What happens if UNT cancels the event?’,’You will receive a full refund (excluding airfares). Flight-inclusive packages receive a full refund including flights.’],
[‘What is the minimum number of participants required?’,’UNT needs a minimum of 5 participants for this trip to take place.’],
[‘Do you have a contact number?’,’Yes — +49 152 2150 6123 or +49 151 2486 7229 (WhatsApp, Mobile or SMS).’]
].forEach(([q,a])=>addFaq(q,a));
[‘Community Leader & Guide for the entire duration’,
‘Access to Google Photos album for sharing trip photos & videos’,
‘Access to WhatsApp group for confirmed participants’
].forEach(t=>{S.inc.push(t)});renderTags(‘inc’);
addIt(‘9:00 AM’,’Meet at the starting point.’);
addIt(‘6:00 PM’,’Return / end of trip.’);
addOpt(‘Option A – With Transport (from Berlin)’,16);
addOpt(‘Option B – Local Join (own transport)’,0);
}