Welcome to Your Trip Planner
-Start planning your next adventure!
-Plan Trips
-Create and organize your travel itineraries
-Save Destinations
-Keep track of places you want to visit
-Share Plans
-Collaborate with friends and family
-diff --git a/backend/app/Http/Controllers/API/TripController.php b/backend/app/Http/Controllers/API/TripController.php new file mode 100644 index 0000000..3dab4c3 --- /dev/null +++ b/backend/app/Http/Controllers/API/TripController.php @@ -0,0 +1,90 @@ +user()->id) + ->orderBy('created_at', 'desc') + ->get(); + + return response()->json($trips); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request): JsonResponse + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'description' => 'nullable|string', + 'start_date' => 'nullable|date', + 'end_date' => 'nullable|date|after_or_equal:start_date', + ]); + + $validated['created_by_user_id'] = $request->user()->id; + + $trip = Trip::create($validated); + + return response()->json($trip, 201); + } + + /** + * Display the specified resource. + */ + public function show(Request $request, string $id): JsonResponse + { + $trip = Trip::where('id', $id) + ->where('created_by_user_id', $request->user()->id) + ->firstOrFail(); + + return response()->json($trip); + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id): JsonResponse + { + $trip = Trip::where('id', $id) + ->where('created_by_user_id', $request->user()->id) + ->firstOrFail(); + + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'description' => 'nullable|string', + 'start_date' => 'nullable|date', + 'end_date' => 'nullable|date|after_or_equal:start_date', + ]); + + $trip->update($validated); + + return response()->json($trip); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(Request $request, string $id): JsonResponse + { + $trip = Trip::where('id', $id) + ->where('created_by_user_id', $request->user()->id) + ->firstOrFail(); + + $trip->delete(); + + return response()->json(['message' => 'Trip deleted successfully']); + } +} diff --git a/backend/app/Models/Trip.php b/backend/app/Models/Trip.php new file mode 100644 index 0000000..296eb79 --- /dev/null +++ b/backend/app/Models/Trip.php @@ -0,0 +1,27 @@ + 'date', + 'end_date' => 'date', + ]; + + public function user(): BelongsTo + { + return $this->belongsTo(User::class, 'created_by_user_id'); + } +} diff --git a/backend/database/migrations/2025_09_27_004838_create_trips_table.php b/backend/database/migrations/2025_09_27_004838_create_trips_table.php new file mode 100644 index 0000000..8cb2d53 --- /dev/null +++ b/backend/database/migrations/2025_09_27_004838_create_trips_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('name'); + $table->text('description')->nullable(); + $table->date('start_date')->nullable(); + $table->date('end_date')->nullable(); + $table->foreignId('created_by_user_id')->constrained('users')->onDelete('cascade'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('trips'); + } +}; diff --git a/backend/routes/api.php b/backend/routes/api.php index 946570d..e387c42 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -1,6 +1,7 @@ =21.1.0" } }, + "node_modules/@heroicons/react": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", + "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16 || ^19.0.0-rc" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index e82bc18..f549e6f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@heroicons/react": "^2.2.0", "axios": "^1.12.2", "react": "^19.1.1", "react-dom": "^19.1.1" diff --git a/frontend/src/App.css b/frontend/src/App.css index 1532ab9..1321eb6 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1,3 +1,47 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Playfair+Display:wght@400;500;600;700&display=swap'); + +:root { + /* Color Palette from Coolors.co */ + --color-navy: #03071e; + --color-dark-red: #370617; + --color-burgundy: #6a040f; + --color-crimson: #9d0208; + --color-red: #d00000; + --color-red-orange: #dc2f02; + --color-orange: #e85d04; + --color-orange-yellow: #f48c06; + --color-yellow-orange: #faa307; + --color-yellow: #ffba08; + + /* Semantic colors */ + --primary-color: var(--color-orange); + --primary-hover: var(--color-red-orange); + --secondary-color: var(--color-burgundy); + --accent-color: var(--color-yellow-orange); + --danger-color: var(--color-crimson); + --danger-hover: var(--color-red); + --text-primary: var(--color-navy); + --text-secondary: var(--color-dark-red); + --text-muted: #666; + + /* Background colors */ + --bg-primary: #faf8f5; + --bg-secondary: #f5f1eb; + --bg-light: #fdf9f4; + --bg-card: #fbf7f2; + --bg-gradient: linear-gradient(135deg, #faf8f5 0%, #f5f1eb 100%); + + /* Typography */ + --font-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; + --font-secondary: 'Playfair Display', Georgia, 'Times New Roman', serif; + + /* Border radius */ + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 16px; +} + * { box-sizing: border-box; } @@ -5,14 +49,18 @@ body { margin: 0; padding: 0; + background: var(--bg-gradient); + min-height: 100vh; + font-family: var(--font-primary); + line-height: 1.6; } .App { min-height: 100vh; display: flex; - align-items: center; + align-items: flex-start; justify-content: center; - padding: 2rem; + padding: 0; width: 100vw; box-sizing: border-box; } @@ -26,7 +74,7 @@ body { .login-form { background: #f8f9fa; padding: 2rem; - border-radius: 8px; + border-radius: var(--radius-md); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); width: 100%; max-width: 400px; @@ -47,23 +95,29 @@ body { .form-group label { display: block; margin-bottom: 0.5rem; - font-weight: 500; - color: #555; + font-weight: 600; + color: var(--color-dark-red); + background: rgba(255, 244, 230, 0.3); + padding: 0.25rem 0.5rem; + border-radius: var(--radius-sm); + display: inline-block; } .form-group input { width: 100%; padding: 0.75rem; - border: 1px solid #ddd; - border-radius: 4px; + border: 1px solid var(--primary-color); + border-radius: var(--radius-md); font-size: 1rem; box-sizing: border-box; + background: #fff4e6; + color: #000; } .form-group input:focus { outline: none; - border-color: #007bff; - box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25); + border-color: var(--color-red-orange); + box-shadow: 0 0 0 2px rgba(220, 47, 2, 0.25); } .form-group input.error { @@ -80,7 +134,7 @@ body { .alert { padding: 0.75rem 1rem; margin-bottom: 1rem; - border-radius: 4px; + border-radius: var(--radius-sm); } .alert-success { @@ -98,21 +152,21 @@ body { button[type="submit"] { width: 100%; padding: 0.75rem; - background-color: #007bff; + background-color: var(--primary-color); color: white; border: none; - border-radius: 4px; + border-radius: var(--radius-sm); font-size: 1rem; cursor: pointer; transition: background-color 0.2s; } button[type="submit"]:hover:not(:disabled) { - background-color: #0056b3; + background-color: var(--primary-hover); } button[type="submit"]:disabled { - background-color: #6c757d; + background-color: var(--text-muted); cursor: not-allowed; } @@ -136,7 +190,7 @@ button[type="submit"]:disabled { .auth-toggle { display: flex; margin-bottom: 2rem; - border-radius: 8px; + border-radius: var(--radius-md); overflow: hidden; border: 1px solid #ddd; } @@ -151,7 +205,7 @@ button[type="submit"]:disabled { } .auth-toggle button.active { - background: #007bff; + background: var(--primary-color); color: white; } @@ -167,7 +221,7 @@ button[type="submit"]:disabled { .link-button { background: none; border: none; - color: #007bff; + color: var(--primary-color); cursor: pointer; text-decoration: underline; padding: 0; @@ -175,14 +229,29 @@ button[type="submit"]:disabled { } .link-button:hover { - color: #0056b3; + color: var(--primary-hover); } /* Dashboard Styles */ .dashboard { + width: 1200px; max-width: 1200px; margin: 0 auto; padding: 2rem; + position: relative; +} + +.dashboard::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 200px; + background: linear-gradient(135deg, var(--color-yellow) 0%, var(--color-orange) 50%, var(--color-red-orange) 100%); + opacity: 0.03; + border-radius: 0 0 50px 50px; + z-index: -1; } .dashboard-header { @@ -194,9 +263,74 @@ button[type="submit"]:disabled { border-bottom: 1px solid #eee; } +.dashboard-title { + display: flex; + align-items: center; +} + .dashboard-header h1 { margin: 0; - color: #333; + color: var(--text-primary); + background: linear-gradient(135deg, var(--color-yellow) 0%, var(--color-orange) 25%, var(--color-red-orange) 50%, var(--color-crimson) 75%, var(--color-dark-red) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + font-weight: 700; + font-size: 2rem; + font-family: var(--font-secondary); +} + +/* User menu styles */ +.user-dropdown { + position: relative; +} + +.user-menu-trigger { + background: var(--bg-card); + border: 1px solid var(--primary-color); + font-size: 0.875rem; + cursor: pointer; + padding: 0.5rem 0.75rem; + border-radius: 20px; + transition: all 0.2s; + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--text-primary); + font-weight: 500; +} + +.user-menu-trigger:hover { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--color-red-orange) 100%); + color: white; + border-color: var(--primary-color); +} + +.user-menu-trigger:focus { + outline: 2px solid var(--primary-color); + outline-offset: 2px; +} + +.dropdown-arrow { + font-size: 0.7rem; + transition: transform 0.2s; +} + +.user-dropdown[data-open="true"] .dropdown-arrow { + transform: rotate(180deg); +} + +.user-dropdown-menu { + position: absolute; + top: 100%; + right: 0; + background: var(--bg-card); + border: 1px solid rgba(228, 93, 4, 0.2); + border-radius: var(--radius-md); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + z-index: 1000; + min-width: 120px; + margin-top: 0.5rem; } .user-info { @@ -205,18 +339,30 @@ button[type="submit"]:disabled { gap: 1rem; } -.logout-btn { - padding: 0.5rem 1rem; - background: #dc3545; - color: white; - border: none; - border-radius: 4px; - cursor: pointer; - transition: background-color 0.2s; +/* Trips section header */ +.trips-section-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0; } -.logout-btn:hover { - background: #c82333; +.create-trip-btn-small { + padding: 0.5rem 1rem; + background: var(--primary-color); + color: white; + border: none; + border-radius: 6px; + cursor: pointer; + font-weight: 500; + font-size: 0.875rem; + transition: all 0.2s; + margin-top: 0.2rem; +} + +.create-trip-btn-small:hover { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--color-red-orange) 100%); + transform: translateY(-1px); } .welcome-section { @@ -239,7 +385,7 @@ button[type="submit"]:disabled { .feature-card { background: #f8f9fa; padding: 2rem; - border-radius: 8px; + border-radius: var(--radius-md); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); text-align: center; } @@ -271,7 +417,7 @@ button[type="submit"]:disabled { text-align: center; padding: 3rem; background: #f8f9fa; - border-radius: 8px; + border-radius: var(--radius-md); margin: 2rem 0; } @@ -283,3 +429,529 @@ button[type="submit"]:disabled { .unauthorized-container p { color: #666; } + +/* Trip Styles */ +.trips-section { + margin-top: 4rem; + position: relative; +} + +.trips-section::before { + content: ''; + position: absolute; + top: -3.5rem; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent 0%, var(--color-yellow) 20%, var(--color-orange) 40%, var(--color-red-orange) 60%, var(--color-crimson) 80%, transparent 100%); + opacity: 0.6; +} + +.trips-section-title { + background: linear-gradient(135deg, #6a040f 0%, #370617 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 1.5rem; + font-size: 2rem; + font-weight: 700; + font-family: var(--font-secondary); +} + +.trips-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; + margin-top: 0; +} + +.trip-card { + background: var(--bg-card); + border-radius: 12px; + padding: 1.5rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + transition: all 0.3s ease; + position: relative; + border: 1px solid rgba(228, 93, 4, 0.1); + overflow: hidden; +} + +.trip-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--color-orange) 0%, var(--color-yellow-orange) 50%, var(--color-yellow) 100%); +} + +.trip-card:hover { + box-shadow: 0 8px 30px rgba(228, 93, 4, 0.15); + transform: translateY(-4px) scale(1.02); +} + +.add-trip-card { + background: var(--bg-card); + border: 4px dashed var(--primary-color); + border-radius: 12px; + padding: 1.5rem; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + min-height: 200px; + opacity: 0.8; +} + +.add-trip-card:hover { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--color-red-orange) 100%); + border-color: var(--primary-hover); + transform: translateY(-2px); + opacity: 1; +} + +.add-trip-card:hover .add-trip-content { + color: white; +} + +.add-trip-card:hover .add-trip-icon { + color: white; +} + +.add-trip-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + color: var(--primary-color); + transition: color 0.3s ease; +} + +.add-trip-icon { + width: 4rem; + height: 4rem; + color: var(--primary-color); +} + +.add-trip-text { + font-size: 1.3rem; + font-weight: 600; +} + +.trip-card-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 1rem; +} + +.trip-card-title { + margin: 0; + color: var(--primary-color); + font-size: 1.25rem; + line-height: 1.3; + flex: 1; + margin-right: 1rem; + position: relative; +} + +.trip-card-title::before { + content: '🗺️'; + font-size: 0.9rem; + margin-right: 0.5rem; + opacity: 0.7; +} + +.trip-card-menu { + position: relative; +} + +.trip-menu-trigger { + background: none; + border: none; + font-size: 1.25rem; + cursor: pointer; + padding: 0.25rem; + color: #666; + border-radius: var(--radius-sm); + transition: background-color 0.2s; +} + +.trip-menu-trigger:hover { + background: #e9ecef; +} + +.trip-dropdown { + position: absolute; + top: 100%; + right: 0; + background: white; + border: 1px solid #ddd; + border-radius: var(--radius-sm); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + z-index: 1000; + min-width: 120px; +} + +.dropdown-item { + display: block; + width: 100%; + padding: 0.5rem 1rem; + border: none; + background: none; + text-align: left; + cursor: pointer; + transition: background-color 0.2s; + color: #333; +} + +.dropdown-item:hover { + background: #f8f9fa; +} + +.dropdown-item-danger { + color: var(--danger-color); +} + +.dropdown-item-danger:hover { + background: #f8d7da; + color: var(--danger-hover); +} + +.trip-card-description { + color: #666; + margin: 0 0 1rem 0; + line-height: 1.5; +} + +.trip-card-dates { + margin-bottom: 1rem; +} + +.trip-date-range { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.trip-dates { + font-weight: 500; + color: var(--text-primary); +} + +.trip-duration { + font-size: 0.875rem; + color: #666; +} + +.trip-dates-placeholder { + color: #999; + font-style: italic; +} + +.trip-card-footer { + border-top: 1px solid #e9ecef; + padding-top: 0.75rem; + margin-top: 1rem; +} + +.trip-created { + font-size: 0.875rem; + color: #999; +} + +.empty-state { + text-align: center; + padding: 3rem 2rem; + background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-light) 100%); + border-radius: 16px; + margin-top: 2rem; + border: 2px dashed rgba(228, 93, 4, 0.2); + position: relative; +} + +.empty-state::before { + content: '✈️'; + font-size: 3rem; + display: block; + margin-bottom: 1rem; + opacity: 0.6; +} + +.empty-state h3 { + color: #666; + margin-bottom: 0.5rem; +} + +.empty-state p { + color: #999; + margin: 0; +} + +/* Modal Styles */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(3, 7, 30, 0.8); + backdrop-filter: blur(4px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + padding: 1rem; + animation: modalOverlayFadeIn 0.2s ease-out; +} + +@keyframes modalOverlayFadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes modalSlideIn { + from { + opacity: 0; + transform: translateY(-20px) scale(0.95); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.modal-content { + background: var(--bg-card); + border-radius: var(--radius-md); + width: 100%; + max-width: 500px; + max-height: 90vh; + overflow: hidden; + box-shadow: + 0 25px 80px rgba(3, 7, 30, 0.4), + 0 0 0 1px rgba(228, 93, 4, 0.1); + animation: modalSlideIn 0.3s ease-out; + position: relative; +} + +.modal-content::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, var(--color-orange) 0%, var(--color-red-orange) 50%, var(--color-crimson) 100%); +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 2rem 2rem 1rem; + background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-light) 100%); +} + +.modal-header h2 { + margin: 0; + color: var(--text-primary); + font-size: 1.5rem; + font-weight: 700; + background: linear-gradient(135deg, var(--primary-color) 0%, var(--color-red-orange) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.modal-close { + background: var(--bg-secondary); + border: 1px solid rgba(228, 93, 4, 0.2); + font-size: 1.25rem; + cursor: pointer; + color: var(--primary-color); + padding: 0; + width: 2.5rem; + height: 2.5rem; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + transition: all 0.2s ease; + font-weight: 300; +} + +.modal-close:hover { + background: var(--primary-color); + color: white; + transform: scale(1.1); +} + +.modal-body { + padding: 0 2rem; + max-height: calc(90vh - 200px); + overflow-y: auto; +} + +.trip-form { + padding: 1.5rem 0; +} + +.trip-form .form-group { + margin-bottom: 1.5rem; +} + +.trip-form textarea { + width: 100%; + padding: 0.75rem; + border: 1px solid var(--primary-color); + border-radius: var(--radius-md); + font-size: 1rem; + font-family: inherit; + resize: vertical; + min-height: 80px; + box-sizing: border-box; + background: #fff4e6; + color: #000; +} + +.trip-form textarea:focus { + outline: none; + border-color: var(--color-red-orange); + box-shadow: 0 0 0 2px rgba(220, 47, 2, 0.25); +} + +.date-format-hint { + font-size: 0.875rem; + color: #666; + font-weight: normal; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; +} + +.modal-actions { + display: flex; + justify-content: flex-end; + gap: 1rem; + padding: 1.5rem; + border-top: 1px solid rgba(228, 93, 4, 0.1); + background: var(--bg-secondary); + border-radius: 0 0 16px 16px; +} + +.btn-primary { + padding: 0.75rem 1.5rem; + background: var(--primary-color); + color: white; + border: none; + border-radius: var(--radius-md); + cursor: pointer; + font-weight: 500; + transition: background-color 0.2s; +} + +.btn-primary:hover:not(:disabled) { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--color-red-orange) 100%); +} + +.btn-primary:disabled { + background: var(--text-muted); + cursor: not-allowed; +} + +.btn-secondary { + padding: 0.75rem 1.5rem; + background: transparent; + color: var(--secondary-color); + border: 2px solid var(--secondary-color); + border-radius: var(--radius-md); + cursor: pointer; + font-weight: 500; + transition: all 0.2s; +} + +.btn-secondary:hover:not(:disabled) { + background: linear-gradient(135deg, var(--secondary-color) 0%, var(--color-burgundy) 100%); + border-color: var(--color-burgundy); + color: white; + transform: translateY(-1px); +} + +.btn-secondary:disabled { + background: var(--text-muted); + cursor: not-allowed; +} + +.btn-danger { + padding: 0.75rem 1.5rem; + background: var(--danger-color); + color: white; + border: none; + border-radius: var(--radius-md); + cursor: pointer; + font-weight: 500; + transition: background-color 0.2s; +} + +.btn-danger:hover:not(:disabled) { + background: var(--danger-hover); +} + +.btn-danger:disabled { + background: var(--text-muted); + cursor: not-allowed; +} + +.confirm-dialog { + max-width: 400px; +} + +.confirm-dialog-body { + padding: 1.5rem; +} + +.confirm-dialog-body p { + margin: 0; + color: var(--text-primary); + line-height: 1.5; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .dashboard { + padding: 1rem; + } + + .dashboard-header { + flex-direction: column; + gap: 1rem; + align-items: stretch; + } + + .dashboard-header-actions { + justify-content: space-between; + } + + .trips-grid { + grid-template-columns: 1fr; + } + + .form-row { + grid-template-columns: 1fr; + } + + .modal-content { + margin: 1rem; + max-width: none; + } + + .modal-actions { + flex-direction: column; + } +} diff --git a/frontend/src/components/BaseModal.jsx b/frontend/src/components/BaseModal.jsx new file mode 100644 index 0000000..589efe4 --- /dev/null +++ b/frontend/src/components/BaseModal.jsx @@ -0,0 +1,48 @@ +const BaseModal = ({ + isOpen, + onClose, + title, + children, + actions, + maxWidth = "500px", + className = "" +}) => { + if (!isOpen) return null; + + const handleOverlayClick = (e) => { + if (e.target === e.currentTarget) { + onClose(); + } + }; + + return ( +
{message}
+Start planning your next adventure!
-Create and organize your travel itineraries
-Keep track of places you want to visit
-Collaborate with friends and family
-{trip.description}
+ )} + +