File size: 24,648 Bytes
8da47df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c489ca9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0825bbb
 
 
c6b1d22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8da47df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c489ca9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0825bbb
22a5bdf
 
0825bbb
 
 
 
 
 
 
 
c489ca9
 
 
 
 
 
 
 
 
 
 
 
 
 
8da47df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0825bbb
8da47df
 
0825bbb
8da47df
 
0825bbb
8da47df
 
0825bbb
8da47df
 
0825bbb
8da47df
 
 
 
 
 
 
 
 
0825bbb
8da47df
 
0825bbb
8da47df
 
0825bbb
8da47df
 
0825bbb
8da47df
 
0825bbb
8da47df
 
 
 
 
 
 
 
 
 
0825bbb
8da47df
 
 
 
0825bbb
8da47df
 
 
 
0825bbb
8da47df
 
 
 
0825bbb
8da47df
 
 
 
0825bbb
8da47df
 
 
 
 
 
 
 
 
c6b1d22
8da47df
 
0825bbb
8da47df
 
 
 
 
 
 
 
 
 
 
c6b1d22
 
 
c489ca9
 
 
8da47df
c489ca9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c6b1d22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8da47df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c489ca9
 
 
 
 
 
 
 
 
 
 
0825bbb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c6b1d22
 
0825bbb
 
 
22a5bdf
c6b1d22
0825bbb
 
 
 
 
 
 
 
 
 
c6b1d22
 
 
0825bbb
c6b1d22
 
 
 
 
 
 
 
 
0825bbb
 
 
 
 
 
 
22a5bdf
0825bbb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8da47df
 
 
 
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Neighbor Carpool Coordinator</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        body {
            background-color: #4ade80;
        }
        .time-input {
            width: 80px;
            text-align: center;
        }
        .day-header {
            transition: all 0.3s ease;
        }
        .day-header:hover {
            transform: translateY(-2px);
        }
        .checkbox-container {
            transition: all 0.3s ease;
        }
        .checkbox-container:hover {
            transform: scale(1.05);
        }
        .instructions-content {
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.3s ease-out;
        }
        .instructions-content.expanded {
            max-height: 200px;
        }
        .pac-container {
            z-index: 1050 !important;
        }
        .address-input {
            transition: all 0.3s ease;
        }
        .address-input:focus {
            border-color: #4ade80;
            box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.2);
        }
        .error {
            border-color: #ef4444 !important;
        }
        .toast {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: #333;
            color: white;
            padding: 12px 24px;
            border-radius: 4px;
            z-index: 1000;
            opacity: 0;
            transition: opacity 0.3s ease;
        }
        .toast.show {
            opacity: 1;
        }
    </style>
</head>
<body class="min-h-screen p-4 md:p-8">
    <div class="max-w-4xl mx-auto bg-white rounded-xl shadow-xl overflow-hidden">
        <!-- Header -->
        <div class="bg-green-600 p-6 text-white">
            <div class="flex items-center justify-between">
                <div>
                    <h1 class="text-2xl md:text-3xl font-bold">
                        <i class="fas fa-car-side mr-3"></i>
                        Neighbor Carpool Coordinator
                    </h1>
                    <p class="mt-2 opacity-90">Coordinate rides with your neighbors for the week</p>
                </div>
                <div class="hidden md:block">
                    <i class="fas fa-users fa-3x opacity-80"></i>
                </div>
            </div>
        </div>

        <!-- Main Content -->
        <div class="p-6">
            <!-- Instructions -->
            <div class="mb-8 p-4 bg-green-50 rounded-lg border border-green-200">
                <div class="flex items-center cursor-pointer" id="instructions-toggle">
                    <h2 class="text-lg font-semibold text-green-800 mb-2">
                        <i class="fas fa-info-circle mr-2" id="info-icon"></i>How it works
                    </h2>
                </div>
                <div class="instructions-content" id="instructions-content">
                    <p class="text-green-700 mt-2">
                        Enter your departure and return times for each day, then check the boxes for days you need carpooling.
                        Share this with your neighbors to coordinate rides!
                    </p>
                    <div class="mt-3 flex items-center text-green-600">
                        <i class="fas fa-lightbulb mr-2"></i>
                        <span class="text-sm">Tip: Double-click on time fields to insert current time</span>
                    </div>
                </div>
            </div>

            <!-- User Info Fields -->
            <div class="mb-6">
                <div class="w-full md:w-1/2">
                    <label for="first-name" class="block text-sm font-medium text-green-700 mb-1">
                        <i class="fas fa-user mr-2"></i>First Name (no spaces)
                    </label>
                    <input type="text" id="first-name" class="address-input w-full p-3 border border-green-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-200" placeholder="Enter your first name" autocomplete="off">
                    <p id="name-error" class="text-red-500 text-xs mt-1 hidden">Please enter a single word without spaces</p>
                </div>
            </div>

            <!-- Address Fields -->
            <div class="mb-6 grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                    <label for="home-address" class="block text-sm font-medium text-green-700 mb-1">
                        <i class="fas fa-home mr-2"></i>Home Address
                    </label>
                    <input type="text" id="home-address" class="address-input w-full p-3 border border-green-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-200" placeholder="Enter your home address" autocomplete="off">
                </div>
                <div>
                    <label for="office-address" class="block text-sm font-medium text-green-700 mb-1">
                        <i class="fas fa-building mr-2"></i>Office Address
                    </label>
                    <input type="text" id="office-address" class="address-input w-full p-3 border border-green-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-200" placeholder="Enter your office address" autocomplete="off">
                </div>
            </div>

            <!-- Carpool Table -->
            <div class="overflow-x-auto">
                <table class="w-full border-collapse">
                    <thead>
                        <tr class="bg-green-100">
                            <th class="p-3 text-left text-green-800">Day</th>
                            <th class="p-3 text-green-800 day-header">Monday</th>
                            <th class="p-3 text-green-800 day-header">Tuesday</th>
                            <th class="p-3 text-green-800 day-header">Wednesday</th>
                            <th class="p-3 text-green-800 day-header">Thursday</th>
                            <th class="p-3 text-green-800 day-header">Friday</th>
                        </tr>
                    </thead>
                    <tbody>
                        <!-- Leaving Home Row -->
                        <tr class="border-b border-green-200 hover:bg-green-50">
                            <td class="p-3 font-medium text-green-700">
                                <i class="fas fa-home mr-2"></i>Leaving Home
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="mon-depart">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="tue-depart">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="wed-depart">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="thu-depart">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="fri-depart">
                            </td>
                        </tr>
                        
                        <!-- Heading Home Row -->
                        <tr class="border-b border-green-200 hover:bg-green-50">
                            <td class="p-3 font-medium text-green-700">
                                <i class="fas fa-building mr-2"></i>Heading Home
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="mon-return">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="tue-return">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="wed-return">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="thu-return">
                            </td>
                            <td class="p-3 text-center">
                                <input type="time" class="time-input border border-green-300 rounded p-1" id="fri-return">
                            </td>
                        </tr>
                        
                        <!-- Carpool Needed Row -->
                        <tr>
                            <td class="p-3 font-medium text-green-700">
                                <i class="fas fa-check-circle mr-2"></i>Carpool Needed
                            </td>
                            <td class="p-3 text-center checkbox-container">
                                <label class="inline-flex items-center">
                                    <input type="checkbox" class="form-checkbox h-5 w-5 text-green-600 rounded border-green-300" id="mon-check">
                                </label>
                            </td>
                            <td class="p-3 text-center checkbox-container">
                                <label class="inline-flex items-center">
                                    <input type="checkbox" class="form-checkbox h-5 w-5 text-green-600 rounded border-green-300" id="tue-check">
                                </label>
                            </td>
                            <td class="p-3 text-center checkbox-container">
                                <label class="inline-flex items-center">
                                    <input type="checkbox" class="form-checkbox h-5 w-5 text-green-600 rounded border-green-300" id="wed-check">
                                </label>
                            </td>
                            <td class="p-3 text-center checkbox-container">
                                <label class="inline-flex items-center">
                                    <input type="checkbox" class="form-checkbox h-5 w-5 text-green-600 rounded border-green-300" id="thu-check">
                                </label>
                            </td>
                            <td class="p-3 text-center checkbox-container">
                                <label class="inline-flex items-center">
                                    <input type="checkbox" class="form-checkbox h-5 w-5 text-green-600 rounded border-green-300" id="fri-check">
                                </label>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <!-- Action Buttons -->
            <div class="mt-8 flex flex-col sm:flex-row justify-center gap-4">
                <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">
                    <i class="fas fa-share-alt mr-2"></i> Share with Neighbors
                </button>
                <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">
                    <i class="fas fa-sync-alt mr-2"></i> Reset
                </button>
            </div>
        </div>

        <!-- Footer -->
        <div class="bg-green-50 p-4 text-center text-green-700 text-sm">
            <p>Made with <i class="fas fa-heart text-red-400"></i> for neighbors helping neighbors</p>
        </div>
    </div>

    <!-- Toast notification -->
    <div id="toast" class="toast">Link copied to clipboard!</div>

    <!-- Load Google Maps API for Places autocomplete -->
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&libraries=places&callback=initAutocomplete" async defer></script>
    
    <script>
        // Initialize Google Maps Places Autocomplete
        function initAutocomplete() {
            console.log("Initializing Google Maps Places Autocomplete...");
            
            try {
                const homeInput = document.getElementById('home-address');
                const officeInput = document.getElementById('office-address');
                
                if (homeInput && officeInput) {
                    // Create autocomplete objects
                    const homeAutocomplete = new google.maps.places.Autocomplete(
                        homeInput,
                        {
                            types: ['geocode'],
                            componentRestrictions: {country: 'us'},
                            fields: ['address_components', 'geometry', 'name']
                        }
                    );
                    
                    const officeAutocomplete = new google.maps.places.Autocomplete(
                        officeInput,
                        {
                            types: ['geocode'],
                            componentRestrictions: {country: 'us'},
                            fields: ['address_components', 'geometry', 'name']
                        }
                    );
                    
                    console.log("Autocomplete objects created successfully");
                    
                    // Prevent form submission when pressing Enter on address fields
                    [homeInput, officeInput].forEach(input => {
                        input.addEventListener('keydown', (e) => {
                            if (e.key === 'Enter') {
                                e.preventDefault();
                                // Close the dropdown if open
                                const dropdown = document.querySelector('.pac-container');
                                if (dropdown) {
                                    dropdown.style.display = 'none';
                                }
                            }
                        });
                    });
                    
                    // Add event listeners for place changes
                    homeAutocomplete.addListener('place_changed', function() {
                        const place = homeAutocomplete.getPlace();
                        console.log("Home address selected:", place);
                    });
                    
                    officeAutocomplete.addListener('place_changed', function() {
                        const place = officeAutocomplete.getPlace();
                        console.log("Office address selected:", place);
                    });
                } else {
                    console.error("Could not find address input elements");
                }
            } catch (error) {
                console.error("Error initializing Google Maps Places Autocomplete:", error);
                // Fallback: Show an alert if autocomplete fails
                alert("Address autocomplete is not working. Please enter your address manually.");
            }
        }

        // Function to show toast notification
        function showToast(message) {
            const toast = document.getElementById('toast');
            toast.textContent = message;
            toast.classList.add('show');
            
            setTimeout(() => {
                toast.classList.remove('show');
            }, 3000);
        }

        // Function to encode data for URL
        function encodeData() {
            const data = {
                firstName: document.getElementById('first-name').value,
                homeAddress: document.getElementById('home-address').value,
                officeAddress: document.getElementById('office-address').value,
                schedule: {
                    monday: {
                        depart: document.getElementById('mon-depart').value,
                        return: document.getElementById('mon-return').value,
                        needed: document.getElementById('mon-check').checked
                    },
                    tuesday: {
                        depart: document.getElementById('tue-depart').value,
                        return: document.getElementById('tue-return').value,
                        needed: document.getElementById('tue-check').checked
                    },
                    wednesday: {
                        depart: document.getElementById('wed-depart').value,
                        return: document.getElementById('wed-return').value,
                        needed: document.getElementById('wed-check').checked
                    },
                    thursday: {
                        depart: document.getElementById('thu-depart').value,
                        return: document.getElementById('thu-return').value,
                        needed: document.getElementById('thu-check').checked
                    },
                    friday: {
                        depart: document.getElementById('fri-depart').value,
                        return: document.getElementById('fri-return').value,
                        needed: document.getElementById('fri-check').checked
                    }
                }
            };
            
            // Convert to JSON and then to base64 for URL
            const jsonString = JSON.stringify(data);
            return btoa(encodeURIComponent(jsonString));
        }

        // Function to copy text to clipboard
        async function copyToClipboard(text) {
            try {
                await navigator.clipboard.writeText(text);
                return true;
            } catch (err) {
                console.error('Failed to copy text: ', err);
                return false;
            }
        }

        // Add some interactivity
        document.addEventListener('DOMContentLoaded', function() {
            // Make checkboxes toggle the row color
            const checkboxes = document.querySelectorAll('input[type="checkbox"]');
            checkboxes.forEach(checkbox => {
                checkbox.addEventListener('change', function() {
                    const dayIndex = this.closest('td').cellIndex;
                    const timeInputs = document.querySelectorAll(`tbody tr:nth-child(-n+2) td:nth-child(${dayIndex + 1}) input`);
                    
                    if(this.checked) {
                        timeInputs.forEach(input => {
                            input.classList.add('bg-green-100', 'border-green-400');
                        });
                    } else {
                        timeInputs.forEach(input => {
                            input.classList.remove('bg-green-100', 'border-green-400');
                        });
                    }
                });
            });

            // Add current time to inputs on double click
            const timeInputs = document.querySelectorAll('.time-input');
            timeInputs.forEach(input => {
                input.addEventListener('dblclick', function() {
                    const now = new Date();
                    const hours = now.getHours().toString().padStart(2, '0');
                    const minutes = now.getMinutes().toString().padStart(2, '0');
                    this.value = `${hours}:${minutes}`;
                });
            });

            // Toggle instructions content
            const toggleInstructions = document.getElementById('instructions-toggle');
            const instructionsContent = document.getElementById('instructions-content');
            const infoIcon = document.getElementById('info-icon');

            toggleInstructions.addEventListener('click', function() {
                instructionsContent.classList.toggle('expanded');
                infoIcon.classList.toggle('fa-info-circle');
                infoIcon.classList.toggle('fa-chevron-down');
            });

            // Validate single-word inputs
            const firstNameInput = document.getElementById('first-name');
            const nameError = document.getElementById('name-error');

            function validateSingleWord(input, errorElement) {
                if (input.value.includes(' ')) {
                    input.classList.add('error');
                    errorElement.classList.remove('hidden');
                    return false;
                } else {
                    input.classList.remove('error');
                    errorElement.classList.add('hidden');
                    return true;
                }
            }

            firstNameInput.addEventListener('input', () => validateSingleWord(firstNameInput, nameError));

            // Share button functionality
            document.getElementById('share-btn').addEventListener('click', async function() {
                // Validate inputs
                const isNameValid = validateSingleWord(firstNameInput, nameError);
                
                if (!isNameValid) {
                    alert('Please fix the errors before sharing');
                    return;
                }

                if (!firstNameInput.value.trim()) {
                    firstNameInput.classList.add('error');
                    nameError.classList.remove('hidden');
                    alert('Please enter your first name');
                    return;
                }

                // Generate the encoded data
                const encodedData = encodeData();
                const shareUrl = `https://huggingface.co/spaces/asifpa/carpuco/${encodedData}`;
                
                // Copy to clipboard
                const success = await copyToClipboard(shareUrl);
                
                if (success) {
                    showToast('Link copied to clipboard!');
                } else {
                    // Fallback if clipboard API fails
                    prompt('Copy this link to share with neighbors:', shareUrl);
                }
            });

            // Reset form
            document.getElementById('reset-btn').addEventListener('click', function() {
                if (confirm('Are you sure you want to reset all fields?')) {
                    // Reset all inputs
                    document.querySelectorAll('input').forEach(input => {
                        if (input.type === 'text') {
                            input.value = '';
                        } else if (input.type === 'time') {
                            input.value = '';
                        } else if (input.type === 'checkbox') {
                            input.checked = false;
                        }
                    });
                    
                    // Remove error states
                    firstNameInput.classList.remove('error');
                    nameError.classList.add('hidden');
                    
                    // Remove any green highlighting from time inputs
                    document.querySelectorAll('.time-input').forEach(input => {
                        input.classList.remove('bg-green-100', 'border-green-400');
                    });
                }
            });
        });
    </script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=asifpa/carpuco" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>