1a12fb870b
- New /developers/ page with API docs, SDKs, pricing, use cases - OpenAPI 3.0 spec for Orders, Missions, Photos, Analytics - Case study: Glasskiosken i Flatenbadet — complete ROI analysis - Updated /order/ with recurring missions and frequency dropdown
620 lines
24 KiB
HTML
620 lines
24 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="sv">
|
||
<head>
|
||
<meta charset="UTF-8"/>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||
<title>quiXzoom — Beställ ett uppdrag</title>
|
||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
|
||
<style>
|
||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||
:root {
|
||
--bg: #f2f2f7;
|
||
--surface: #ffffff;
|
||
--surface2: #f2f2f7;
|
||
--border: rgba(0,0,0,0.1);
|
||
--accent: #ff3b30;
|
||
--accent2: #34c759;
|
||
--blue: #007aff;
|
||
--text: #1c1c1e;
|
||
--text2: #6e6e73;
|
||
--font: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', sans-serif;
|
||
}
|
||
@media (prefers-color-scheme: dark) {
|
||
:root { --bg:#0a0a0f; --surface:#1c1c1e; --surface2:#2c2c2e; --border:rgba(255,255,255,0.08); --text:#f5f5f7; --text2:#8e8e93; }
|
||
}
|
||
body { background: var(--bg); color: var(--text); font-family: var(--font); min-height: 100vh; padding: 0; }
|
||
|
||
/* Header */
|
||
.header {
|
||
background: var(--surface); border-bottom: 1px solid var(--border);
|
||
padding: 16px 20px; display: flex; align-items: center; gap: 12px;
|
||
position: sticky; top: 0; z-index: 100;
|
||
}
|
||
.logo { font-size: 20px; font-weight: 700; letter-spacing: -0.5px; }
|
||
.logo span { color: var(--accent); }
|
||
.header-title { font-size: 15px; color: var(--text2); }
|
||
|
||
/* Layout */
|
||
.container { max-width: 680px; margin: 0 auto; padding: 24px 16px 48px; }
|
||
|
||
/* Section */
|
||
.section { background: var(--surface); border-radius: var(--radius-lg); padding: 20px; margin-bottom: 16px; }
|
||
.section-title { font-size: 17px; font-weight: 600; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
|
||
|
||
/* Form fields */
|
||
.field { margin-bottom: 16px; }
|
||
.field:last-child { margin-bottom: 0; }
|
||
.field-label { font-size: 13px; font-weight: 500; color: var(--text2); margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.3px; }
|
||
.field-input {
|
||
width: 100%; background: var(--surface2); border: 1.5px solid var(--border);
|
||
border-radius: var(--radius-md); padding: 12px 14px; font-size: 15px; color: var(--text);
|
||
font-family: var(--font); transition: border-color 0.15s;
|
||
}
|
||
.field-input:focus { outline: none; border-color: var(--blue); }
|
||
.field-input::placeholder { color: var(--text2); }
|
||
textarea.field-input { resize: vertical; min-height: 80px; }
|
||
select.field-input { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236e6e73' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; padding-right: 36px; }
|
||
|
||
/* Map picker */
|
||
#location-map { width: 100%; height: 220px; border-radius: var(--radius-md); overflow: hidden; margin-top: 10px; border: 1.5px solid var(--border); }
|
||
.location-addr { margin-top: 8px; font-size: 13px; color: var(--text2); display: flex; align-items: center; gap: 6px; }
|
||
.location-pin { color: var(--accent); font-size: 16px; }
|
||
|
||
/* Budget slider */
|
||
.slider-wrap { margin-top: 8px; }
|
||
.budget-display { font-size: 24px; font-weight: 700; color: var(--accent); margin-bottom: 10px; }
|
||
input[type="range"] {
|
||
-webkit-appearance: none; width: 100%; height: 4px; border-radius: var(--radius-sm);
|
||
background: linear-gradient(to right, var(--accent) 0%, var(--accent) var(--pct, 20%), var(--surface2) var(--pct, 20%), var(--surface2) 100%);
|
||
outline: none; cursor: pointer;
|
||
}
|
||
input[type="range"]::-webkit-slider-thumb {
|
||
-webkit-appearance: none; width: 22px; height: 22px; border-radius: var(--radius-full);
|
||
background: var(--accent); box-shadow: 0 2px 8px rgba(0,0,0,0.25); cursor: pointer;
|
||
}
|
||
.budget-labels { display: flex; justify-content: space-between; font-size: 11px; color: var(--text2); margin-top: 4px; }
|
||
|
||
/* Camera count */
|
||
.camera-selector { display: flex; align-items: center; gap: 14px; }
|
||
.count-btn {
|
||
width: 36px; height: 36px; border-radius: var(--radius-full); background: var(--surface2);
|
||
border: 1.5px solid var(--border); font-size: 20px; cursor: pointer; display: flex;
|
||
align-items: center; justify-content: center; color: var(--text); transition: background 0.1s;
|
||
}
|
||
.count-btn:hover { background: var(--border); }
|
||
.count-val { font-size: 22px; font-weight: 700; min-width: 36px; text-align: center; }
|
||
|
||
/* Type selector */
|
||
.type-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
|
||
.type-btn {
|
||
background: var(--surface2); border: 1.5px solid var(--border); border-radius: var(--radius-md);
|
||
padding: 12px 8px; text-align: center; cursor: pointer; transition: all 0.15s;
|
||
}
|
||
.type-btn:hover { border-color: var(--blue); }
|
||
.type-btn.active { background: rgba(0,122,255,0.1); border-color: var(--blue); }
|
||
.type-icon { font-size: 22px; margin-bottom: 4px; }
|
||
.type-label { font-size: 12px; font-weight: 500; }
|
||
|
||
/* Submit */
|
||
.submit-section { padding: 0 0 8px; }
|
||
.submit-btn {
|
||
width: 100%; padding: 16px; background: var(--accent); color: white; border: none;
|
||
border-radius: var(--radius-lg); font-size: 17px; font-weight: 600; cursor: pointer;
|
||
font-family: var(--font); transition: opacity 0.15s; display: flex; align-items: center; justify-content: center; gap: 8px;
|
||
}
|
||
.submit-btn:hover:not(:disabled) { opacity: 0.88; }
|
||
.submit-btn:disabled { opacity: 0.45; cursor: not-allowed; }
|
||
|
||
/* Confirmation */
|
||
.confirm-screen { display: none; text-align: center; padding: 40px 20px; }
|
||
.confirm-icon { font-size: 64px; margin-bottom: 16px; }
|
||
.confirm-title { font-size: 26px; font-weight: 700; letter-spacing: -0.5px; margin-bottom: 8px; }
|
||
.confirm-sub { font-size: 15px; color: var(--text2); margin-bottom: 28px; line-height: 1.5; }
|
||
.mission-id-box {
|
||
background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-lg);
|
||
padding: 16px; margin-bottom: 24px;
|
||
}
|
||
.mission-id-label { font-size: 12px; color: var(--text2); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
|
||
.mission-id-val { font-size: 22px; font-weight: 700; font-feature-settings: 'tnum'; letter-spacing: 2px; }
|
||
.track-btn {
|
||
display: inline-block; padding: 14px 32px; background: var(--blue); color: white;
|
||
border-radius: var(--radius-lg); font-size: 16px; font-weight: 600; text-decoration: none;
|
||
transition: opacity 0.15s;
|
||
}
|
||
.track-btn:hover { opacity: 0.88; }
|
||
@media (max-width: 640px) {
|
||
.hero h1 { font-size: 2rem !important; }
|
||
.hero p { font-size: 1rem !important; }
|
||
.card { padding: 1.5rem !important; }
|
||
.grid { grid-template-columns: 1fr !important; }
|
||
.btn { padding: 0.75rem 1.5rem !important; font-size: 1rem !important; }
|
||
}
|
||
/* QUIXZOOM STANDARD — Dark Theme */
|
||
:root {
|
||
--qz-bg: #0a0a0a;
|
||
--qz-surface: #111111;
|
||
--qz-surface-2: #1a1a1a;
|
||
--qz-border: rgba(255,255,255,0.08);
|
||
--qz-text: #e8e8e8;
|
||
--qz-text-dim: #a0a0a0;
|
||
--qz-text-muted: #6b6b6b;
|
||
--qz-blue: #007AFF;
|
||
--qz-blue-dark: #0056CC;
|
||
--qz-radius: 10px;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif;
|
||
background: var(--qz-bg);
|
||
color: var(--qz-text);
|
||
line-height: 1.6;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
|
||
/* Navigation */
|
||
.qz-nav {
|
||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
padding: 0 24px; height: 56px;
|
||
background: rgba(255,255,255,0.92);
|
||
backdrop-filter: blur(16px);
|
||
border-bottom: 1px solid var(--qz-border);
|
||
}
|
||
|
||
.qz-nav-logo { font-size: 18px; font-weight: 700; color: #fff; text-decoration: none; }
|
||
.qz-nav-links { display: flex; gap: 24px; list-style: none; }
|
||
.qz-nav-links a { font-size: 14px; color: var(--qz-text-dim); text-decoration: none; transition: color 0.2s; }
|
||
.qz-nav-links a:hover { color: #fff; }
|
||
|
||
/* Buttons */
|
||
.qz-btn {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
padding: 12px 24px; border-radius: var(--qz-radius);
|
||
font-size: 15px; font-weight: 600; text-decoration: none;
|
||
transition: all 0.2s; cursor: pointer; border: none;
|
||
}
|
||
|
||
.qz-btn-primary {
|
||
background: var(--qz-blue); color: #fff;
|
||
}
|
||
.qz-btn-primary:hover {
|
||
background: var(--qz-blue-dark); transform: translateY(-1px);
|
||
}
|
||
|
||
.qz-btn-ghost {
|
||
background: transparent; color: var(--qz-text);
|
||
border: 1px solid var(--qz-border);
|
||
}
|
||
.qz-btn-ghost:hover {
|
||
border-color: var(--qz-blue); color: var(--qz-blue);
|
||
}
|
||
|
||
/* Cards */
|
||
.qz-card {
|
||
background: var(--qz-surface);
|
||
border: 1px solid var(--qz-border);
|
||
border-radius: var(--qz-radius);
|
||
padding: 24px;
|
||
transition: transform 0.2s, border-color 0.2s;
|
||
}
|
||
.qz-card:hover {
|
||
transform: translateY(-2px);
|
||
border-color: rgba(0,122,255,0.3);
|
||
}
|
||
|
||
/* Footer */
|
||
.qz-footer {
|
||
border-top: 1px solid var(--qz-border);
|
||
padding: 40px 24px;
|
||
text-align: center;
|
||
color: var(--qz-text-dim);
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* Banner */
|
||
.qz-banner {
|
||
background: #001E50;
|
||
color: rgba(255,255,255,0.55);
|
||
text-align: center;
|
||
padding: 10px;
|
||
font-size: 12px;
|
||
}
|
||
.qz-banner a { color: rgba(255,255,255,0.8); text-decoration: none; }
|
||
|
||
@media (max-width: 768px) {
|
||
.qz-nav-links { display: none; }
|
||
}
|
||
</style>
|
||
|
||
<style id="wcag-contrast-enforcement">
|
||
/* AAMOS GLOBAL CONTRAST ENFORCEMENT — WCAG AA (4.5:1 minimum) */
|
||
/* Regel: Ingen text under 70% opacity. Aldrig. */
|
||
body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
|
||
/* Fix common low-contrast patterns */
|
||
[style*="rgba(60,60,67,0.4)"] { color: rgba(60,60,67,0.65) !important; }
|
||
[style*="rgba(60,60,67,0.3)"] { color: rgba(60,60,67,0.65) !important; }
|
||
[style*="rgba(255,255,255,0.4)"] { color: rgba(255,255,255,0.72) !important; }
|
||
[style*="rgba(255,255,255,0.3)"] { color: rgba(255,255,255,0.72) !important; }
|
||
[style*="opacity: 0.4"] { opacity: 0.72 !important; }
|
||
[style*="opacity: 0.3"] { opacity: 0.72 !important; }
|
||
@media (max-width: 640px) {
|
||
.hero h1 { font-size: 2rem !important; }
|
||
.hero p { font-size: 1rem !important; }
|
||
.card { padding: 1.5rem !important; }
|
||
.grid { grid-template-columns: 1fr !important; }
|
||
.btn { padding: 0.75rem 1.5rem !important; font-size: 1rem !important; }
|
||
}
|
||
/* QUIXZOOM STANDARD — Dark Theme */
|
||
:root {
|
||
--qz-bg: #0a0a0a;
|
||
--qz-surface: #111111;
|
||
--qz-surface-2: #1a1a1a;
|
||
--qz-border: rgba(255,255,255,0.08);
|
||
--qz-text: #e8e8e8;
|
||
--qz-text-dim: #a0a0a0;
|
||
--qz-text-muted: #6b6b6b;
|
||
--qz-blue: #007AFF;
|
||
--qz-blue-dark: #0056CC;
|
||
--qz-radius: 10px;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif;
|
||
background: var(--qz-bg);
|
||
color: var(--qz-text);
|
||
line-height: 1.6;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
|
||
/* Navigation */
|
||
.qz-nav {
|
||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
padding: 0 24px; height: 56px;
|
||
background: rgba(255,255,255,0.92);
|
||
backdrop-filter: blur(16px);
|
||
border-bottom: 1px solid var(--qz-border);
|
||
}
|
||
|
||
.qz-nav-logo { font-size: 18px; font-weight: 700; color: #fff; text-decoration: none; }
|
||
.qz-nav-links { display: flex; gap: 24px; list-style: none; }
|
||
.qz-nav-links a { font-size: 14px; color: var(--qz-text-dim); text-decoration: none; transition: color 0.2s; }
|
||
.qz-nav-links a:hover { color: #fff; }
|
||
|
||
/* Buttons */
|
||
.qz-btn {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
padding: 12px 24px; border-radius: var(--qz-radius);
|
||
font-size: 15px; font-weight: 600; text-decoration: none;
|
||
transition: all 0.2s; cursor: pointer; border: none;
|
||
}
|
||
|
||
.qz-btn-primary {
|
||
background: var(--qz-blue); color: #fff;
|
||
}
|
||
.qz-btn-primary:hover {
|
||
background: var(--qz-blue-dark); transform: translateY(-1px);
|
||
}
|
||
|
||
.qz-btn-ghost {
|
||
background: transparent; color: var(--qz-text);
|
||
border: 1px solid var(--qz-border);
|
||
}
|
||
.qz-btn-ghost:hover {
|
||
border-color: var(--qz-blue); color: var(--qz-blue);
|
||
}
|
||
|
||
/* Cards */
|
||
.qz-card {
|
||
background: var(--qz-surface);
|
||
border: 1px solid var(--qz-border);
|
||
border-radius: var(--qz-radius);
|
||
padding: 24px;
|
||
transition: transform 0.2s, border-color 0.2s;
|
||
}
|
||
.qz-card:hover {
|
||
transform: translateY(-2px);
|
||
border-color: rgba(0,122,255,0.3);
|
||
}
|
||
|
||
/* Footer */
|
||
.qz-footer {
|
||
border-top: 1px solid var(--qz-border);
|
||
padding: 40px 24px;
|
||
text-align: center;
|
||
color: var(--qz-text-dim);
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* Banner */
|
||
.qz-banner {
|
||
background: #001E50;
|
||
color: rgba(255,255,255,0.55);
|
||
text-align: center;
|
||
padding: 10px;
|
||
font-size: 12px;
|
||
}
|
||
.qz-banner a { color: rgba(255,255,255,0.8); text-decoration: none; }
|
||
|
||
@media (max-width: 768px) {
|
||
.qz-nav-links { display: none; }
|
||
}
|
||
</style>
|
||
<script src="i18n.js"></script>
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:title" content="quiXzoom — Beställ ett uppdrag">
|
||
<meta property="og:description" content="quiXzoom — Earn per Mission. No Platform Fee.">
|
||
<meta property="og:url" content="https://www.quixzoom.com/request-mission.html">
|
||
<meta property="og:image" content="https://www.quixzoom.com/images/mission-map.jpg">
|
||
<meta property="og:image:width" content="1200">
|
||
<meta property="og:image:height" content="630">
|
||
<meta property="og:image:alt" content="quiXzoom — request a mission in your area">
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<meta name="twitter:image" content="https://www.quixzoom.com/images/mission-map.jpg">
|
||
<meta name="twitter:title" content="quiXzoom — Beställ ett uppdrag">
|
||
<script type="module" src="https://auth.quixzoom.com/site-auth-snippet.js"></script>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="header">
|
||
<div class="logo">qui<span>X</span>zoom</div>
|
||
<div class="header-title">/ Beställ uppdrag</div>
|
||
</div>
|
||
|
||
<div class="container" id="form-container">
|
||
|
||
<!-- Location -->
|
||
<div class="section">
|
||
<div class="section-title"> Plats</div>
|
||
<div class="field">
|
||
<div class="field-label">Adress</div>
|
||
<input class="field-input" id="address" type="text" placeholder="Ange adress eller klicka på kartan…" oninput="updateAddress(this.value)"/>
|
||
</div>
|
||
<div id="location-map"></div>
|
||
<div class="location-addr">
|
||
<span class="location-pin"></span>
|
||
<span id="chosen-location">Klicka på kartan för att välja plats</span>
|
||
</div>
|
||
<input type="hidden" id="lat" value="7.9519"/>
|
||
<input type="hidden" id="lng" value="98.2849"/>
|
||
</div>
|
||
|
||
<!-- Mission details -->
|
||
<div class="section">
|
||
<div class="section-title"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H10M6 8H10M6 11H8" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg> Uppdragsdetaljer</div>
|
||
<div class="field">
|
||
<div class="field-label">Titel / Beskrivning av uppdrag</div>
|
||
<input class="field-input" id="title" type="text" placeholder="T.ex. Hotell-lobby fotografering…"/>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field-label">Vad ska fotograferas/filmas?</div>
|
||
<textarea class="field-input" id="description" placeholder="Beskriv detaljerat vad du vill att Zoomern ska fånga. Inkludera specifika vinklar, motiv eller krav."></textarea>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field-label">Typ av uppdrag</div>
|
||
<div class="type-grid">
|
||
<div class="type-btn active" data-type="photography" onclick="selectType(this)">
|
||
<div class="type-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="12" height="9" rx="2" stroke="#666" stroke-width="1.5"/><circle cx="8" cy="8.5" r="2.5" stroke="#666" stroke-width="1.5"/><path d="M5 4L6 2H10L11 4" stroke="#666" stroke-width="1.5"/></svg></div>
|
||
<div class="type-label">Foto</div>
|
||
</div>
|
||
<div class="type-btn" data-type="video" onclick="selectType(this)">
|
||
<div class="type-icon"></div>
|
||
<div class="type-label">Video</div>
|
||
</div>
|
||
<div class="type-btn" data-type="drone" onclick="selectType(this)">
|
||
<div class="type-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg></div>
|
||
<div class="type-label">Drone</div>
|
||
</div>
|
||
<div class="type-btn" data-type="livestream" onclick="selectType(this)">
|
||
<div class="type-icon"></div>
|
||
<div class="type-label">Livestream</div>
|
||
</div>
|
||
<div class="type-btn" data-type="360" onclick="selectType(this)">
|
||
<div class="type-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 8C2 11.3 4.7 14 8 14C10.5 14 12.7 12.5 13.7 10.3" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M14 8C14 4.7 11.3 2 8 2C5.5 2 3.3 3.5 2.3 5.7" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M13.5 7.5L14 10L11.5 9.5" stroke="#666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M2.5 8.5L2 6L4.5 6.5" stroke="#666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
|
||
<div class="type-label">360°</div>
|
||
</div>
|
||
<div class="type-btn" data-type="documentary" onclick="selectType(this)">
|
||
<div class="type-icon"></div>
|
||
<div class="type-label">Dokumentär</div>
|
||
</div>
|
||
</div>
|
||
<input type="hidden" id="mission-type" value="photography"/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Date & time -->
|
||
<div class="section">
|
||
<div class="section-title"> Datum & Tid</div>
|
||
<div class="field">
|
||
<div class="field-label">Startdatum och tid</div>
|
||
<input class="field-input" id="date-time" type="datetime-local"/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Cameras -->
|
||
<div class="section">
|
||
<div class="section-title"> Antal Zoomers</div>
|
||
<div class="field">
|
||
<div class="field-label">Önskat antal kameror / Zoomers</div>
|
||
<div class="camera-selector">
|
||
<button class="count-btn" onclick="changeCount(-1)">−</button>
|
||
<div class="count-val" id="camera-count">1</div>
|
||
<button class="count-btn" onclick="changeCount(1)">+</button>
|
||
<span style="color:var(--text2);font-size:13px;">Zoomer(s)</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Budget -->
|
||
<div class="section">
|
||
<div class="section-title"> Budget</div>
|
||
<div class="field">
|
||
<div class="field-label">Budget (SEK)</div>
|
||
<div class="slider-wrap">
|
||
<div class="budget-display" id="budget-display">5 000 kr</div>
|
||
<input type="range" id="budget-slider" min="500" max="50000" value="5000" step="500" oninput="updateBudget(this.value)"/>
|
||
<div class="budget-labels"><span>500 kr</span><span>50 000 kr</span></div>
|
||
</div>
|
||
<input type="hidden" id="budget" value="5000"/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Contact -->
|
||
<div class="section">
|
||
<div class="section-title"> Dina uppgifter</div>
|
||
<div class="field">
|
||
<div class="field-label">Namn</div>
|
||
<input class="field-input" id="contact-name" type="text" placeholder="För- och efternamn"/>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field-label">E-post</div>
|
||
<input class="field-input" id="contact-email" type="email" placeholder="din@email.com"/>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field-label">Telefon (valfritt)</div>
|
||
<input class="field-input" id="contact-phone" type="tel" placeholder="+46 70 123 45 67"/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Submit -->
|
||
<div class="submit-section">
|
||
<button class="submit-btn" id="submit-btn" onclick="submitMission()">
|
||
Skicka beställning
|
||
</button>
|
||
<div style="text-align:center;font-size:12px;color:var(--text2);margin-top:10px;">
|
||
Du bekräftar att uppdraget följer quiXzooms riktlinjer. Vi återkommer inom 30 minuter.
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Confirmation screen -->
|
||
<div class="confirm-screen" id="confirm-screen">
|
||
<div class="confirm-icon"></div>
|
||
<div class="confirm-title">Uppdrag beställt!</div>
|
||
<div class="confirm-sub">Vi har tagit emot din beställning och matchar dig med rätt Zoomer. Du får en bekräftelse via e-post inom kort.</div>
|
||
<div class="mission-id-box">
|
||
<div class="mission-id-label">Uppdragets ID</div>
|
||
<div class="mission-id-val" id="confirm-mission-id">—</div>
|
||
</div>
|
||
<a class="track-btn" id="track-link" href="#"> Följ uppdraget live</a>
|
||
</div>
|
||
|
||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||
<script>
|
||
// Map
|
||
const map = L.map('location-map', { center: [7.9519, 98.2849], zoom: 12 });
|
||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||
attribution: '© OpenStreetMap',
|
||
}).addTo(map);
|
||
|
||
let marker = L.marker([7.9519, 98.2849], { draggable: true }).addTo(map);
|
||
marker.on('dragend', e => {
|
||
const pos = e.target.getLatLng();
|
||
updateCoords(pos.lat, pos.lng);
|
||
});
|
||
|
||
map.on('click', e => {
|
||
marker.setLatLng(e.latlng);
|
||
updateCoords(e.latlng.lat, e.latlng.lng);
|
||
});
|
||
|
||
function updateCoords(lat, lng) {
|
||
document.getElementById('lat').value = lat.toFixed(6);
|
||
document.getElementById('lng').value = lng.toFixed(6);
|
||
document.getElementById('chosen-location').textContent = `${lat.toFixed(5)}°N, ${lng.toFixed(5)}°E`;
|
||
}
|
||
|
||
function updateAddress(addr) {
|
||
// Geocoding could be added here
|
||
document.getElementById('chosen-location').textContent = addr || 'Klicka på kartan för att välja plats';
|
||
}
|
||
|
||
// Type selector
|
||
function selectType(el) {
|
||
document.querySelectorAll('.type-btn').forEach(b => b.classList.remove('active'));
|
||
el.classList.add('active');
|
||
document.getElementById('mission-type').value = el.dataset.type;
|
||
}
|
||
|
||
// Camera count
|
||
let cameraCount = 1;
|
||
function changeCount(delta) {
|
||
cameraCount = Math.max(1, Math.min(10, cameraCount + delta));
|
||
document.getElementById('camera-count').textContent = cameraCount;
|
||
}
|
||
|
||
// Budget slider
|
||
function updateBudget(val) {
|
||
document.getElementById('budget').value = val;
|
||
document.getElementById('budget-display').textContent = parseInt(val).toLocaleString('sv-SE') + ' kr';
|
||
const pct = ((val - 500) / (50000 - 500)) * 100;
|
||
document.getElementById('budget-slider').style.setProperty('--pct', pct + '%');
|
||
}
|
||
updateBudget(5000);
|
||
|
||
// Default date/time (tomorrow 10:00)
|
||
const tomorrow = new Date();
|
||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||
tomorrow.setHours(10, 0, 0, 0);
|
||
document.getElementById('date-time').value = tomorrow.toISOString().slice(0, 16);
|
||
|
||
// Submit
|
||
async function submitMission() {
|
||
const title = document.getElementById('title').value.trim();
|
||
const contactName = document.getElementById('contact-name').value.trim();
|
||
const contactEmail = document.getElementById('contact-email').value.trim();
|
||
|
||
if (!title) { alert('Ange en titel för uppdraget.'); return; }
|
||
if (!contactEmail) { alert('Ange din e-postadress.'); return; }
|
||
|
||
const btn = document.getElementById('submit-btn');
|
||
btn.disabled = true;
|
||
btn.textContent = '⏳ Skickar…';
|
||
|
||
const payload = {
|
||
title,
|
||
lat: document.getElementById('lat').value,
|
||
lng: document.getElementById('lng').value,
|
||
description: document.getElementById('description').value,
|
||
type: document.getElementById('mission-type').value,
|
||
date_time: document.getElementById('date-time').value,
|
||
cameras: cameraCount,
|
||
budget: document.getElementById('budget').value,
|
||
customer: contactName || contactEmail,
|
||
contact_name: contactName,
|
||
contact_email: contactEmail,
|
||
contact_phone: document.getElementById('contact-phone').value,
|
||
};
|
||
|
||
try {
|
||
const r = await fetch('https://api.quixzoom.com/api/qz/missions', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(payload),
|
||
});
|
||
const d = await r.json();
|
||
if (d.ok && d.mission) {
|
||
document.getElementById('form-container').style.display = 'none';
|
||
document.getElementById('confirm-screen').style.display = 'block';
|
||
document.getElementById('confirm-mission-id').textContent = d.mission.id.toUpperCase();
|
||
document.getElementById('track-link').href = `/quixzoom/mission-map.html?mission=${d.mission.id}`;
|
||
} else {
|
||
btn.disabled = false;
|
||
btn.textContent = ' Skicka beställning';
|
||
alert(d.error || 'Något gick fel. Försök igen.');
|
||
}
|
||
} catch(e) {
|
||
btn.disabled = false;
|
||
btn.textContent = ' Skicka beställning';
|
||
alert('Nätverksfel. Kontrollera din anslutning.');
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|