Add 1 files
Browse files- index.html +97 -56
index.html
CHANGED
@@ -47,6 +47,22 @@
|
|
47 |
.error {
|
48 |
border-color: #ef4444 !important;
|
49 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
</style>
|
51 |
</head>
|
52 |
<body class="min-h-screen p-4 md:p-8">
|
@@ -210,10 +226,7 @@
|
|
210 |
|
211 |
<!-- Action Buttons -->
|
212 |
<div class="mt-8 flex flex-col sm:flex-row justify-center gap-4">
|
213 |
-
<button id="
|
214 |
-
<i class="fas fa-save mr-2"></i> Save Schedule
|
215 |
-
</button>
|
216 |
-
<button class="bg-white hover:bg-green-50 text-green-700 border border-green-300 font-bold py-3 px-6 rounded-lg flex items-center justify-center transition">
|
217 |
<i class="fas fa-share-alt mr-2"></i> Share with Neighbors
|
218 |
</button>
|
219 |
<button id="reset-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 font-bold py-3 px-6 rounded-lg flex items-center justify-center transition">
|
@@ -228,6 +241,9 @@
|
|
228 |
</div>
|
229 |
</div>
|
230 |
|
|
|
|
|
|
|
231 |
<!-- Load Google Maps API for Places autocomplete -->
|
232 |
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&libraries=places&callback=initAutocomplete" async defer></script>
|
233 |
|
@@ -296,6 +312,68 @@
|
|
296 |
}
|
297 |
}
|
298 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
// Add some interactivity
|
300 |
document.addEventListener('DOMContentLoaded', function() {
|
301 |
// Make checkboxes toggle the row color
|
@@ -357,13 +435,13 @@
|
|
357 |
|
358 |
firstNameInput.addEventListener('input', () => validateSingleWord(firstNameInput, nameError));
|
359 |
|
360 |
-
//
|
361 |
-
document.getElementById('
|
362 |
// Validate inputs
|
363 |
const isNameValid = validateSingleWord(firstNameInput, nameError);
|
364 |
|
365 |
if (!isNameValid) {
|
366 |
-
alert('Please fix the errors before
|
367 |
return;
|
368 |
}
|
369 |
|
@@ -374,56 +452,19 @@
|
|
374 |
return;
|
375 |
}
|
376 |
|
377 |
-
//
|
378 |
-
const
|
379 |
-
|
380 |
-
homeAddress: document.getElementById('home-address').value,
|
381 |
-
officeAddress: document.getElementById('office-address').value,
|
382 |
-
schedule: {
|
383 |
-
monday: {
|
384 |
-
depart: document.getElementById('mon-depart').value,
|
385 |
-
return: document.getElementById('mon-return').value,
|
386 |
-
needed: document.getElementById('mon-check').checked
|
387 |
-
},
|
388 |
-
tuesday: {
|
389 |
-
depart: document.getElementById('tue-depart').value,
|
390 |
-
return: document.getElementById('tue-return').value,
|
391 |
-
needed: document.getElementById('tue-check').checked
|
392 |
-
},
|
393 |
-
wednesday: {
|
394 |
-
depart: document.getElementById('wed-depart').value,
|
395 |
-
return: document.getElementById('wed-return').value,
|
396 |
-
needed: document.getElementById('wed-check').checked
|
397 |
-
},
|
398 |
-
thursday: {
|
399 |
-
depart: document.getElementById('thu-depart').value,
|
400 |
-
return: document.getElementById('thu-return').value,
|
401 |
-
needed: document.getElementById('thu-check').checked
|
402 |
-
},
|
403 |
-
friday: {
|
404 |
-
depart: document.getElementById('fri-depart').value,
|
405 |
-
return: document.getElementById('fri-return').value,
|
406 |
-
needed: document.getElementById('fri-check').checked
|
407 |
-
}
|
408 |
-
}
|
409 |
-
};
|
410 |
-
|
411 |
-
// Convert to JSON
|
412 |
-
const jsonData = JSON.stringify(scheduleData, null, 2);
|
413 |
|
414 |
-
//
|
415 |
-
const
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
URL.revokeObjectURL(url);
|
424 |
-
|
425 |
-
// Show success message
|
426 |
-
alert(`Schedule saved as ${firstNameInput.value.trim()}-carpool-schedule.json`);
|
427 |
});
|
428 |
|
429 |
// Reset form
|
|
|
47 |
.error {
|
48 |
border-color: #ef4444 !important;
|
49 |
}
|
50 |
+
.toast {
|
51 |
+
position: fixed;
|
52 |
+
bottom: 20px;
|
53 |
+
left: 50%;
|
54 |
+
transform: translateX(-50%);
|
55 |
+
background-color: #333;
|
56 |
+
color: white;
|
57 |
+
padding: 12px 24px;
|
58 |
+
border-radius: 4px;
|
59 |
+
z-index: 1000;
|
60 |
+
opacity: 0;
|
61 |
+
transition: opacity 0.3s ease;
|
62 |
+
}
|
63 |
+
.toast.show {
|
64 |
+
opacity: 1;
|
65 |
+
}
|
66 |
</style>
|
67 |
</head>
|
68 |
<body class="min-h-screen p-4 md:p-8">
|
|
|
226 |
|
227 |
<!-- Action Buttons -->
|
228 |
<div class="mt-8 flex flex-col sm:flex-row justify-center gap-4">
|
229 |
+
<button id="share-btn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-6 rounded-lg flex items-center justify-center transition">
|
|
|
|
|
|
|
230 |
<i class="fas fa-share-alt mr-2"></i> Share with Neighbors
|
231 |
</button>
|
232 |
<button id="reset-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 font-bold py-3 px-6 rounded-lg flex items-center justify-center transition">
|
|
|
241 |
</div>
|
242 |
</div>
|
243 |
|
244 |
+
<!-- Toast notification -->
|
245 |
+
<div id="toast" class="toast">Link copied to clipboard!</div>
|
246 |
+
|
247 |
<!-- Load Google Maps API for Places autocomplete -->
|
248 |
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&libraries=places&callback=initAutocomplete" async defer></script>
|
249 |
|
|
|
312 |
}
|
313 |
}
|
314 |
|
315 |
+
// Function to show toast notification
|
316 |
+
function showToast(message) {
|
317 |
+
const toast = document.getElementById('toast');
|
318 |
+
toast.textContent = message;
|
319 |
+
toast.classList.add('show');
|
320 |
+
|
321 |
+
setTimeout(() => {
|
322 |
+
toast.classList.remove('show');
|
323 |
+
}, 3000);
|
324 |
+
}
|
325 |
+
|
326 |
+
// Function to encode data for URL
|
327 |
+
function encodeData() {
|
328 |
+
const data = {
|
329 |
+
firstName: document.getElementById('first-name').value,
|
330 |
+
homeAddress: document.getElementById('home-address').value,
|
331 |
+
officeAddress: document.getElementById('office-address').value,
|
332 |
+
schedule: {
|
333 |
+
monday: {
|
334 |
+
depart: document.getElementById('mon-depart').value,
|
335 |
+
return: document.getElementById('mon-return').value,
|
336 |
+
needed: document.getElementById('mon-check').checked
|
337 |
+
},
|
338 |
+
tuesday: {
|
339 |
+
depart: document.getElementById('tue-depart').value,
|
340 |
+
return: document.getElementById('tue-return').value,
|
341 |
+
needed: document.getElementById('tue-check').checked
|
342 |
+
},
|
343 |
+
wednesday: {
|
344 |
+
depart: document.getElementById('wed-depart').value,
|
345 |
+
return: document.getElementById('wed-return').value,
|
346 |
+
needed: document.getElementById('wed-check').checked
|
347 |
+
},
|
348 |
+
thursday: {
|
349 |
+
depart: document.getElementById('thu-depart').value,
|
350 |
+
return: document.getElementById('thu-return').value,
|
351 |
+
needed: document.getElementById('thu-check').checked
|
352 |
+
},
|
353 |
+
friday: {
|
354 |
+
depart: document.getElementById('fri-depart').value,
|
355 |
+
return: document.getElementById('fri-return').value,
|
356 |
+
needed: document.getElementById('fri-check').checked
|
357 |
+
}
|
358 |
+
}
|
359 |
+
};
|
360 |
+
|
361 |
+
// Convert to JSON and then to base64 for URL
|
362 |
+
const jsonString = JSON.stringify(data);
|
363 |
+
return btoa(encodeURIComponent(jsonString));
|
364 |
+
}
|
365 |
+
|
366 |
+
// Function to copy text to clipboard
|
367 |
+
async function copyToClipboard(text) {
|
368 |
+
try {
|
369 |
+
await navigator.clipboard.writeText(text);
|
370 |
+
return true;
|
371 |
+
} catch (err) {
|
372 |
+
console.error('Failed to copy text: ', err);
|
373 |
+
return false;
|
374 |
+
}
|
375 |
+
}
|
376 |
+
|
377 |
// Add some interactivity
|
378 |
document.addEventListener('DOMContentLoaded', function() {
|
379 |
// Make checkboxes toggle the row color
|
|
|
435 |
|
436 |
firstNameInput.addEventListener('input', () => validateSingleWord(firstNameInput, nameError));
|
437 |
|
438 |
+
// Share button functionality
|
439 |
+
document.getElementById('share-btn').addEventListener('click', async function() {
|
440 |
// Validate inputs
|
441 |
const isNameValid = validateSingleWord(firstNameInput, nameError);
|
442 |
|
443 |
if (!isNameValid) {
|
444 |
+
alert('Please fix the errors before sharing');
|
445 |
return;
|
446 |
}
|
447 |
|
|
|
452 |
return;
|
453 |
}
|
454 |
|
455 |
+
// Generate the encoded data
|
456 |
+
const encodedData = encodeData();
|
457 |
+
const shareUrl = `https://huggingface.co/spaces/asifpa/carpuco/${encodedData}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
458 |
|
459 |
+
// Copy to clipboard
|
460 |
+
const success = await copyToClipboard(shareUrl);
|
461 |
+
|
462 |
+
if (success) {
|
463 |
+
showToast('Link copied to clipboard!');
|
464 |
+
} else {
|
465 |
+
// Fallback if clipboard API fails
|
466 |
+
prompt('Copy this link to share with neighbors:', shareUrl);
|
467 |
+
}
|
|
|
|
|
|
|
|
|
468 |
});
|
469 |
|
470 |
// Reset form
|