Subversion Repositories SmartDukaan

Rev

Rev 36807 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Store Verification - SmartDukaan</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
    <style>
        body {
            background: #f5f6f8;
            font-family: 'Segoe UI', Roboto, sans-serif;
            color: #2b2b2b;
        }

        /* ---------- Top navbar ---------- */
        .top-nav {
            background: #fff;
            border-bottom: 1px solid #ececec;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
            padding: 14px 22px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            position: sticky;
            top: 0;
            z-index: 10;
        }

        .nav-home {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            color: #2b2b2b;
            font-weight: 600;
            font-size: 15px;
            text-decoration: none;
        }

        .nav-home:hover {
            color: #e1212a;
            text-decoration: none;
        }

        .nav-brand {
            display: inline-flex;
            align-items: center;
            text-decoration: none;
        }

        .nav-brand .brand-logo {
            height: 30px;
            width: auto;
            display: block;
        }

        .nav-help {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            font-size: 14px;
            color: #555;
            white-space: nowrap;
        }

        .nav-call {
            display: inline-flex;
            align-items: center;
            gap: 7px;
            text-decoration: none;
            color: #555;
        }

        .nav-call:hover {
            text-decoration: none;
        }

        .nav-call .call-word {
            color: #555;
            font-weight: 600;
        }

        .nav-help .phone {
            color: #e1212a;
            font-weight: 700;
        }

        @media (max-width: 575px) {
            .top-nav {
                padding: 10px 12px;
            }

            .nav-brand .brand-logo {
                height: 22px;
            }

            .nav-help .q-label,
            .nav-call .call-word {
                display: none;
            }

            .nav-call {
                gap: 5px;
            }

            .nav-help .phone {
                font-size: 13px;
            }

            .subhead {
                padding: 12px 14px 0;
            }
        }

        /* ---------- Sub-header home button ---------- */
        .subhead {
            padding: 16px 22px 0;
        }

        .btn-home {
            display: inline-flex;
            align-items: center;
            gap: 7px;
            background: #fff;
            color: #374151;
            border: 1px solid #e3e6ea;
            border-radius: 9px;
            padding: 8px 14px;
            font-size: 14px;
            font-weight: 600;
            text-decoration: none;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
        }

        .btn-home:hover {
            background: #f1f3f5;
            color: #374151;
            text-decoration: none;
        }

        /* ---------- Greeting ---------- */
        .greeting {
            text-align: center;
            font-size: 19px;
            color: #2b2b2b;
            margin: 26px 16px 18px;
        }

        /* ---------- Card ---------- */
        .geo-card {
            max-width: 720px;
            margin: 0 auto 36px;
            background: #fff;
            border-radius: 14px;
            box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
            overflow: hidden;
        }

        .card-head {
            padding: 22px 28px 18px;
            border-bottom: 1px solid #eee;
        }

        .card-head h4 {
            margin: 0 0 6px;
            font-weight: 700;
            font-size: 22px;
        }

        .card-head p {
            margin: 0;
            color: #6b7280;
            font-size: 14px;
        }

        .card-body-geo {
            padding: 26px 28px 28px;
        }

        @media (max-width: 575px) {
            .card-head, .card-body-geo {
                padding-left: 18px;
                padding-right: 18px;
            }
        }

        /* ---------- Step indicator + labels ---------- */
        .step-indicator {
            display: flex;
            justify-content: center;
            gap: 8px;
            margin-bottom: 10px;
        }

        .step-caption {
            text-align: center;
            font-size: 13px;
            font-weight: 600;
            color: #8b93a1;
            margin-bottom: 24px;
        }

        .step-dot {
            width: 28px;
            height: 5px;
            border-radius: 3px;
            background: #e3e6ea;
            transition: background 0.3s;
        }

        .step-dot.done {
            background: #22c55e;
        }

        .step-dot.current {
            background: #e1212a;
        }

        .section-label {
            font-size: 12px;
            font-weight: 700;
            letter-spacing: 0.6px;
            text-transform: uppercase;
            color: #8b93a1;
            margin-bottom: 12px;
        }

        .section-label .step-no {
            color: #e1212a;
        }

        /* Hindi line shown right under its English counterpart */
        .hindi {
            display: block;
            margin-top: 6px;
        }

        /* divider between the two steps on the same page */
        .step-divider {
            border: none;
            border-top: 1px solid #eef0f3;
            margin: 26px 0;
        }

        .step-section.locked {
            opacity: 0.6;
            pointer-events: none;
        }

        /* ---------- Form fields ---------- */
        .field-label {
            font-weight: 600;
            font-size: 15px;
            margin-bottom: 8px;
            display: block;
        }

        .field-label .req {
            color: #e1212a;
            margin-left: 2px;
        }

        .input-geo {
            width: 100%;
            background: #f1f3f5;
            border: 1px solid #f1f3f5;
            border-radius: 10px;
            padding: 13px 16px;
            font-size: 15px;
            transition: border-color 0.2s, background 0.2s;
        }

        .input-geo:focus {
            outline: none;
            background: #fff;
            border-color: #e1212a;
            box-shadow: 0 0 0 0.18rem rgba(225, 33, 42, 0.15);
        }

        .input-geo:disabled {
            color: #6b7280;
        }

        .mobile-row {
            position: relative;
        }

        .mobile-row .input-geo {
            width: 100%;
        }

        /* reserve room on the right for the in-field badge once verified */
        .input-geo.field-verified {
            padding-right: 104px;
        }

        .verified-pill {
            position: absolute;
            right: 8px;
            top: 50%;
            transform: translateY(-50%);
            display: none;
            align-items: center;
            gap: 6px;
            background: #e8f7ee;
            color: #16a34a;
            border-radius: 8px;
            padding: 6px 12px;
            font-size: 13px;
            font-weight: 600;
            white-space: nowrap;
        }

        .verified-pill.show {
            display: inline-flex;
            animation: badgeIn 0.4s ease both;
        }

        @keyframes badgeIn {
            from {
                opacity: 0;
                transform: translateY(-50%) translateX(8px);
            }
            to {
                opacity: 1;
                transform: translateY(-50%) translateX(0);
            }
        }

        /* soft reveal used for Step 2 appearing */
        @keyframes softReveal {
            from {
                opacity: 0;
                transform: translateY(10px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .reveal-soft {
            animation: softReveal 0.45s ease both;
        }

        /* the tick draws itself once the badge appears */
        .verified-pill svg path {
            stroke-dasharray: 24;
            stroke-dashoffset: 24;
        }

        .verified-pill.show svg path {
            animation: drawTick 0.45s ease-out 0.15s forwards;
        }

        @keyframes drawTick {
            to {
                stroke-dashoffset: 0;
            }
        }

        /* ---------- Success / thank-you ---------- */
        .success-wrap {
            min-height: 380px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            gap: 30px;
            padding: 44px 24px;
            text-align: center;
        }

        /* circle draws a full 360, then the tick ticks left -> right; repeats 3x every 4s */
        .success-circle {
            stroke-dasharray: 151;
            stroke-dashoffset: 151;
            animation: drawCircle 4s ease-in-out 3 forwards;
        }

        .success-check {
            stroke-dasharray: 32;
            stroke-dashoffset: 32;
            animation: drawCheck 4s ease-in-out 3 forwards;
        }

        @keyframes drawCircle {
            0% {
                stroke-dashoffset: 151;
            }
            25% {
                stroke-dashoffset: 0;
            }
            100% {
                stroke-dashoffset: 0;
            }
        }

        @keyframes drawCheck {
            0%, 25% {
                stroke-dashoffset: 32;
            }
            45% {
                stroke-dashoffset: 0;
            }
            100% {
                stroke-dashoffset: 0;
            }
        }

        .success-msg {
            margin: 0;
            font-size: 22px;
            font-weight: 700;
            color: #16a34a;
        }

        .success-msg-hi {
            margin: 6px 0 0;
            font-size: 16px;
            color: #4b5563;
        }

        /* ---------- Capture (combined location + photo) ---------- */
        .capture-help {
            color: #6b7280;
            font-size: 14px;
            margin: 0 0 16px;
        }

        /* "Take Store Photo" + "Close" controls row */
        .camera-controls {
            display: flex;
            gap: 10px;
            align-items: stretch;
            margin-bottom: 18px;
        }

        .btn-camera-open {
            flex: 1;
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: center;
            gap: 9px;
            background: #ef5a68;
            color: #fff;
            border: none;
            border-radius: 12px;
            padding: 15px 18px;
            cursor: pointer;
            box-shadow: 0 2px 10px rgba(239, 90, 104, 0.3);
        }

        .btn-camera-open .sep {
            opacity: 0.5;
            font-weight: 400;
        }

        .btn-camera-close {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
            background: #fff;
            color: #455a64;
            border: 1px solid #cfd6dd;
            border-radius: 12px;
            padding: 0 22px;
            font-size: 15px;
            font-weight: 600;
            cursor: pointer;
            white-space: nowrap;
        }

        .btn-camera-close .close-x {
            display: none;
        }

        /* mobile: collapse Close to a compact icon-only ✕ — placed AFTER the
           base rules above so it wins the cascade on small screens */
        @media (max-width: 575px) {
            .btn-camera-close {
                padding: 0 14px;
            }

            .btn-camera-close .close-label {
                display: none;
            }

            .btn-camera-close .close-x {
                display: block;
            }
        }

        .btn-camera-close:hover {
            background: #f1f3f5;
        }

        .btn-camera-open:hover {
            filter: brightness(0.96);
            color: #fff;
        }

        .btn-camera-open .label-en {
            font-size: 15px;
            font-weight: 700;
            line-height: 1.2;
        }

        .btn-camera-open .label-hi {
            font-size: 14px;
            font-weight: 500;
            opacity: 0.95;
        }

        .camera-wrap {
            position: relative;
            background: #000;
            border-radius: 12px;
            overflow: hidden;
            aspect-ratio: 4 / 3;
            margin-bottom: 14px;
        }

        .camera-wrap video,
        .camera-wrap img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            display: block;
        }

        .camera-wrap .cam-overlay {
            position: absolute;
            inset: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #fff;
            font-size: 13px;
            background: rgba(0, 0, 0, 0.55);
            text-align: center;
            padding: 16px;
        }

        .capture-row {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 16px;
            margin-bottom: 16px;
        }

        .btn-capture {
            background: #fff;
            color: #e1212a;
            border: 3px solid #e1212a;
            border-radius: 50%;
            width: 64px;
            height: 64px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        }

        .btn-capture:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .btn-capture .inner {
            width: 48px;
            height: 48px;
            border-radius: 50%;
            background: linear-gradient(135deg, #f7931e 0%, #e1212a 100%);
        }

        .btn-retake {
            background: transparent;
            border: 1px solid #b0bec5;
            color: #455a64;
            border-radius: 8px;
            padding: 9px 16px;
            cursor: pointer;
            font-size: 14px;
        }

        .capture-status {
            border-radius: 10px;
            padding: 12px 16px;
            font-size: 14px;
            margin-bottom: 18px;
            display: none;
        }

        .capture-status.ok {
            display: block;
            background: #e8f7ee;
            color: #16a34a;
        }

        .capture-status.err {
            display: block;
            background: #fce4ec;
            color: #c62828;
        }

        /* ---------- Buttons ---------- */
        .btn-primary-geo {
            background: #475569;
            color: #fff;
            border: none;
            border-radius: 10px;
            padding: 14px 24px;
            font-size: 16px;
            width: 100%;
            cursor: pointer;
            font-weight: 600;
            box-shadow: 0 2px 6px rgba(71, 85, 105, 0.20);
        }

        .btn-primary-geo:hover {
            background: #334155;
            color: #fff;
        }

        .btn-primary-geo:disabled {
            background: #b0bec5;
            box-shadow: none;
            cursor: not-allowed;
        }

        .btn-submit {
            background: #ef5a68;
            color: #fff;
            border: none;
            border-radius: 10px;
            padding: 15px 24px;
            font-size: 16px;
            width: 100%;
            cursor: pointer;
            font-weight: 700;
            box-shadow: 0 2px 10px rgba(239, 90, 104, 0.3);
        }

        .btn-submit:hover {
            filter: brightness(0.96);
            color: #fff;
        }

        .btn-submit:disabled {
            background: #f1a8b0;
            box-shadow: none;
            cursor: not-allowed;
        }

        .inline-err {
            background: #fce4ec;
            color: #c62828;
            border-radius: 8px;
            padding: 11px 14px;
            font-size: 14px;
            margin-bottom: 14px;
            display: none;
        }

        /* ---------- Consent ---------- */
        .consent-box {
            border: 1px solid #e3e6ea;
            background: #fafbfc;
            border-radius: 10px;
            padding: 16px 18px;
            margin-bottom: 22px;
            display: flex;
            gap: 12px;
            align-items: flex-start;
        }

        .consent-box input[type="checkbox"] {
            width: 18px;
            height: 18px;
            margin-top: 2px;
            flex-shrink: 0;
            cursor: pointer;
            accent-color: #e1212a;
        }

        .consent-box label {
            margin: 0;
            font-size: 13.5px;
            color: #4b5563;
            line-height: 1.5;
            cursor: pointer;
        }

        /* ---------- Spinner ---------- */
        .spinner {
            display: inline-block;
            width: 18px;
            height: 18px;
            border: 3px solid #fff;
            border-top-color: transparent;
            border-radius: 50%;
            animation: spin 0.8s linear infinite;
            vertical-align: middle;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        /* ---------- Footer ---------- */
        .footer-help {
            text-align: center;
            font-size: 14px;
            color: #4b5563;
            padding: 20px 16px 2px;
        }

        .footer-call {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            color: #e1212a;
            font-weight: 700;
            text-decoration: none;
            margin-left: 6px;
        }

        .footer-call:hover {
            text-decoration: none;
        }

        .geo-footer {
            text-align: center;
            color: #9aa1ab;
            font-size: 13px;
            padding: 8px 16px 30px;
            line-height: 1.6;
        }
    </style>
</head>
<body>

<!-- ===== Top navbar ===== -->
<div class="top-nav">
    <a href="https://smartdukaan.com/" class="nav-brand">
        <img src="https://images.smartdukaan.com/uploads/campaigns/image2026-06-10/smartdukaanlogo_singleline_june20261781071724758.png" alt="SmartDukaan" class="brand-logo">
    </a>
    <span class="nav-help">
        <span class="q-label">Any questions?</span>
        <a href="tel:1800270273" class="nav-call">
            <span class="call-word">Call</span>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#e1212a" stroke-width="2"
                 stroke-linecap="round" stroke-linejoin="round"><path
                    d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
            <span class="phone">1800 270 273</span>
        </a>
    </span>
</div>

<div class="subhead">
    <a href="https://smartdukaan.com/" class="btn-home">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
             stroke-linecap="round" stroke-linejoin="round">
            <path d="M3 9.5L12 3l9 6.5"/>
            <path
                    d="M5 10v10h14V10"/>
            <path d="M9 20v-6h6v6"/>
        </svg>
        Home
    </a>
</div>

    #if($leadName && $leadName.trim() != "")
    <p class="greeting">Greetings, <strong>$leadName</strong>!</p>
    #else
    <p class="greeting">Greetings!</p>
    #end

<div class="geo-card">
    <div class="card-head">
        <h4>Store Verification Form</h4>
        <p>Please provide your details for our Area Sales Manager to schedule a visit</p>
    </div>
    <div class="card-body-geo">
        <div class="step-indicator">
            <div class="step-dot current" id="dot1"></div>
            <div class="step-dot" id="dot2"></div>
        </div>
        <div class="step-caption" id="stepCaption">Step 1 of 2</div>

        <!-- ===== STEP 1: Mobile verification (stays on the page) ===== -->
        <div class="step-section" id="step1Section">
            <div class="section-label"><span class="step-no">Step 1.</span> Verify Mobile Number</div>
            <label class="field-label" for="mobileNumber">Mobile Number <span class="req">*</span></label>
            <div class="mobile-row">
                <input type="tel" class="input-geo" id="mobileNumber" maxlength="10"
                       placeholder="Enter 10-digit registered mobile number" autocomplete="off">
                <div class="verified-pill" id="mobileVerified">
                    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"
                         stroke-linecap="round" stroke-linejoin="round">
                        <path d="M4 12L9 17L20 6"/>
                    </svg>
                    Verified
                </div>
            </div>
            <div id="mobileError" class="inline-err mt-3"></div>
            <button class="btn-primary-geo mt-3" id="btnVerifyMobile">Verify &amp; Continue</button>
        </div>

        <!-- ===== STEP 2: Single combined capture — photo + auto location ===== -->
        <div class="step-section" id="step2Section" style="display:none;">
            <hr class="step-divider">
            <div class="section-label"><span class="step-no">Step 2.</span> Capture Your Store Photo</div>
            <p class="capture-help">
                Tap the button below to open your camera and take a live photo of your store front.
                Your location is recorded automatically with the photo.
                <span class="hindi">नीचे दिए गए बटन पर टैप करके कैमरा खोलें और अपनी दुकान के सामने की लाइव फोटो लें। आपकी लोकेशन फोटो के साथ अपने-आप रिकॉर्ड हो जाती है।</span>
            </p>

            <div class="camera-controls">
                <button type="button" class="btn-camera-open" id="btnOpenCamera">
                    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                         stroke-linecap="round" stroke-linejoin="round">
                        <path
                                d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
                        <circle
                                cx="12" cy="13" r="4"/>
                    </svg>
                    <span class="label-en">Take a Photo</span>
                    <span class="sep">|</span>
                    <span class="label-hi">दुकान की फोटो लें</span>
                </button>
                <button type="button" class="btn-camera-close" id="btnCloseCamera" style="display:none;"
                        aria-label="Close camera">
                    <svg class="close-x" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                         stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
                        <line x1="18" y1="6" x2="6"
                              y2="18"/>
                        <line x1="6" y1="6" x2="18" y2="18"/>
                    </svg>
                    <span class="close-label">Close</span>
                </button>
            </div>

            <div id="cameraStage" style="display:none;">
                <div class="camera-wrap" id="cameraWrap">
                    <video id="cameraVideo" autoplay playsinline muted></video>
                    <img id="photoPreview" alt="Captured photo" style="display:none;">
                    <div class="cam-overlay" id="cameraOverlay">Starting camera...</div>
                </div>

                <div class="capture-row">
                    <button type="button" class="btn-capture" id="btnCapture" disabled>
                        <span class="inner"></span>
                    </button>
                    <button type="button" class="btn-retake" id="btnRetake" style="display:none;">Retake</button>
                </div>
            </div>

            <div id="captureStatus" class="capture-status"></div>

            <!-- Consent -->
            <div class="consent-box">
                <input type="checkbox" id="consentCheck">
                <label for="consentCheck">
                    I acknowledge that the information provided above is accurate and I consent to SmartDukaan's
                    Area Sales Manager visiting my store at the location specified. I understand that this
                    information will be used for onboarding purposes only.
                    <span class="hindi">मैं स्वीकार करता/करती हूँ कि ऊपर दी गई जानकारी सही है, और मैं SmartDukaan के एरिया सेल्स मैनेजर को बताए गए स्थान पर मेरी दुकान पर आने की सहमति देता/देती हूँ। मुझे पता है कि इस जानकारी का उपयोग केवल ऑनबोर्डिंग के लिए किया जाएगा।</span>
                </label>
            </div>

            <div id="submitError" class="inline-err"></div>

            <input type="hidden" id="latitude" value="">
            <input type="hidden" id="longitude" value="">
            <input type="hidden" id="imageDocumentId" value="0">

            <button class="btn-submit" id="btnSubmit" disabled>Submit Details</button>
        </div>
    </div>
</div>

<div class="footer-help">
    Need help? Call
    <a href="tel:1800270273" class="footer-call">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
             stroke-linecap="round" stroke-linejoin="round">
            <path
                    d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/>
        </svg>
        1800 270 273
    </a>
</div>
<div class="geo-footer">
    &copy; 2026 SmartDukaan. All rights reserved.<br>
    Transforming mobile retail across India
</div>

<!-- Hidden canvas used to grab a still frame from the live video stream -->
<canvas id="captureCanvas" style="display:none;"></canvas>

<input type="hidden" id="leadId" value="$leadId">

<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script>
    var contextPath = "$rc.contextPath";
    var mediaStream = null; // live camera stream

    function markStepsAfterVerify() {
        $('#dot1').removeClass('current').addClass('done');
        $('#dot2').addClass('current');
        $('#stepCaption').text('Step 2 of 2');
    }

    // ===== STEP 1: Verify mobile against the lead record =====
    $('#btnVerifyMobile').click(function () {
        var mobile = $('#mobileNumber').val().trim();
        if (!mobile || mobile.length < 10) {
            $('#mobileError').text('Please enter a valid 10-digit mobile number').show();
            return;
        }
        var btn = $(this);
        btn.prop('disabled', true).html('<span class="spinner"></span> Verifying...');
        $('#mobileError').hide();

        $.ajax({
            url: contextPath + '/lead-geo/verify-mobile',
            method: 'POST',
            data: {leadId: $('#leadId').val(), mobileNumber: mobile},
            success: function (resp) {
                if (resp.response && resp.response.verified) {
                    // Lock step 1, reveal step 2 on the same page
                    $('#mobileNumber').prop('disabled', true).addClass('field-verified');
                    btn.hide();
                    $('#mobileVerified').addClass('show');
                    markStepsAfterVerify();
                    $('#step2Section').css('display', 'block').addClass('reveal-soft');
                } else {
                    $('#mobileError').text('Verification failed. Please try again.').show();
                    btn.prop('disabled', false).text('Verify & Continue');
                }
            },
            error: function (xhr) {
                var msg = 'Verification failed';
                try {
                    msg = JSON.parse(xhr.responseText).message || msg;
                } catch (e) {
                }
                $('#mobileError').text(msg).show();
                btn.prop('disabled', false).text('Verify & Continue');
            }
        });
    });

    $('#mobileNumber').keypress(function (e) {
        if (e.which === 13) $('#btnVerifyMobile').click();
    });

    // Open the camera only when the user taps "Take Store Photo".
    // The button stays visible and a "Close" button appears so the user
    // stays in control of the camera.
    $('#btnOpenCamera').click(function () {
        $('#cameraStage').show();
        $('#btnCloseCamera').show();
        startCamera();
    });

    $('#btnCloseCamera').click(function () {
        stopCamera();
        $('#cameraStage').hide();
        $(this).hide();
    });

    // ===== STEP 2: Live camera — live capture only (no gallery picker). =====
    // Geolocation is grabbed silently at the instant the photo is captured,
    // so location and photo are a single combined action.
    function startCamera() {
        var overlay = $('#cameraOverlay').show().text('Starting camera...');
        $('#photoPreview').hide();
        $('#cameraVideo').show();
        if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
            overlay.text('Your browser does not support live camera. Please open this link in Chrome/Safari on your phone.');
            return;
        }
        navigator.mediaDevices.getUserMedia({
            video: {facingMode: {ideal: 'environment'}}, // prefer rear camera
            audio: false
        }).then(function (stream) {
            mediaStream = stream;
            var video = document.getElementById('cameraVideo');
            video.srcObject = stream;
            video.onloadedmetadata = function () {
                overlay.hide();
                $('#btnCapture').prop('disabled', false);
            };
        }).catch(function (err) {
            var msg = 'Camera access denied. ';
            if (err && err.name === 'NotAllowedError') msg += 'Please allow camera permission and reload.';
            else if (err && err.name === 'NotFoundError') msg += 'No camera was found on this device.';
            else if (location.protocol !== 'https:' && location.hostname !== 'localhost') {
                msg = 'Live camera requires HTTPS. Please open this link over a secure connection.';
            }
            overlay.text(msg);
        });
    }

    function stopCamera() {
        if (mediaStream) {
            mediaStream.getTracks().forEach(function (t) {
                t.stop();
            });
            mediaStream = null;
        }
    }

    // Capture frame + silently grab geolocation (single combined action)
    $('#btnCapture').click(function () {
        var btn = $(this);
        btn.prop('disabled', true);
        $('#captureStatus').attr('class', 'capture-status ok').text('Capturing photo and your location...');

        var video = document.getElementById('cameraVideo');
        var canvas = document.getElementById('captureCanvas');
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

        // Show still preview, hide live video, allow retake
        var dataUrl = canvas.toDataURL('image/jpeg', 0.9);
        $('#photoPreview').attr('src', dataUrl).show();
        $('#cameraVideo').hide();
        $('#btnRetake').show();

        canvas.toBlob(function (blob) {
            if (!blob) {
                btn.prop('disabled', false);
                $('#captureStatus').attr('class', 'capture-status err').text('Could not capture photo. Try again.');
                return;
            }
            // Upload photo + grab geolocation in parallel
            var uploadDone = uploadPhoto(blob);
            var geoDone = captureGeo();
            $.when(uploadDone, geoDone).done(function () {
                $('#captureStatus').attr('class', 'capture-status ok')
                        .html('&#10004; Store photo and location captured.');
                stopCamera();
                refreshSubmitState();
            }).fail(function (msg) {
                btn.prop('disabled', false);
                $('#captureStatus').attr('class', 'capture-status err').text(msg || 'Capture failed. Try again.');
            });
        }, 'image/jpeg', 0.9);
    });

    $('#btnRetake').click(function () {
        $('#photoPreview').hide();
        $('#cameraVideo').show();
        $(this).hide();
        $('#imageDocumentId').val('0');
        $('#latitude').val('');
        $('#longitude').val('');
        $('#captureStatus').attr('class', 'capture-status').hide();
        refreshSubmitState();
        if (!mediaStream) startCamera();
        else $('#btnCapture').prop('disabled', false);
    });

    function uploadPhoto(blob) {
        var d = $.Deferred();
        var formData = new FormData();
        formData.append('file', blob, 'store-photo.jpg');
        $.ajax({
            url: contextPath + '/lead-geo/upload-image',
            method: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function (resp) {
                if (resp.response && resp.response.document_id) {
                    $('#imageDocumentId').val(resp.response.document_id);
                    d.resolve();
                } else {
                    d.reject('Upload failed.');
                }
            },
            error: function () {
                d.reject('Upload failed. Please try again.');
            }
        });
        return d.promise();
    }

    function captureGeo() {
        var d = $.Deferred();
        if (!navigator.geolocation) {
            d.reject('Geolocation not supported.');
            return d.promise();
        }
        navigator.geolocation.getCurrentPosition(
                function (pos) {
                    $('#latitude').val(pos.coords.latitude);
                    $('#longitude').val(pos.coords.longitude);
                    d.resolve();
                },
                function (err) {
                    var msg = 'Unable to get location. ';
                    if (err.code === 1) msg += 'Please allow location permission.';
                    else if (err.code === 2) msg += 'Location unavailable.';
                    else if (err.code === 3) msg += 'Timed out. Try again.';
                    d.reject(msg);
                },
                {enableHighAccuracy: true, timeout: 15000, maximumAge: 0}
        );
        return d.promise();
    }

    // ===== Submit gating: photo + location + consent all required =====
    function refreshSubmitState() {
        var hasLocation = $('#latitude').val() !== '' && $('#longitude').val() !== '';
        var hasImage = $('#imageDocumentId').val() !== '0';
        var consented = $('#consentCheck').is(':checked');
        $('#btnSubmit').prop('disabled', !(hasLocation && hasImage && consented));
    }

    $('#consentCheck').change(refreshSubmitState);

    // ===== Submit =====
    $('#btnSubmit').click(function () {
        var btn = $(this);
        btn.prop('disabled', true).html('<span class="spinner"></span> Submitting...');
        $('#submitError').hide();

        $.ajax({
            url: contextPath + '/lead-geo/submit',
            method: 'POST',
            data: {
                leadId: $('#leadId').val(),
                mobileNumber: $('#mobileNumber').val().trim(),
                latitude: $('#latitude').val(),
                longitude: $('#longitude').val(),
                imageDocumentId: $('#imageDocumentId').val()
            },
            success: function (resp) {
                $('.greeting').remove();
                $('.geo-card').html(
                        '<div class="success-wrap">' +
                        '<svg class="success-svg" width="120" height="120" viewBox="0 0 52 52" fill="none">' +
                        '<circle class="success-circle" cx="26" cy="26" r="24" fill="none" stroke="#22c55e"' +
                        ' stroke-width="3" stroke-linecap="round" transform="rotate(-90 26 26)"></circle>' +
                        '<path class="success-check" d="M16 27L23 34L37 19" fill="none" stroke="#22c55e" stroke-width="4"' +
                        ' stroke-linecap="round" stroke-linejoin="round"></path>' +
                        '</svg>' +
                        '<div>' +
                        '<h4 class="success-msg">Thank you for verification</h4>' +
                        '<p class="success-msg-hi">सत्यापन के लिए धन्यवाद</p>' +
                        '</div>' +
                        '</div>'
                );
                stopCamera();
            },
            error: function () {
                btn.prop('disabled', false).text('Submit Details');
                $('#submitError').text('Submission failed. Please try again.').show();
            }
        });
    });
</script>
</body>
</html>