vi-c commited on
Commit
bf7a140
·
verified ·
1 Parent(s): 047cd12

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +274 -91
index.html CHANGED
@@ -39,6 +39,19 @@
39
  color: #3b82f6;
40
  font-weight: 600;
41
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  </style>
43
  </head>
44
  <body class="bg-gray-50">
@@ -143,6 +156,21 @@
143
  <!-- Map View -->
144
  <div id="mapView" class="mb-8">
145
  <div id="map" class="map-container w-full"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  </div>
147
 
148
  <!-- List View (Hidden by default) -->
@@ -268,73 +296,73 @@
268
 
269
  <div>
270
  <label class="block text-gray-700 font-medium mb-2">Price</label>
271
- <select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
272
- <option value="free">Free</option>
273
- <option value="paid">Paid</option>
274
- </select>
275
- </div>
276
- </div>
277
-
278
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
279
- <div>
280
- <label class="block text-gray-700 font-medium mb-2">Age Range</label>
281
- <div class="flex flex-wrap gap-2">
282
- <label class="inline-flex items-center">
283
- <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 0-2
284
- </label>
285
- <label class="inline-flex items-center">
286
- <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 3-5
287
- </label>
288
- <label class="inline-flex items-center">
289
- <input type="checkbox" class="rounded border-gray-300 text-blue-500" checked> 6-9
290
- </label>
291
- <label class="inline-flex items-center">
292
- <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 10-12
293
- </label>
294
- <label class="inline-flex items-center">
295
- <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 13+
296
- </label>
297
- </div>
298
- </div>
299
-
300
- <div>
301
- <label class="block text-gray-700 font-medium mb-2">Activity Type</label>
302
- <div class="flex flex-wrap gap-2">
303
- <label class="inline-flex items-center">
304
- <input type="radio" name="locationType" class="rounded-full border-gray-300 text-blue-500" checked> Indoor
305
- </label>
306
- <label class="inline-flex items-center">
307
- <input type="radio" name="locationType" class="rounded-full border-gray-300 text-blue-500"> Outdoor
308
- </label>
309
- </div>
310
- </div>
311
- </div>
312
-
313
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
314
- <div>
315
- <label class="block text-gray-700 font-medium mb-2">Duration</label>
316
- <select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
317
- <option value="permanent">Permanent</option>
318
- <option value="temporary">Temporary</option>
319
- </select>
320
- </div>
321
-
322
- <div>
323
- <label class="block text-gray-700 font-medium mb-2">Upload Images</label>
324
- <div class="border-2 border-dashed border-gray-300 rounded-lg p-4 text-center">
325
- <i class="fas fa-cloud-upload-alt text-3xl text-gray-400 mb-2"></i>
326
- <p class="text-gray-500">Drag & drop images here or click to browse</p>
327
- <input type="file" class="hidden" multiple>
328
- </div>
329
- </div>
330
- </div>
331
-
332
- <div class="pt-4">
333
- <button type="submit" class="w-full bg-green-500 hover:bg-green-600 text-white py-3 rounded-lg font-medium transition">
334
- Submit Activity
335
- </button>
336
- </div>
337
- </form>
338
  </div>
339
  </div>
340
  </div>
@@ -452,21 +480,30 @@
452
  </footer>
453
 
454
  <script>
455
- // Initialize map
456
  function initMap() {
 
 
 
 
457
  const map = new google.maps.Map(document.getElementById("map"), {
458
- center: { lat: 40.7128, lng: -74.0060 }, // Default to New York
459
  zoom: 12,
460
  styles: [
461
  {
462
  featureType: "poi",
463
  elementType: "labels",
464
  stylers: [{ visibility: "off" }]
 
 
 
 
 
465
  }
466
  ]
467
  });
468
 
469
- // Sample markers (in a real app, these would come from your database)
470
  const activities = [
471
  {
472
  name: "Discovery Children's Museum",
@@ -474,7 +511,11 @@
474
  type: "indoor",
475
  ages: "2-12",
476
  price: "paid",
477
- rating: 4.8
 
 
 
 
478
  },
479
  {
480
  name: "Sunshine Nature Park",
@@ -482,7 +523,11 @@
482
  type: "outdoor",
483
  ages: "all",
484
  price: "free",
485
- rating: 4.6
 
 
 
 
486
  },
487
  {
488
  name: "Creative Kids Art Studio",
@@ -490,7 +535,35 @@
490
  type: "indoor",
491
  ages: "5-12",
492
  price: "paid",
493
- rating: 4.9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  }
495
  ];
496
 
@@ -510,26 +583,39 @@
510
 
511
  // Info window content
512
  const contentString = `
513
- <div class="max-w-xs">
514
- <h3 class="font-bold text-lg">${activity.name}</h3>
515
- <div class="flex items-center my-1">
516
- <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-${activity.type === "indoor" ? "blue" : "green"}-100 text-${activity.type === "indoor" ? "blue" : "green"}-800 mr-2">
517
- ${activity.type === "indoor" ? "Indoor" : "Outdoor"}
518
- </span>
519
- <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
520
- Ages ${activity.ages}
521
- </span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522
  </div>
523
- <div class="flex items-center my-1">
524
- <span class="text-yellow-500">
525
- ${Array(Math.floor(activity.rating)).fill('<i class="fas fa-star"></i>').join('')}
526
- ${activity.rating % 1 ? '<i class="fas fa-star-half-alt"></i>' : ''}
527
- </span>
528
- <span class="ml-1 text-gray-600">(${activity.rating})</span>
529
  </div>
530
- <p class="text-sm text-gray-700 mt-1">${activity.price === "free" ? "Free admission" : "Paid activity"}</p>
531
- <button class="mt-2 px-3 py-1 bg-blue-500 text-white rounded-lg text-sm hover:bg-blue-600 transition">
532
- View Details
533
  </button>
534
  </div>
535
  `;
@@ -539,16 +625,113 @@
539
  });
540
 
541
  marker.addListener("click", () => {
 
 
 
 
 
542
  infowindow.open(map, marker);
543
  });
544
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
545
  }
546
 
547
  // Initialize the map when the page loads
548
  document.addEventListener("DOMContentLoaded", () => {
549
  // Note: In a real app, you would need a valid Google Maps API key
 
550
  // initMap();
551
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
  // Tab switching
553
  const mapTab = document.getElementById("mapTab");
554
  const listTab = document.getElementById("listTab");
 
39
  color: #3b82f6;
40
  font-weight: 600;
41
  }
42
+ .gm-style .gm-style-iw-c {
43
+ padding: 0 !important;
44
+ max-width: 300px !important;
45
+ }
46
+ .gm-style .gm-style-iw-d {
47
+ overflow: hidden !important;
48
+ }
49
+ .gm-style .gm-style-iw-t::after {
50
+ background: none !important;
51
+ }
52
+ .custom-info-window {
53
+ padding: 12px;
54
+ }
55
  </style>
56
  </head>
57
  <body class="bg-gray-50">
 
156
  <!-- Map View -->
157
  <div id="mapView" class="mb-8">
158
  <div id="map" class="map-container w-full"></div>
159
+ <div class="mt-4 flex justify-between items-center">
160
+ <div class="flex items-center space-x-4">
161
+ <div class="flex items-center">
162
+ <div class="w-4 h-4 rounded-full bg-blue-500 mr-2"></div>
163
+ <span class="text-sm">Indoor Activities</span>
164
+ </div>
165
+ <div class="flex items-center">
166
+ <div class="w-4 h-4 rounded-full bg-green-500 mr-2"></div>
167
+ <span class="text-sm">Outdoor Activities</span>
168
+ </div>
169
+ </div>
170
+ <button id="locateMeBtn" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition">
171
+ <i class="fas fa-location-arrow mr-2"></i>Find Near Me
172
+ </button>
173
+ </div>
174
  </div>
175
 
176
  <!-- List View (Hidden by default) -->
 
296
 
297
  <div>
298
  <label class="block text-gray-700 font-medium mb-2">Price</label>
299
+ <select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
300
+ <option value="free">Free</option>
301
+ <option value="paid">Paid</option>
302
+ </select>
303
+ </div>
304
+ </div>
305
+
306
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
307
+ <div>
308
+ <label class="block text-gray-700 font-medium mb-2">Age Range</label>
309
+ <div class="flex flex-wrap gap-2">
310
+ <label class="inline-flex items-center">
311
+ <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 0-2
312
+ </label>
313
+ <label class="inline-flex items-center">
314
+ <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 3-5
315
+ </label>
316
+ <label class="inline-flex items-center">
317
+ <input type="checkbox" class="rounded border-gray-300 text-blue-500" checked> 6-9
318
+ </label>
319
+ <label class="inline-flex items-center">
320
+ <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 10-12
321
+ </label>
322
+ <label class="inline-flex items-center">
323
+ <input type="checkbox" class="rounded border-gray-300 text-blue-500"> 13+
324
+ </label>
325
+ </div>
326
+ </div>
327
+
328
+ <div>
329
+ <label class="block text-gray-700 font-medium mb-2">Activity Type</label>
330
+ <div class="flex flex-wrap gap-2">
331
+ <label class="inline-flex items-center">
332
+ <input type="radio" name="locationType" class="rounded-full border-gray-300 text-blue-500" checked> Indoor
333
+ </label>
334
+ <label class="inline-flex items-center">
335
+ <input type="radio" name="locationType" class="rounded-full border-gray-300 text-blue-500"> Outdoor
336
+ </label>
337
+ </div>
338
+ </div>
339
+ </div>
340
+
341
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
342
+ <div>
343
+ <label class="block text-gray-700 font-medium mb-2">Duration</label>
344
+ <select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
345
+ <option value="permanent">Permanent</option>
346
+ <option value="temporary">Temporary</option>
347
+ </select>
348
+ </div>
349
+
350
+ <div>
351
+ <label class="block text-gray-700 font-medium mb-2">Upload Images</label>
352
+ <div class="border-2 border-dashed border-gray-300 rounded-lg p-4 text-center">
353
+ <i class="fas fa-cloud-upload-alt text-3xl text-gray-400 mb-2"></i>
354
+ <p class="text-gray-500">Drag & drop images here or click to browse</p>
355
+ <input type="file" class="hidden" multiple>
356
+ </div>
357
+ </div>
358
+ </div>
359
+
360
+ <div class="pt-4">
361
+ <button type="submit" class="w-full bg-green-500 hover:bg-green-600 text-white py-3 rounded-lg font-medium transition">
362
+ Submit Activity
363
+ </button>
364
+ </div>
365
+ </form>
366
  </div>
367
  </div>
368
  </div>
 
480
  </footer>
481
 
482
  <script>
483
+ // Initialize map with sample data
484
  function initMap() {
485
+ // Default to New York coordinates
486
+ const defaultLocation = { lat: 40.7128, lng: -74.0060 };
487
+
488
+ // Create map
489
  const map = new google.maps.Map(document.getElementById("map"), {
490
+ center: defaultLocation,
491
  zoom: 12,
492
  styles: [
493
  {
494
  featureType: "poi",
495
  elementType: "labels",
496
  stylers: [{ visibility: "off" }]
497
+ },
498
+ {
499
+ featureType: "transit",
500
+ elementType: "labels.icon",
501
+ stylers: [{ visibility: "off" }]
502
  }
503
  ]
504
  });
505
 
506
+ // Sample activities data
507
  const activities = [
508
  {
509
  name: "Discovery Children's Museum",
 
511
  type: "indoor",
512
  ages: "2-12",
513
  price: "paid",
514
+ rating: 4.8,
515
+ priceAmount: "$15",
516
+ description: "Interactive exhibits designed to spark curiosity and creativity in children of all ages.",
517
+ image: "https://images.unsplash.com/photo-1577896851231-70ef18881754?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
518
+ tags: ["Educational", "Hands-on", "STEM"]
519
  },
520
  {
521
  name: "Sunshine Nature Park",
 
523
  type: "outdoor",
524
  ages: "all",
525
  price: "free",
526
+ rating: 4.6,
527
+ priceAmount: "Free",
528
+ description: "Beautiful trails, playgrounds, and picnic areas perfect for family outings.",
529
+ image: "https://images.unsplash.com/photo-1517825738774-7de9363ef735?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
530
+ tags: ["Nature", "Playground", "Picnic"]
531
  },
532
  {
533
  name: "Creative Kids Art Studio",
 
535
  type: "indoor",
536
  ages: "5-12",
537
  price: "paid",
538
+ rating: 4.9,
539
+ priceAmount: "$25",
540
+ description: "Weekly art classes that encourage creativity and self-expression in children.",
541
+ image: "https://images.unsplash.com/photo-1571019613454-1cb2f99b2d8b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
542
+ tags: ["Arts & Crafts", "Painting", "Creative"]
543
+ },
544
+ {
545
+ name: "Little Explorers Science Center",
546
+ position: { lat: 40.7178, lng: -74.0030 },
547
+ type: "indoor",
548
+ ages: "3-10",
549
+ price: "paid",
550
+ rating: 4.7,
551
+ priceAmount: "$18",
552
+ description: "Hands-on science experiments and demonstrations for young curious minds.",
553
+ image: "https://images.unsplash.com/photo-1550751827-4bd374c3f58b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
554
+ tags: ["Science", "Experiments", "Learning"]
555
+ },
556
+ {
557
+ name: "Adventure Playground",
558
+ position: { lat: 40.7078, lng: -74.0210 },
559
+ type: "outdoor",
560
+ ages: "4-12",
561
+ price: "free",
562
+ rating: 4.5,
563
+ priceAmount: "Free",
564
+ description: "Unique playground with natural elements and creative play structures.",
565
+ image: "https://images.unsplash.com/photo-1565992441121-4367c2967103?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
566
+ tags: ["Playground", "Adventure", "Outdoor"]
567
  }
568
  ];
569
 
 
583
 
584
  // Info window content
585
  const contentString = `
586
+ <div class="custom-info-window">
587
+ <div class="flex items-start">
588
+ <img src="${activity.image}" alt="${activity.name}" class="w-24 h-24 object-cover rounded-lg mr-3">
589
+ <div>
590
+ <h3 class="font-bold text-lg">${activity.name}</h3>
591
+ <div class="flex items-center my-1">
592
+ <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${
593
+ activity.type === "indoor" ? "bg-blue-100 text-blue-800" : "bg-green-100 text-green-800"
594
+ } mr-2">
595
+ ${activity.type === "indoor" ? "Indoor" : "Outdoor"}
596
+ </span>
597
+ <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
598
+ Ages ${activity.ages}
599
+ </span>
600
+ </div>
601
+ <div class="flex items-center my-1">
602
+ <span class="text-yellow-500">
603
+ ${Array(Math.floor(activity.rating)).fill('<i class="fas fa-star"></i>').join('')}
604
+ ${activity.rating % 1 ? '<i class="fas fa-star-half-alt"></i>' : ''}
605
+ </span>
606
+ <span class="ml-1 text-gray-600">(${activity.rating})</span>
607
+ </div>
608
+ <p class="text-sm text-gray-700 mt-1">${activity.price === "free" ? "Free admission" : "Price: " + activity.priceAmount}</p>
609
+ </div>
610
  </div>
611
+ <div class="mt-2">
612
+ <p class="text-sm text-gray-700">${activity.description}</p>
613
+ <div class="flex flex-wrap gap-1 mt-2">
614
+ ${activity.tags.map(tag => `<span class="bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded">${tag}</span>`).join('')}
615
+ </div>
 
616
  </div>
617
+ <button class="w-full mt-3 px-3 py-2 bg-blue-500 text-white rounded-lg text-sm hover:bg-blue-600 transition">
618
+ View Details & Directions
 
619
  </button>
620
  </div>
621
  `;
 
625
  });
626
 
627
  marker.addListener("click", () => {
628
+ // Close any open info windows
629
+ if (window.currentInfoWindow) {
630
+ window.currentInfoWindow.close();
631
+ }
632
+ window.currentInfoWindow = infowindow;
633
  infowindow.open(map, marker);
634
  });
635
  });
636
+
637
+ // Try to get user's current location
638
+ if (navigator.geolocation) {
639
+ navigator.geolocation.getCurrentPosition(
640
+ (position) => {
641
+ const userLocation = {
642
+ lat: position.coords.latitude,
643
+ lng: position.coords.longitude
644
+ };
645
+
646
+ // Add user location marker
647
+ new google.maps.Marker({
648
+ position: userLocation,
649
+ map: map,
650
+ title: "Your Location",
651
+ icon: {
652
+ url: "https://maps.google.com/mapfiles/ms/icons/red-dot.png",
653
+ scaledSize: new google.maps.Size(32, 32)
654
+ }
655
+ });
656
+
657
+ // Center map on user location
658
+ map.setCenter(userLocation);
659
+ map.setZoom(14);
660
+ },
661
+ () => {
662
+ // If geolocation fails, use default location
663
+ console.log("Geolocation failed, using default location");
664
+ }
665
+ );
666
+ }
667
+
668
+ // Locate me button
669
+ document.getElementById('locateMeBtn').addEventListener('click', () => {
670
+ if (navigator.geolocation) {
671
+ navigator.geolocation.getCurrentPosition(
672
+ (position) => {
673
+ const userLocation = {
674
+ lat: position.coords.latitude,
675
+ lng: position.coords.longitude
676
+ };
677
+
678
+ // Pan to user location
679
+ map.panTo(userLocation);
680
+ map.setZoom(14);
681
+
682
+ // Add or update user location marker
683
+ if (window.userLocationMarker) {
684
+ window.userLocationMarker.setPosition(userLocation);
685
+ } else {
686
+ window.userLocationMarker = new google.maps.Marker({
687
+ position: userLocation,
688
+ map: map,
689
+ title: "Your Location",
690
+ icon: {
691
+ url: "https://maps.google.com/mapfiles/ms/icons/red-dot.png",
692
+ scaledSize: new google.maps.Size(32, 32)
693
+ }
694
+ });
695
+ }
696
+ },
697
+ () => {
698
+ alert("Unable to get your location. Please check your browser permissions.");
699
+ }
700
+ );
701
+ } else {
702
+ alert("Geolocation is not supported by your browser.");
703
+ }
704
+ });
705
  }
706
 
707
  // Initialize the map when the page loads
708
  document.addEventListener("DOMContentLoaded", () => {
709
  // Note: In a real app, you would need a valid Google Maps API key
710
+ // For demo purposes, we'll simulate the map initialization
711
  // initMap();
712
 
713
+ // Show a placeholder for the map since we don't have an API key
714
+ const mapContainer = document.getElementById('map');
715
+ mapContainer.innerHTML = `
716
+ <div class="w-full h-full bg-gray-200 rounded-xl flex items-center justify-center">
717
+ <div class="text-center p-6">
718
+ <i class="fas fa-map-marked-alt text-5xl text-blue-500 mb-4"></i>
719
+ <h3 class="text-xl font-bold text-gray-700 mb-2">Interactive Map</h3>
720
+ <p class="text-gray-600 mb-4">With a valid Google Maps API key, this would display an interactive map with activity locations.</p>
721
+ <div class="flex justify-center space-x-4">
722
+ <div class="flex items-center">
723
+ <div class="w-4 h-4 rounded-full bg-blue-500 mr-2"></div>
724
+ <span class="text-sm">Indoor</span>
725
+ </div>
726
+ <div class="flex items-center">
727
+ <div class="w-4 h-4 rounded-full bg-green-500 mr-2"></div>
728
+ <span class="text-sm">Outdoor</span>
729
+ </div>
730
+ </div>
731
+ </div>
732
+ </div>
733
+ `;
734
+
735
  // Tab switching
736
  const mapTab = document.getElementById("mapTab");
737
  const listTab = document.getElementById("listTab");