|
| 1 | +@import com.statusneo.vms.enums.VisitPurpose |
1 | 2 | <!DOCTYPE html> |
2 | 3 | <html lang="en"> |
3 | 4 | <head> |
|
6 | 7 | <title>Visitor Check-in</title> |
7 | 8 | <link href="/main.css" rel="stylesheet"> |
8 | 9 | <script src="/webjars/htmx.org/2.0.7/dist/htmx.min.js"></script> |
| 10 | + <style> |
| 11 | + html { height: 100%; **overflow: hidden;** } |
| 12 | + body { height: 100vh; **overflow: hidden;** } |
| 13 | + </style> |
9 | 14 | </head> |
10 | | -<body class="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100"> |
11 | | - |
12 | | -<!-- Top-level modal container so HTMX swaps can render full-screen overlays without being clipped --> |
| 15 | +<body class="bg-gradient-to-br from-blue-50 to-indigo-100 h-screen w-screen overflow-hidden"> |
13 | 16 | <div id="modal-container"></div> |
14 | | - |
15 | | -<div class="container mx-auto px-4 py-8 max-w-4xl"> |
16 | | - <!-- Header --> |
17 | | - <div class="text-center mb-8"> |
| 17 | +<div class="container mx-auto px-4 py-8 max-w-3xl h-full flex flex-col justify-center"> |
| 18 | + <div class="text-center mb-6 flex-shrink-0"> |
18 | 19 | <div class="flex justify-center mb-4"> |
19 | 20 | <img id="site-logo" src="/images/StatusNeo-logo.png" alt="StatusNeo Logo" style="height:36px !important; max-height:36px !important; width:auto !important;" class="mx-auto"> |
20 | 21 | </div> |
21 | 22 | <h1 class="text-3xl font-bold text-gray-800 mb-2">Visitor Check-in</h1> |
22 | 23 | <p class="text-gray-600">Please fill in your details to register your visit</p> |
23 | 24 | </div> |
24 | 25 |
|
25 | | - <!-- Main Form --> |
26 | 26 | <div class="bg-white rounded-2xl shadow-xl p-6 md:p-8"> |
27 | | - <!-- Modal Container --> |
28 | | - <div id="modal-container"></div> |
29 | 27 |
|
30 | 28 | <form id="visitor-form" |
31 | 29 | hx-post="/register" |
32 | 30 | hx-target="#modal-container" |
33 | 31 | hx-swap="innerHTML" |
34 | 32 | hx-trigger="submit" |
35 | | - class="space-y-6"> |
| 33 | + class="space-y-6 h-full flex flex-col"> |
36 | 34 | <input type="hidden" name="_csrf" value=""> |
37 | | - |
38 | 35 | <div id="form-content"> |
39 | | - <!-- Two Column Grid for Tablet/Desktop --> |
40 | 36 | <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
41 | | - |
42 | 37 | <div class="space-y-2"> |
43 | 38 | <label for="name" class="block text-sm font-medium text-gray-700 flex items-center"> |
44 | 39 | <svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
68 | 63 | class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors" |
69 | 64 | placeholder="Enter your email address"> |
70 | 65 | </div> |
71 | | - |
72 | 66 | <div class="space-y-2"> |
73 | 67 | <label for="phone" class="block text-sm font-medium text-gray-700 flex items-center"> |
74 | 68 | <svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
83 | 77 | class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors" |
84 | 78 | placeholder="Enter your phone number"> |
85 | 79 | </div> |
86 | | - |
87 | 80 | <div class="space-y-2"> |
88 | 81 | <label for="company" class="block text-sm font-medium text-gray-700 flex items-center"> |
89 | 82 | <svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
98 | 91 | class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors" |
99 | 92 | placeholder="Enter your company name"> |
100 | 93 | </div> |
101 | | - |
102 | 94 | <div class="space-y-2"> |
103 | 95 | <label for="laptop" class="block text-sm font-medium text-gray-700 flex items-center"> |
104 | 96 | <svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
112 | 104 | class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors" |
113 | 105 | placeholder="Enter your laptop number (optional)"> |
114 | 106 | </div> |
115 | | - |
116 | | - <div class="md:col-span-2 space-y-2"> |
| 107 | + <div class="space-y-2"> |
| 108 | + <label for="govtId" class="block text-sm font-medium text-gray-700 flex items-center"> |
| 109 | + <svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 110 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V8a2 2 0 00-2-2h-5m-7 0V4a2 2 0 012-2h4a2 2 0 012 2v2M7 12h10m-10 4h10"/> |
| 111 | + </svg> |
| 112 | + <span class="align-middle">Valid Govt ID (DL / PAN / Aadhaar) *</span> |
| 113 | + </label> |
| 114 | + <input type="text" |
| 115 | + id="govtId" |
| 116 | + name="govtId" |
| 117 | + required |
| 118 | + class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors" |
| 119 | + placeholder="Enter your government ID number"> |
| 120 | + </div> |
| 121 | + <div class="space-y-2"> |
117 | 122 | <label for="host-search" class="block text-sm font-medium text-gray-700 flex items-center"> |
118 | 123 | <svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
119 | 124 | <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/> |
|
142 | 147 | </svg> |
143 | 148 | </div> |
144 | 149 |
|
145 | | - <!-- Dropdown Results --> |
146 | 150 | <div id="host-results" |
147 | 151 | class="absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg max-h-48 overflow-y-auto hidden"> |
148 | | - <!-- Results will be populated by HTMX --> |
149 | 152 | </div> |
150 | 153 | </div> |
151 | 154 | </div> |
| 155 | + |
| 156 | + <div class="space-y-2"> |
| 157 | + <label for="visit-purpose" class="block text-sm font-medium text-gray-700"> |
| 158 | + <svg class="inline w-4 h-4 mr-1 text-gray-500 align-middle" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 159 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> |
| 160 | + </svg> |
| 161 | + <span class="align-middle">Visit Purpose <span class="text-gray-700">*</span></span> |
| 162 | + </label> |
| 163 | + |
| 164 | + <select id="visit-purpose" name="visit-purpose" |
| 165 | + required |
| 166 | + class="mt-1 block w-full pl-3 pr-10 py-3 text-base border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md shadow-sm transition-colors"> |
| 167 | + <option value="">-- Select purpose --</option> |
| 168 | + |
| 169 | + @for (VisitPurpose purpose : VisitPurpose.values()) |
| 170 | + <option value="${purpose.getFormValue()}">${purpose.getDisplayName()}</option> |
| 171 | + @endfor |
| 172 | + </select> |
| 173 | + </div> |
152 | 174 | </div> |
153 | 175 |
|
154 | | - <!-- Submit Button --> |
155 | 176 | <div class="flex justify-center pt-4"> |
156 | 177 | <button type="submit" |
157 | 178 | id="send-otp-btn" |
158 | | - disabled class="px-8 py-4 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors min-w-48 text-lg relative flex items-center justify-center"> <span class="htmx-indicator:hidden">Send OTP</span> |
| 179 | + disabled class="px-8 py-4 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors min-w-48 text-lg relative flex items-center justify-center"> |
| 180 | + <span class="htmx-indicator:hidden">Send OTP</span> |
159 | 181 | <span class="htmx-indicator absolute inset-0 flex items-center justify-center"> |
160 | 182 | <svg class="inline animate-spin h-5 w-5 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> |
161 | 183 | <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> |
|
166 | 188 | </button> |
167 | 189 | </div> |
168 | 190 | </div> |
| 191 | + <div class="mt-6 text-center text-sm text-gray-500"> |
| 192 | + By checking in, you agree to our visitor policies and terms of service. |
| 193 | + </div> |
169 | 194 | </form> |
170 | | - |
171 | | - <!-- Footer --> |
172 | | - <div class="mt-6 text-center text-sm text-gray-500"> |
173 | | - By checking in, you agree to our visitor policies and terms of service. |
174 | | - </div> |
175 | 195 | </div> |
176 | 196 | </div> |
177 | 197 |
|
178 | | -<!-- Removed a small duplicate autocomplete handler here in favor of the more complete handlers below --> |
179 | | - |
180 | 198 | <script> |
181 | 199 | // Form validation (host is not mandatory) |
182 | 200 | function validateForm() { |
183 | 201 | const name = document.getElementById('name').value; |
184 | 202 | const email = document.getElementById('email').value; |
185 | 203 | const phone = document.getElementById('phone').value; |
186 | 204 | const company = document.getElementById('company').value; |
| 205 | + const govtId = document.getElementById('govtId').value; |
| 206 | + const visitPurpose = document.getElementById('visit-purpose').value; |
187 | 207 |
|
188 | | - const isValid = name && email && phone && company; |
| 208 | + const isValid = name && email && phone && company && govtId && visitPurpose; |
189 | 209 | document.getElementById('send-otp-btn').disabled = !isValid; |
190 | 210 | } |
191 | 211 |
|
192 | 212 | document.querySelectorAll('input[required]').forEach(input => { |
193 | 213 | input.addEventListener('input', validateForm); |
194 | 214 | }); |
195 | | -
|
| 215 | + document.getElementById('visit-purpose').addEventListener('change', validateForm); |
196 | 216 | validateForm(); |
197 | 217 | </script> |
198 | 218 |
|
|
0 commit comments