Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Travel Companion App</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --primary: #4361ee; | |
| --secondary: #3f37c9; | |
| --accent: #4cc9f0; | |
| --light: #f8f9fa; | |
| --dark: #212529; | |
| --success: #4ade80; | |
| --warning: #facc15; | |
| --danger: #f87171; | |
| --radius: 12px; | |
| --shadow: 0 10px 20px rgba(0,0,0,0.1); | |
| --transition: all 0.3s ease; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%); | |
| color: var(--dark); | |
| min-height: 100vh; | |
| overflow-x: hidden; | |
| } | |
| .app-container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| /* Splash Screen */ | |
| .splash-screen { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%); | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| z-index: 1000; | |
| transition: opacity 0.8s ease, visibility 0.8s; | |
| } | |
| .splash-content { | |
| text-align: center; | |
| color: white; | |
| padding: 20px; | |
| } | |
| .logo { | |
| font-size: 4rem; | |
| margin-bottom: 20px; | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.1); } | |
| 100% { transform: scale(1); } | |
| } | |
| .app-name { | |
| font-family: 'Playfair Display', serif; | |
| font-size: 3rem; | |
| margin-bottom: 10px; | |
| letter-spacing: 1px; | |
| } | |
| .tagline { | |
| font-size: 1.2rem; | |
| margin-bottom: 40px; | |
| max-width: 500px; | |
| } | |
| .start-btn { | |
| background: white; | |
| color: var(--primary); | |
| border: none; | |
| padding: 15px 40px; | |
| font-size: 1.1rem; | |
| font-weight: 600; | |
| border-radius: 50px; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| box-shadow: var(--shadow); | |
| } | |
| .start-btn:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 15px 25px rgba(0,0,0,0.2); | |
| } | |
| /* Main App */ | |
| .main-app { | |
| display: none; | |
| opacity: 0; | |
| transition: opacity 0.5s ease; | |
| } | |
| /* Header */ | |
| .app-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 20px 0; | |
| margin-bottom: 30px; | |
| } | |
| .header-title { | |
| font-family: 'Playfair Display', serif; | |
| font-size: 2rem; | |
| color: var(--secondary); | |
| } | |
| .user-actions { | |
| display: flex; | |
| gap: 15px; | |
| } | |
| .icon-btn { | |
| background: white; | |
| border: none; | |
| width: 45px; | |
| height: 45px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| box-shadow: var(--shadow); | |
| transition: var(--transition); | |
| color: var(--primary); | |
| } | |
| .icon-btn:hover { | |
| background: var(--primary); | |
| color: white; | |
| transform: translateY(-3px); | |
| } | |
| /* Navigation */ | |
| .app-nav { | |
| display: flex; | |
| overflow-x: auto; | |
| gap: 10px; | |
| padding: 10px 0; | |
| margin-bottom: 30px; | |
| scrollbar-width: none; | |
| } | |
| .app-nav::-webkit-scrollbar { | |
| display: none; | |
| } | |
| .nav-item { | |
| background: white; | |
| padding: 12px 25px; | |
| border-radius: var(--radius); | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| white-space: nowrap; | |
| box-shadow: var(--shadow); | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .nav-item.active { | |
| background: var(--primary); | |
| color: white; | |
| } | |
| .nav-item:hover:not(.active) { | |
| background: #eef2ff; | |
| } | |
| /* Module Container */ | |
| .module-container { | |
| background: white; | |
| border-radius: var(--radius); | |
| box-shadow: var(--shadow); | |
| padding: 30px; | |
| margin-bottom: 30px; | |
| display: none; | |
| } | |
| .module-container.active { | |
| display: block; | |
| animation: fadeIn 0.5s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .module-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 25px; | |
| padding-bottom: 15px; | |
| border-bottom: 2px solid #f0f4f8; | |
| } | |
| .module-title { | |
| font-size: 1.8rem; | |
| color: var(--secondary); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .module-actions { | |
| display: flex; | |
| gap: 10px; | |
| } | |
| /* Journal Module */ | |
| .journal-entry { | |
| margin-bottom: 25px; | |
| padding: 20px; | |
| border-radius: var(--radius); | |
| background: #f8fafc; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.05); | |
| } | |
| .entry-header { | |
| display: flex; | |
| justify-content: space-between; | |
| margin-bottom: 15px; | |
| color: #64748b; | |
| font-size: 0.9rem; | |
| } | |
| .entry-content { | |
| margin-bottom: 15px; | |
| line-height: 1.6; | |
| } | |
| .entry-photos { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); | |
| gap: 10px; | |
| margin-top: 15px; | |
| } | |
| .photo-thumb { | |
| width: 100%; | |
| aspect-ratio: 1/1; | |
| border-radius: 8px; | |
| object-fit: cover; | |
| } | |
| .new-entry-form { | |
| background: #f1f5f9; | |
| padding: 25px; | |
| border-radius: var(--radius); | |
| margin-top: 30px; | |
| } | |
| .form-group { | |
| margin-bottom: 20px; | |
| } | |
| .form-label { | |
| display: block; | |
| margin-bottom: 8px; | |
| font-weight: 500; | |
| } | |
| .form-input, .form-textarea { | |
| width: 100%; | |
| padding: 12px 15px; | |
| border: 1px solid #cbd5e1; | |
| border-radius: 8px; | |
| font-family: 'Poppins', sans-serif; | |
| font-size: 1rem; | |
| } | |
| .form-textarea { | |
| min-height: 150px; | |
| resize: vertical; | |
| } | |
| .photo-upload { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-top: 10px; | |
| } | |
| .upload-btn { | |
| background: var(--accent); | |
| color: white; | |
| border: none; | |
| padding: 8px 15px; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| } | |
| .submit-btn { | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| padding: 12px 25px; | |
| border-radius: 8px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .submit-btn:hover { | |
| background: var(--secondary); | |
| transform: translateY(-2px); | |
| } | |
| /* Trip Builder */ | |
| .trip-days { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| } | |
| .day-card { | |
| background: #f8fafc; | |
| border-radius: var(--radius); | |
| padding: 20px; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.05); | |
| } | |
| .day-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 15px; | |
| padding-bottom: 10px; | |
| border-bottom: 1px dashed #cbd5e1; | |
| } | |
| .day-title { | |
| font-weight: 600; | |
| color: var(--secondary); | |
| } | |
| .day-actions { | |
| display: flex; | |
| gap: 10px; | |
| } | |
| .activity-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 15px; | |
| } | |
| .activity-item { | |
| display: flex; | |
| align-items: center; | |
| padding: 12px 15px; | |
| background: white; | |
| border-radius: 8px; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.05); | |
| } | |
| .drag-handle { | |
| cursor: move; | |
| margin-right: 12px; | |
| color: #94a3b8; | |
| } | |
| .activity-content { | |
| flex: 1; | |
| } | |
| .activity-time { | |
| font-size: 0.9rem; | |
| color: #64748b; | |
| margin-bottom: 5px; | |
| } | |
| .add-activity { | |
| display: flex; | |
| gap: 10px; | |
| margin-top: 15px; | |
| } | |
| .activity-input { | |
| flex: 1; | |
| padding: 10px 15px; | |
| border: 1px solid #cbd5e1; | |
| border-radius: 8px; | |
| } | |
| .add-btn { | |
| background: var(--success); | |
| color: white; | |
| border: none; | |
| border-radius: 8px; | |
| width: 40px; | |
| cursor: pointer; | |
| } | |
| .add-day-btn { | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| padding: 12px 20px; | |
| border-radius: 8px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| margin-top: 20px; | |
| } | |
| /* Nearby Discovery */ | |
| .map-container { | |
| height: 400px; | |
| border-radius: var(--radius); | |
| overflow: hidden; | |
| margin-bottom: 25px; | |
| background: #e2e8f0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| position: relative; | |
| } | |
| .map-placeholder { | |
| text-align: center; | |
| color: #64748b; | |
| } | |
| .discovery-controls { | |
| display: flex; | |
| gap: 15px; | |
| margin-bottom: 20px; | |
| flex-wrap: wrap; | |
| } | |
| .filter-btn { | |
| background: white; | |
| border: 1px solid #cbd5e1; | |
| padding: 8px 15px; | |
| border-radius: 20px; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| } | |
| .filter-btn.active { | |
| background: var(--primary); | |
| color: white; | |
| border-color: var(--primary); | |
| } | |
| .poi-list { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); | |
| gap: 20px; | |
| } | |
| .poi-card { | |
| background: white; | |
| border-radius: var(--radius); | |
| overflow: hidden; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.05); | |
| transition: var(--transition); | |
| } | |
| .poi-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 15px rgba(0,0,0,0.1); | |
| } | |
| .poi-image { | |
| width: 100%; | |
| height: 150px; | |
| object-fit: cover; | |
| } | |
| .poi-content { | |
| padding: 15px; | |
| } | |
| .poi-name { | |
| font-weight: 600; | |
| margin-bottom: 8px; | |
| } | |
| .poi-details { | |
| display: flex; | |
| justify-content: space-between; | |
| color: #64748b; | |
| font-size: 0.9rem; | |
| } | |
| /* Weather & Suggestions */ | |
| .weather-container { | |
| display: flex; | |
| gap: 30px; | |
| margin-bottom: 30px; | |
| flex-wrap: wrap; | |
| } | |
| .current-weather { | |
| flex: 1; | |
| min-width: 300px; | |
| background: linear-gradient(135deg, #4cc9f0 0%, #4361ee 100%); | |
| border-radius: var(--radius); | |
| padding: 25px; | |
| color: white; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: space-between; | |
| } | |
| .weather-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .weather-temp { | |
| font-size: 3rem; | |
| font-weight: 700; | |
| } | |
| .weather-icon { | |
| font-size: 3rem; | |
| } | |
| .weather-details { | |
| display: grid; | |
| grid-template-columns: repeat(2, 1fr); | |
| gap: 15px; | |
| margin-top: 20px; | |
| } | |
| .weather-item { | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .weather-label { | |
| font-size: 0.9rem; | |
| opacity: 0.8; | |
| } | |
| .weather-value { | |
| font-weight: 600; | |
| font-size: 1.1rem; | |
| } | |
| .suggestions { | |
| flex: 1; | |
| min-width: 300px; | |
| background: white; | |
| border-radius: var(--radius); | |
| padding: 25px; | |
| box-shadow: var(--shadow); | |
| } | |
| .suggestion-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 15px; | |
| margin-top: 20px; | |
| } | |
| .suggestion-item { | |
| display: flex; | |
| gap: 15px; | |
| padding: 15px; | |
| border-radius: 8px; | |
| background: #f8fafc; | |
| } | |
| .suggestion-icon { | |
| background: #dbeafe; | |
| color: var(--primary); | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-shrink: 0; | |
| } | |
| /* Event Calendar */ | |
| .calendar-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 20px; | |
| } | |
| .calendar-nav { | |
| display: flex; | |
| gap: 10px; | |
| } | |
| .calendar-grid { | |
| display: grid; | |
| grid-template-columns: repeat(7, 1fr); | |
| gap: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .calendar-day { | |
| text-align: center; | |
| font-weight: 600; | |
| color: #64748b; | |
| padding: 10px; | |
| } | |
| .calendar-dates { | |
| display: grid; | |
| grid-template-columns: repeat(7, 1fr); | |
| gap: 10px; | |
| } | |
| .calendar-date { | |
| aspect-ratio: 1/1; | |
| background: #f8fafc; | |
| border-radius: 8px; | |
| display: flex; | |
| flex-direction: column; | |
| padding: 10px; | |
| position: relative; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| } | |
| .calendar-date:hover { | |
| background: #e0f2fe; | |
| } | |
| .date-number { | |
| font-weight: 600; | |
| margin-bottom: 5px; | |
| } | |
| .calendar-event { | |
| background: var(--accent); | |
| color: white; | |
| font-size: 0.7rem; | |
| padding: 3px 6px; | |
| border-radius: 4px; | |
| margin-top: 5px; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| } | |
| .event-modal { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0,0,0,0.5); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| z-index: 1000; | |
| opacity: 0; | |
| visibility: hidden; | |
| transition: var(--transition); | |
| } | |
| .event-modal.active { | |
| opacity: 1; | |
| visibility: visible; | |
| } | |
| .modal-content { | |
| background: white; | |
| width: 90%; | |
| max-width: 500px; | |
| border-radius: var(--radius); | |
| padding: 30px; | |
| position: relative; | |
| } | |
| .close-modal { | |
| position: absolute; | |
| top: 15px; | |
| right: 15px; | |
| background: none; | |
| border: none; | |
| font-size: 1.5rem; | |
| cursor: pointer; | |
| color: #64748b; | |
| } | |
| /* Live Location */ | |
| .location-container { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| text-align: center; | |
| padding: 40px 20px; | |
| } | |
| .location-icon { | |
| background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%); | |
| width: 100px; | |
| height: 100px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin-bottom: 30px; | |
| color: white; | |
| font-size: 2.5rem; | |
| } | |
| .location-text { | |
| max-width: 500px; | |
| margin-bottom: 30px; | |
| line-height: 1.6; | |
| } | |
| .location-btn { | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| padding: 15px 40px; | |
| border-radius: 50px; | |
| font-size: 1.1rem; | |
| font-weight: 500; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| transition: var(--transition); | |
| } | |
| .location-btn:hover { | |
| background: var(--secondary); | |
| transform: translateY(-3px); | |
| box-shadow: var(--shadow); | |
| } | |
| /* Booking Integration */ | |
| .booking-form { | |
| display: flex; | |
| gap: 15px; | |
| margin-bottom: 30px; | |
| flex-wrap: wrap; | |
| } | |
| .url-input { | |
| flex: 1; | |
| min-width: 250px; | |
| padding: 12px 15px; | |
| border: 1px solid #cbd5e1; | |
| border-radius: 8px; | |
| font-size: 1rem; | |
| } | |
| .parse-btn { | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| padding: 12px 25px; | |
| border-radius: 8px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| } | |
| .booking-results { | |
| background: #f8fafc; | |
| border-radius: var(--radius); | |
| padding: 25px; | |
| } | |
| .booking-item { | |
| display: flex; | |
| gap: 20px; | |
| padding: 15px 0; | |
| border-bottom: 1px solid #e2e8f0; | |
| } | |
| .booking-item:last-child { | |
| border-bottom: none; | |
| } | |
| .booking-icon { | |
| color: var(--primary); | |
| font-size: 1.5rem; | |
| } | |
| .booking-details { | |
| flex: 1; | |
| } | |
| .booking-title { | |
| font-weight: 600; | |
| margin-bottom: 5px; | |
| } | |
| /* Export Module */ | |
| .export-options { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); | |
| gap: 20px; | |
| margin-bottom: 30px; | |
| } | |
| .export-card { | |
| background: white; | |
| border-radius: var(--radius); | |
| padding: 25px; | |
| text-align: center; | |
| box-shadow: var(--shadow); | |
| transition: var(--transition); | |
| cursor: pointer; | |
| border: 2px solid transparent; | |
| } | |
| .export-card:hover { | |
| transform: translateY(-5px); | |
| border-color: var(--primary); | |
| } | |
| .export-icon { | |
| font-size: 2.5rem; | |
| color: var(--primary); | |
| margin-bottom: 15px; | |
| } | |
| .export-name { | |
| font-weight: 600; | |
| margin-bottom: 10px; | |
| } | |
| .export-desc { | |
| color: #64748b; | |
| font-size: 0.9rem; | |
| margin-bottom: 20px; | |
| } | |
| .export-btn { | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| padding: 8px 20px; | |
| border-radius: 6px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| } | |
| .export-btn:hover { | |
| background: var(--secondary); | |
| } | |
| /* Responsive Design */ | |
| @media (max-width: 768px) { | |
| .app-nav { | |
| padding: 10px 5px; | |
| } | |
| .nav-item { | |
| padding: 10px 15px; | |
| font-size: 0.9rem; | |
| } | |
| .module-container { | |
| padding: 20px; | |
| } | |
| .weather-container { | |
| flex-direction: column; | |
| } | |
| .calendar-dates, .calendar-grid { | |
| gap: 5px; | |
| } | |
| .calendar-date { | |
| padding: 5px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .app-header { | |
| flex-direction: column; | |
| align-items: flex-start; | |
| gap: 15px; | |
| } | |
| .discovery-controls, .add-activity, .booking-form { | |
| flex-direction: column; | |
| } | |
| .booking-form .parse-btn { | |
| width: 100%; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Splash Screen --> | |
| <div class="splash-screen" id="splashScreen"> | |
| <div class="splash-content"> | |
| <div class="logo"> | |
| <i class="fas fa-compass"></i> | |
| </div> | |
| <h1 class="app-name">Travel Companion</h1> | |
| <p class="tagline">Your all-in-one travel assistant for seamless journeys and unforgettable experiences</p> | |
| <button class="start-btn" id="startBtn"> | |
| Begin Journey <i class="fas fa-arrow-right"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Main App --> | |
| <div class="main-app" id="mainApp"> | |
| <div class="app-container"> | |
| <!-- Header --> | |
| <header class="app-header"> | |
| <h1 class="header-title">Travel Companion</h1> | |
| <div class="user-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-search"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-cog"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-user"></i> | |
| </button> | |
| </div> | |
| </header> | |
| <!-- Navigation --> | |
| <nav class="app-nav"> | |
| <div class="nav-item active" data-module="journal"> | |
| <i class="fas fa-book"></i> Journal | |
| </div> | |
| <div class="nav-item" data-module="trip"> | |
| <i class="fas fa-route"></i> Trip Builder | |
| </div> | |
| <div class="nav-item" data-module="nearby"> | |
| <i class="fas fa-map-marked-alt"></i> Nearby | |
| </div> | |
| <div class="nav-item" data-module="weather"> | |
| <i class="fas fa-cloud-sun"></i> Weather & AI | |
| </div> | |
| <div class="nav-item" data-module="calendar"> | |
| <i class="fas fa-calendar-alt"></i> Events | |
| </div> | |
| <div class="nav-item" data-module="location"> | |
| <i class="fas fa-location-dot"></i> Live Location | |
| </div> | |
| <div class="nav-item" data-module="booking"> | |
| <i class="fas fa-hotel"></i> Bookings | |
| </div> | |
| <div class="nav-item" data-module="export"> | |
| <i class="fas fa-file-export"></i> Export | |
| </div> | |
| </nav> | |
| <!-- Journal Module --> | |
| <section class="module-container active" id="journalModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-book"></i> Travel Journal | |
| </h2> | |
| <div class="module-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-sort"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-filter"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="journal-entry"> | |
| <div class="entry-header"> | |
| <span>Paris, France</span> | |
| <span>May 15, 2023 • 3:45 PM</span> | |
| </div> | |
| <div class="entry-content"> | |
| <h3>First Day in the City of Lights</h3> | |
| <p>Arrived in Paris this morning after a smooth flight. The view of the Eiffel Tower from my hotel room is absolutely breathtaking! Started my day with a croissant and café au lait at a charming little boulangerie near the hotel...</p> | |
| </div> | |
| <div class="entry-photos"> | |
| <img src="https://images.unsplash.com/photo-1502602898657-3e91760cbb34?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80" alt="Eiffel Tower" class="photo-thumb"> | |
| <img src="https://images.unsplash.com/photo-1559715541-5daf8a0296d0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80" alt="Paris street" class="photo-thumb"> | |
| <img src="https://images.unsplash.com/photo-1564507004663-b6dfb3c824d5?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80" alt="Croissant" class="photo-thumb"> | |
| </div> | |
| </div> | |
| <div class="journal-entry"> | |
| <div class="entry-header"> | |
| <span>Santorini, Greece</span> | |
| <span>May 10, 2023 • 6:20 PM</span> | |
| </div> | |
| <div class="entry-content"> | |
| <h3>Sunset in Oia</h3> | |
| <p>Today was magical! Spent the afternoon exploring the narrow streets of Oia with their iconic blue-domed churches. As evening approached, found the perfect spot to watch the sunset over the caldera...</p> | |
| </div> | |
| <div class="entry-photos"> | |
| <img src="https://images.unsplash.com/photo-1531590407785-ecd0b6f5c0d6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80" alt="Santorini" class="photo-thumb"> | |
| </div> | |
| </div> | |
| <div class="new-entry-form"> | |
| <h3>New Journal Entry</h3> | |
| <div class="form-group"> | |
| <label class="form-label">Title</label> | |
| <input type="text" class="form-input" placeholder="Entry title"> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label">Content</label> | |
| <textarea class="form-textarea" placeholder="Write about your experience..."></textarea> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label">Add Photos</label> | |
| <div class="photo-upload"> | |
| <button class="upload-btn"> | |
| <i class="fas fa-camera"></i> Choose Photos | |
| </button> | |
| <span>No photos selected</span> | |
| </div> | |
| </div> | |
| <button class="submit-btn"> | |
| <i class="fas fa-plus"></i> Add Entry | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Trip Builder Module --> | |
| <section class="module-container" id="tripModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-route"></i> Trip Builder | |
| </h2> | |
| <div class="module-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-save"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="trip-days"> | |
| <div class="day-card"> | |
| <div class="day-header"> | |
| <h3 class="day-title">Day 1: Arrival in Tokyo</h3> | |
| <div class="day-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-edit"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-trash"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="activity-list"> | |
| <div class="activity-item"> | |
| <div class="drag-handle"> | |
| <i class="fas fa-grip-lines"></i> | |
| </div> | |
| <div class="activity-content"> | |
| <div class="activity-time">10:00 AM</div> | |
| <div>Arrive at Narita Airport</div> | |
| </div> | |
| </div> | |
| <div class="activity-item"> | |
| <div class="drag-handle"> | |
| <i class="fas fa-grip-lines"></i> | |
| </div> | |
| <div class="activity-content"> | |
| <div class="activity-time">12:00 PM</div> | |
| <div>Check-in at Hotel Gracery Shinjuku</div> | |
| </div> | |
| </div> | |
| <div class="activity-item"> | |
| <div class="drag-handle"> | |
| <i class="fas fa-grip-lines"></i> | |
| </div> | |
| <div class="activity-content"> | |
| <div class="activity-time">2:00 PM</div> | |
| <div>Explore Shinjuku Gyoen National Garden</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="add-activity"> | |
| <input type="text" class="activity-input" placeholder="Add new activity"> | |
| <button class="add-btn"> | |
| <i class="fas fa-plus"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="day-card"> | |
| <div class="day-header"> | |
| <h3 class="day-title">Day 2: Cultural Exploration</h3> | |
| <div class="day-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-edit"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-trash"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="activity-list"> | |
| <div class="activity-item"> | |
| <div class="drag-handle"> | |
| <i class="fas fa-grip-lines"></i> | |
| </div> | |
| <div class="activity-content"> | |
| <div class="activity-time">9:00 AM</div> | |
| <div>Visit Senso-ji Temple in Asakusa</div> | |
| </div> | |
| </div> | |
| <div class="activity-item"> | |
| <div class="drag-handle"> | |
| <i class="fas fa-grip-lines"></i> | |
| </div> | |
| <div class="activity-content"> | |
| <div class="activity-time">1:00 PM</div> | |
| <div>Lunch at Tsukiji Fish Market</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="add-activity"> | |
| <input type="text" class="activity-input" placeholder="Add new activity"> | |
| <button class="add-btn"> | |
| <i class="fas fa-plus"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <button class="add-day-btn"> | |
| <i class="fas fa-plus"></i> Add New Day | |
| </button> | |
| </section> | |
| <!-- Nearby Discovery Module --> | |
| <section class="module-container" id="nearbyModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-map-marked-alt"></i> Nearby Discovery | |
| </h2> | |
| <div class="module-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-sync-alt"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="map-container"> | |
| <div class="map-placeholder"> | |
| <i class="fas fa-map-marked-alt" style="font-size: 3rem; margin-bottom: 15px;"></i> | |
| <h3>Interactive Map</h3> | |
| <p>Discover points of interest around your location</p> | |
| </div> | |
| </div> | |
| <div class="discovery-controls"> | |
| <button class="filter-btn active">All</button> | |
| <button class="filter-btn">Restaurants</button> | |
| <button class="filter-btn">Attractions</button> | |
| <button class="filter-btn">Hotels</button> | |
| <button class="filter-btn">Shopping</button> | |
| <button class="filter-btn">Nature</button> | |
| </div> | |
| <div class="poi-list"> | |
| <div class="poi-card"> | |
| <img src="https://images.unsplash.com/photo-1552566626-52f8b828add9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=600&q=80" alt="Restaurant" class="poi-image"> | |
| <div class="poi-content"> | |
| <div class="poi-name">Le Petit Bistro</div> | |
| <div class="poi-details"> | |
| <span>French Restaurant</span> | |
| <span>0.3 mi</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="poi-card"> | |
| <img src="https://images.unsplash.com/photo-1504674900247-0877df9cc836?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=600&q=80" alt="Museum" class="poi-image"> | |
| <div class="poi-content"> | |
| <div class="poi-name">City Art Museum</div> | |
| <div class="poi-details"> | |
| <span>Art Museum</span> | |
| <span>0.5 mi</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="poi-card"> | |
| <img src="https://images.unsplash.com/photo-1519671482749-fd09be7ccebf?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=600&q=80" alt="Park" class="poi-image"> | |
| <div class="poi-content"> | |
| <div class="poi-name">Central Park</div> | |
| <div class="poi-details"> | |
| <span>Public Park</span> | |
| <span>0.7 mi</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="poi-card"> | |
| <img src="https://images.unsplash.com/photo-1566073771259-6a8506099945?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=600&q=80" alt="Hotel" class="poi-image"> | |
| <div class="poi-content"> | |
| <div class="poi-name">Grand Plaza Hotel</div> | |
| <div class="poi-details"> | |
| <span>4-star Hotel</span> | |
| <span>0.4 mi</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Weather & Suggestions Module --> | |
| <section class="module-container" id="weatherModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-cloud-sun"></i> Weather & AI Suggestions | |
| </h2> | |
| <div class="module-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-location-dot"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="weather-container"> | |
| <div class="current-weather"> | |
| <div class="weather-header"> | |
| <div> | |
| <div class="weather-location">Paris, France</div> | |
| <div class="weather-date">Friday, May 26, 2023</div> | |
| </div> | |
| <div class="weather-icon"> | |
| <i class="fas fa-sun"></i> | |
| </div> | |
| </div> | |
| <div class="weather-temp">22°C</div> | |
| <div class="weather-condition">Sunny</div> | |
| <div class="weather-details"> | |
| <div class="weather-item"> | |
| <span class="weather-label">Feels Like</span> | |
| <span class="weather-value">24°C</span> | |
| </div> | |
| <div class="weather-item"> | |
| <span class="weather-label">Humidity</span> | |
| <span class="weather-value">45%</span> | |
| </div> | |
| <div class="weather-item"> | |
| <span class="weather-label">Wind</span> | |
| <span class="weather-value">12 km/h</span> | |
| </div> | |
| <div class="weather-item"> | |
| <span class="weather-label">UV Index</span> | |
| <span class="weather-value">6 (High)</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="suggestions"> | |
| <h3>AI-Powered Suggestions</h3> | |
| <p>Based on current weather and your preferences</p> | |
| <div class="suggestion-list"> | |
| <div class="suggestion-item"> | |
| <div class="suggestion-icon"> | |
| <i class="fas fa-umbrella-beach"></i> | |
| </div> | |
| <div> | |
| <div class="suggestion-title">Outdoor Activities</div> | |
| <div class="suggestion-desc">Perfect weather for a picnic in Luxembourg Gardens</div> | |
| </div> | |
| </div> | |
| <div class="suggestion-item"> | |
| <div class="suggestion-icon"> | |
| <i class="fas fa-utensils"></i> | |
| </div> | |
| <div> | |
| <div class="suggestion-title">Dining Recommendation</div> | |
| <div class="suggestion-desc">Try outdoor seating at Café de Flore for people watching</div> | |
| </div> | |
| </div> | |
| <div class="suggestion-item"> | |
| <div class="suggestion-icon"> | |
| <i class="fas fa-landmark"></i> | |
| </div> | |
| <div> | |
| <div class="suggestion-title">Cultural Experience</div> | |
| <div class="suggestion-desc">Visit the Louvre - less crowded in the afternoon</div> | |
| </div> | |
| </div> | |
| <div class="suggestion-item"> | |
| <div class="suggestion-icon"> | |
| <i class="fas fa-sun"></i> | |
| </div> | |
| <div> | |
| <div class="suggestion-title">Weather Tip</div> | |
| <div class="suggestion-desc">Wear sunscreen and a hat for sun protection</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Event Calendar Module --> | |
| <section class="module-container" id="calendarModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-calendar-alt"></i> Event Calendar | |
| </h2> | |
| <div class="module-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-download"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-plus"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="calendar-header"> | |
| <h3>June 2023</h3> | |
| <div class="calendar-nav"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-chevron-left"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-chevron-right"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="calendar-grid"> | |
| <div class="calendar-day">Sun</div> | |
| <div class="calendar-day">Mon</div> | |
| <div class="calendar-day">Tue</div> | |
| <div class="calendar-day">Wed</div> | |
| <div class="calendar-day">Thu</div> | |
| <div class="calendar-day">Fri</div> | |
| <div class="calendar-day">Sat</div> | |
| </div> | |
| <div class="calendar-dates"> | |
| <!-- Previous month dates --> | |
| <div class="calendar-date inactive"> | |
| <div class="date-number">28</div> | |
| </div> | |
| <div class="calendar-date inactive"> | |
| <div class="date-number">29</div> | |
| </div> | |
| <div class="calendar-date inactive"> | |
| <div class="date-number">30</div> | |
| </div> | |
| <div class="calendar-date inactive"> | |
| <div class="date-number">31</div> | |
| </div> | |
| <!-- Current month dates --> | |
| <div class="calendar-date"> | |
| <div class="date-number">1</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">2</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">3</div> | |
| <div class="calendar-event">Music Festival</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">4</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">5</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">6</div> | |
| <div class="calendar-event">Food Market</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">7</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">8</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">9</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">10</div> | |
| <div class="calendar-event">City Tour</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">11</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">12</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">13</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">14</div> | |
| <div class="calendar-event">Bastille Day</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">15</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">16</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">17</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">18</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">19</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">20</div> | |
| <div class="calendar-event">Wine Tasting</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">21</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">22</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">23</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">24</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">25</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">26</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">27</div> | |
| <div class="calendar-event">Art Exhibition</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">28</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">29</div> | |
| </div> | |
| <div class="calendar-date"> | |
| <div class="date-number">30</div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Live Location Module --> | |
| <section class="module-container" id="locationModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-location-dot"></i> Live Location Sharing | |
| </h2> | |
| </div> | |
| <div class="location-container"> | |
| <div class="location-icon"> | |
| <i class="fas fa-location-dot"></i> | |
| </div> | |
| <h3>Share Your Real-Time Location</h3> | |
| <p class="location-text"> | |
| Let your friends and family follow your journey in real-time. Share your location securely with selected contacts for a specified duration. | |
| </p> | |
| <button class="location-btn"> | |
| <i class="fas fa-share-alt"></i> Share My Location | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Booking Integration Module --> | |
| <section class="module-container" id="bookingModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-hotel"></i> Booking Integration | |
| </h2> | |
| </div> | |
| <div class="booking-form"> | |
| <input type="text" class="url-input" placeholder="Paste booking confirmation URL"> | |
| <button class="parse-btn">Parse Booking</button> | |
| </div> | |
| <div class="booking-results"> | |
| <div class="booking-item"> | |
| <div class="booking-icon"> | |
| <i class="fas fa-hotel"></i> | |
| </div> | |
| <div class="booking-details"> | |
| <div class="booking-title">Hotel Booking</div> | |
| <div>Grand Plaza Hotel, Paris</div> | |
| <div>Check-in: Jun 15, 2023 • Check-out: Jun 20, 2023</div> | |
| </div> | |
| </div> | |
| <div class="booking-item"> | |
| <div class="booking-icon"> | |
| <i class="fas fa-plane"></i> | |
| </div> | |
| <div class="booking-details"> | |
| <div class="booking-title">Flight Reservation</div> | |
| <div>New York (JFK) to Paris (CDG)</div> | |
| <div>June 14, 2023 • 8:30 PM</div> | |
| </div> | |
| </div> | |
| <div class="booking-item"> | |
| <div class="booking-icon"> | |
| <i class="fas fa-ticket-alt"></i> | |
| </div> | |
| <div class="booking-details"> | |
| <div class="booking-title">Event Tickets</div> | |
| <div>Louvre Museum Timed Entry</div> | |
| <div>June 16, 2023 • 2:00 PM</div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Export Module --> | |
| <section class="module-container" id="exportModule"> | |
| <div class="module-header"> | |
| <h2 class="module-title"> | |
| <i class="fas fa-file-export"></i> Export Your Data | |
| </h2> | |
| </div> | |
| <div class="export-options"> | |
| <div class="export-card"> | |
| <div class="export-icon"> | |
| <i class="fas fa-book"></i> | |
| </div> | |
| <div class="export-name">Journal Export</div> | |
| <div class="export-desc">Export your travel journal with photos as a beautiful PDF document</div> | |
| <button class="export-btn">Export PDF</button> | |
| </div> | |
| <div class="export-card"> | |
| <div class="export-icon"> | |
| <i class="fas fa-route"></i> | |
| </div> | |
| <div class="export-name">Trip Itinerary</div> | |
| <div class="export-desc">Download your trip itinerary as PDF or CSV for printing</div> | |
| <button class="export-btn">Export</button> | |
| </div> | |
| <div class="export-card"> | |
| <div class="export-icon"> | |
| <i class="fas fa-calendar-alt"></i> | |
| </div> | |
| <div class="export-name">Calendar Export</div> | |
| <div class="export-desc">Export your events calendar as ICS file for other calendars</div> | |
| <button class="export-btn">Export ICS</button> | |
| </div> | |
| <div class="export-card"> | |
| <div class="export-icon"> | |
| <i class="fas fa-map-marked-alt"></i> | |
| </div> | |
| <div class="export-name">Travel Map</div> | |
| <div class="export-desc">Generate a map with all your visited locations as an image</div> | |
| <button class="export-btn">Export Image</button> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| </div> | |
| <script> | |
| // Leaflet integration for maps | |
| const map = L.map('map').setView([0, 0], 13); | |
| // Define a function to initialize the map | |
| function initializeMap(lat, lng) { | |
| // Remove existing map container if exists | |
| const mapDiv = document.getElementById('map'); | |
| if (mapDiv) { | |
| mapDiv.style.display = 'block'; | |
| mapDiv.innerHTML = ''; | |
| } | |
| const map = L.map('map').setView([lat, lng], 13); | |
| L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { | |
| attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' | |
| }).addTo(map); | |
| L.marker([lat, lng]).addTo(map) | |
| .bindPopup('Your location') | |
| .openPopup(); | |
| } | |
| // Splash screen transition | |
| document.getElementById('startBtn').addEventListener('click', function() { | |
| const splashScreen = document.getElementById('splashScreen'); | |
| const mainApp = document.getElementById('mainApp'); | |
| // First get location to initialize map | |
| if (navigator.geolocation) { | |
| navigator.geolocation.getCurrentPosition(position => { | |
| const { latitude, longitude } = position.coords; | |
| splashScreen.style.opacity = '0'; | |
| splashScreen.style.visibility = 'hidden'; | |
| setTimeout(() => { | |
| mainApp.style.display = 'block'; | |
| setTimeout(() => { | |
| mainApp.style.opacity = '1'; | |
| initializeMap(latitude, longitude); | |
| }, 50); | |
| }, 800); | |
| }, showError); | |
| } else { | |
| // Handle case where geolocation is not available | |
| splashScreen.style.opacity = '0'; | |
| splashScreen.style.visibility = 'hidden'; | |
| setTimeout(() => { | |
| mainApp.style.display = 'block'; | |
| setTimeout(() => { | |
| mainApp.style.opacity = '1'; | |
| }, 50); | |
| }, 800); | |
| } | |
| }); | |
| function showError(error) { | |
| alert('Geolocation error: ' + error.message); | |
| } | |
| // Navigation between modules | |
| const navItems = document.querySelectorAll('.nav-item'); | |
| const modules = document.querySelectorAll('.module-container'); | |
| navItems.forEach(item => { | |
| item.addEventListener('click', function() { | |
| // Remove active class from all nav items and modules | |
| navItems.forEach(nav => nav.classList.remove('active')); | |
| modules.forEach(mod => mod.classList.remove('active')); | |
| // Add active class to clicked nav item | |
| this.classList.add('active'); | |
| // Show corresponding module | |
| const moduleId = this.getAttribute('data-module') + 'Module'; | |
| document.getElementById(moduleId).classList.add('active'); | |
| }); | |
| }); | |
| // Filter buttons for Nearby Discovery | |
| const filterButtons = document.querySelectorAll('.filter-btn'); | |
| filterButtons.forEach(button => { | |
| button.addEventListener('click', function() { | |
| filterButtons.forEach(btn => btn.classList.remove('active')); | |
| this.classList.add('active'); | |
| }); | |
| }); | |
| // Simple drag and drop for trip activities | |
| const activityItems = document.querySelectorAll('.activity-item'); | |
| activityItems.forEach(item => { | |
| item.setAttribute('draggable', true); | |
| item.addEventListener('dragstart', function(e) { | |
| e.dataTransfer.setData('text/plain', this.id); | |
| setTimeout(() => this.classList.add('dragging'), 0); | |
| }); | |
| item.addEventListener('dragend', function() { | |
| this.classList.remove('dragging'); | |
| }); | |
| }); | |
| // Add new activity | |
| const addButtons = document.querySelectorAll('.add-btn'); | |
| addButtons.forEach(button => { | |
| button.addEventListener('click', function() { | |
| const input = this.previousElementSibling; | |
| if (input.value.trim() !== '') { | |
| const activityList = this.closest('.day-card').querySelector('.activity-list'); | |
| const newActivity = document.createElement('div'); | |
| newActivity.className = 'activity-item'; | |
| newActivity.innerHTML = ` | |
| <div class="drag-handle"> | |
| <i class="fas fa-grip-lines"></i> | |
| </div> | |
| <div class="activity-content"> | |
| <div class="activity-time">New</div> | |
| <div>${input.value}</div> | |
| </div> | |
| `; | |
| activityList.appendChild(newActivity); | |
| input.value = ''; | |
| } | |
| }); | |
| }); | |
| // Add new day | |
| document.querySelector('.add-day-btn').addEventListener('click', function() { | |
| const tripDays = document.querySelector('.trip-days'); | |
| const dayCount = tripDays.children.length + 1; | |
| const newDay = document.createElement('div'); | |
| newDay.className = 'day-card'; | |
| newDay.innerHTML = ` | |
| <div class="day-header"> | |
| <h3 class="day-title">Day ${dayCount}: New Day</h3> | |
| <div class="day-actions"> | |
| <button class="icon-btn"> | |
| <i class="fas fa-edit"></i> | |
| </button> | |
| <button class="icon-btn"> | |
| <i class="fas fa-trash"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="activity-list"> | |
| <!-- Activities will be added here --> | |
| </div> | |
| <div class="add-activity"> | |
| <input type="text" class="activity-input" placeholder="Add new activity"> | |
| <button class="add-btn"> | |
| <i class="fas fa-plus"></i> | |
| </button> | |
| </div> | |
| `; | |
| tripDays.appendChild(newDay); | |
| // Add event listener to the new add button | |
| newDay.querySelector('.add-btn').addEventListener('click', function() { | |
| const input = this.previousElementSibling; | |
| if (input.value.trim() !== '') { | |
| const activityList = this.closest('.day-card').querySelector('.activity-list'); | |
| const newActivity = document.createElement('div'); | |
| newActivity.className = 'activity-item'; | |
| newActivity.innerHTML = ` | |
| <div class="drag-handle"> | |
| <i class="fas fa-grip-lines"></i> | |
| </div> | |
| <div class="activity-content"> | |
| <div class="activity-time">New</div> | |
| <div>${input.value}</div> | |
| </div> | |
| `; | |
| activityList.appendChild(newActivity); | |
| input.value = ''; | |
| } | |
| }); | |
| }); | |
| // Location sharing | |
| document.querySelector('.location-btn').addEventListener('click', function() { | |
| if (navigator.share) { | |
| navigator.share({ | |
| title: 'My Current Location', | |
| text: 'Follow my journey in real-time!', | |
| url: window.location.href | |
| }) | |
| .then(() => console.log('Shared successfully')) | |
| .catch(error => console.log('Sharing failed', error)); | |
| } else { | |
| alert('Web Share API not supported in your browser'); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |