File size: 6,169 Bytes
701628b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
{% extends "base.html" %}

{% block content %}
<div class="top-bar">
    <a href="/dashboard" style="color: var(--color-text); text-decoration: none;">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M19 12H5M12 19l-7-7 7-7"/>
        </svg>
    </a>
    <h2>Register</h2>
    <a href="/dashboard" class="top-bar-logo-wrap">
        <img src="{{ url_for('static', filename='images/logo.png') }}" alt="One Step Greener" class="top-bar-logo top-bar-logo-sm" />
    </a>
</div>

<!-- PIN gate: always shown first; hidden after correct PIN -->
<div id="pinGate" class="pin-gate">
    <p class="pin-prompt">Enter PIN to access Register.</p>
    <input type="password" id="pinInput" class="pin-input" placeholder="PIN" maxlength="8" inputmode="numeric" autocomplete="off" />
    <button type="button" id="pinSubmit" class="btn-primary pin-submit">Continue</button>
    <p id="pinError" class="pin-error" style="display: none;"></p>
</div>

<!-- Register form: hidden until PIN verified; switchable tab Employee | Manforce -->
<div id="registerForm" class="register-form-locked" style="display: none;">
    <div class="register-tabs" role="tablist">
        <button type="button" id="tabEmployee" class="register-tab active" role="tab" aria-selected="true" data-tab="employee">Employee</button>
        <button type="button" id="tabManforce" class="register-tab" role="tab" aria-selected="false" data-tab="manforce">Manforce</button>
    </div>
    <div id="panelEmployee" class="register-panel active" role="tabpanel">
        <input type="text" id="employeeCode" placeholder="Employee code">
        <p class="status-text" id="statusTextEmployee">Align face within frame</p>
        <button id="btnRegisterEmployee" class="btn-primary" disabled>Register</button>
    </div>
    <div id="panelManforce" class="register-panel" role="tabpanel" hidden>
        <input type="text" id="manforceAadhaar" placeholder="Aadhaar number">
        <input type="text" id="manforceName" placeholder="Full name">
        <input type="text" id="manforceMobile" placeholder="Mobile number">
        <p class="status-text" id="statusTextManforce">Align face within frame</p>
        <button id="btnRegisterManforce" class="btn-primary" disabled>Register</button>
    </div>
    <div class="video-rect-container register-video-shared">
        <video id="videoFeed" autoplay playsinline muted></video>
        <div class="rect-overlay"></div>
        <svg class="progress-ring" viewBox="0 0 40 40">
            <circle cx="20" cy="20" r="18" stroke="#333" stroke-width="4" fill="none"/>
            <circle id="progressCircle" cx="20" cy="20" r="18" stroke="var(--color-primary)" stroke-width="4" fill="none" stroke-dasharray="113" stroke-dashoffset="113" transform="rotate(-90 20 20)"/>
        </svg>
    </div>
    <p class="status-text" id="statusText">Align face within frame</p>
    <p class="status-hint register-capture-hint">Look at the camera and blink naturally during capture.</p>
</div>

<!-- Spoof toast (same as attendance) -->
<div id="spoofToast" class="toast toast-danger" role="alert" aria-live="polite">
    <span class="toast-icon"></span>
    <div class="toast-body">
        <strong class="toast-title">Spoofing detected</strong>
        <p class="toast-message" id="spoofToastMessage">Use a live face, not a photo or screen.</p>
    </div>
</div>

<div id="successState" class="success-state" style="display:none;">
    <img src="{{ url_for('static', filename='images/face-id-success.png') }}" alt="Face registered" class="success-face-icon" />
    <h2>Registered</h2>
    <div class="chip" id="successChip"></div>
    <button class="btn-outline" onclick="location.reload()">Register Another</button>
    <br>
    <a href="/dashboard" style="color: var(--color-text-muted); font-size: 13px; margin-top: 20px; display:inline-block;">Back to check in</a>
</div>

{% endblock %}

{% block scripts %}
<script>
(function() {
    var pinGate = document.getElementById('pinGate');
    var registerForm = document.getElementById('registerForm');
    var pinInput = document.getElementById('pinInput');
    var pinSubmit = document.getElementById('pinSubmit');
    var pinError = document.getElementById('pinError');

    if (pinGate && registerForm && pinInput && pinSubmit) {
        function doVerify() {
            var pin = (pinInput.value || '').trim();
            pinError.style.display = 'none';
            if (!pin) {
                pinError.textContent = 'Enter PIN';
                pinError.style.display = 'block';
                return;
            }
            pinSubmit.disabled = true;
            fetch('/api/verify-pin', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ pin: pin })
            })
            .then(function(r) { return r.json(); })
            .then(function(data) {
                pinSubmit.disabled = false;
                if (data.status === 'ok') {
                    pinGate.style.display = 'none';
                    registerForm.style.display = 'block';
                    if (window.loadRegisterScript) window.loadRegisterScript();
                } else {
                    pinError.textContent = data.message || 'Incorrect PIN';
                    pinError.style.display = 'block';
                }
            })
            .catch(function() {
                pinSubmit.disabled = false;
                pinError.textContent = 'Request failed';
                pinError.style.display = 'block';
            });
        }
        pinSubmit.addEventListener('click', doVerify);
        pinInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') doVerify(); });

        window.loadRegisterScript = function() {
            if (window.registerScriptLoaded) return;
            window.registerScriptLoaded = true;
            var s = document.createElement('script');
            s.src = "{{ url_for('static', filename='js/register.js') }}";
            document.body.appendChild(s);
        };
    }
})();
</script>
{% endblock %}