diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index bc6fb98..190bc5b 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -177,6 +177,9 @@ "noShuttles": "No tourist routes available at the moment.", "filterRoute": "Filter by route", "allRoutes": "All routes", + "category": "Category", + "local": "Local", + "interprovincial": "Interprovincial", "tripType": "Trip type", "oneWay": "One way", "roundTrip": "Round trip", diff --git a/frontend/src/i18n/locales/es.json b/frontend/src/i18n/locales/es.json index 28a5ad8..3d19ec6 100644 --- a/frontend/src/i18n/locales/es.json +++ b/frontend/src/i18n/locales/es.json @@ -179,6 +179,9 @@ "noShuttles": "No hay rutas turísticas disponibles en este momento.", "filterRoute": "Filtrar por ruta", "allRoutes": "Todas las rutas", + "category": "Categoría", + "local": "Local", + "interprovincial": "Interprovincial", "tripType": "Tipo de viaje", "oneWay": "Ida", "roundTrip": "Vuelta", diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index b58bb3d..db93063 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -175,6 +175,7 @@ export interface Shuttle { phone_number?: string english_speaking?: boolean image_url?: string + category?: 'local' | 'interprovincial' | 'all' is_active: boolean created_at?: string updated_at?: string diff --git a/frontend/src/views/AdminShuttles.vue b/frontend/src/views/AdminShuttles.vue index ce44703..967d932 100644 --- a/frontend/src/views/AdminShuttles.vue +++ b/frontend/src/views/AdminShuttles.vue @@ -16,6 +16,8 @@ const shuttleForm = ref({ origin: 'Boquete', destination: 'Santa Catalina', vehicle_type: 'Mini Van Compartida', + category: 'local', + description: '', price_per_person: 35, price_private_trip: 180, estimated_duration: '4.5 horas', @@ -66,6 +68,8 @@ async function saveShuttle() { origin: shuttleForm.value.origin, destination: shuttleForm.value.destination, vehicle_type: shuttleForm.value.vehicle_type, + category: shuttleForm.value.category, + description: shuttleForm.value.description, company_name: shuttleForm.value.company_name, price_per_person: shuttleForm.value.price_per_person, price_private_trip: shuttleForm.value.price_private_trip, @@ -144,9 +148,28 @@ async function saveShuttle() { +
+
+ + +
+
+ + +
+
+
- - + +
@@ -276,6 +299,11 @@ async function saveShuttle() {
+ +
+

{{ shuttleForm.description }}

+
+
@@ -339,6 +367,7 @@ async function saveShuttle() { font-weight: 800; margin: 0; background: linear-gradient(135deg, #fff 0%, #94a3b8 100%); + background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; } @@ -409,7 +438,7 @@ async function saveShuttle() { color: #94a3b8; } -.form-group input { +.form-group input, .nexus-select, .nexus-textarea { background: rgba(15, 23, 42, 0.5); border: 1px solid rgba(255, 255, 255, 0.1); padding: 14px 16px; @@ -420,11 +449,34 @@ async function saveShuttle() { transition: all 0.3s; } -.form-group input:focus { +.nexus-select { + cursor: pointer; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='white'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 1rem center; + background-size: 1.5em; + padding-right: 3rem; +} + +.nexus-textarea { + resize: vertical; + min-height: 100px; +} + +.form-group input:focus, .nexus-select:focus, .nexus-textarea:focus { border-color: #fee715; box-shadow: 0 0 0 4px rgba(254, 231, 21, 0.1); } +.shuttle-description-preview { + padding: 0 20px 14px; + color: rgba(255,255,255,0.7); + font-size: 0.85rem; + line-height: 1.5; + white-space: pre-wrap; +} + .file-upload-wrapper { position: relative; width: 100%; diff --git a/frontend/src/views/DiscoverView.vue b/frontend/src/views/DiscoverView.vue index 900b75c..20a3b58 100644 --- a/frontend/src/views/DiscoverView.vue +++ b/frontend/src/views/DiscoverView.vue @@ -142,7 +142,7 @@ function resetFilters() { -
+
@@ -408,8 +411,9 @@ function resetFilters() { background: var(--bg-primary); border: 1.5px solid var(--border-color); border-radius: 0.875rem; - padding: 0.75rem 1rem; - transition: border-color 0.2s; + padding: 0.75rem 1.125rem; + transition: all 0.3s ease; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); } .search-wrap:focus-within { border-color: var(--active-color); } @@ -426,7 +430,12 @@ function resetFilters() { outline: none; } -.search-input::placeholder { color: var(--text-secondary); } +.search-input::placeholder { color: var(--text-secondary); opacity: 0.7; } + +.search-wrap:focus-within .search-icon { + transform: scale(1.1); + color: var(--active-color); +} .search-clear { background: none; @@ -445,11 +454,13 @@ function resetFilters() { ═══════════════════════════════════════════ */ .cat-chips-wrap { background: var(--bg-secondary); - padding: 0.75rem 0; + padding: 0.875rem 0; border-bottom: 1px solid var(--border-color); position: sticky; top: 0; - z-index: 10; + z-index: 100; + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); } .cat-chips-scroll { @@ -465,27 +476,61 @@ function resetFilters() { .cat-chip { display: inline-flex; align-items: center; - gap: 0.25rem; - padding: 0.5rem 0.875rem; + padding: 0.125rem; border-radius: 99px; - border: 1.5px solid var(--border-color); + border: 1px solid var(--border-color); background: var(--bg-primary); color: var(--text-secondary); - font-size: 0.8125rem; - font-weight: 700; font-family: inherit; cursor: pointer; white-space: nowrap; flex-shrink: 0; - transition: all 0.18s; + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); } -.cat-chip:hover { border-color: var(--active-color); color: var(--text-primary); } +.cat-chip-inner { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem 0.5rem 0.625rem; +} + +.cat-emoji { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + background: var(--bg-secondary); + border-radius: 50%; + font-size: 1rem; + transition: transform 0.3s ease; +} + +.cat-text { + font-size: 0.875rem; + font-weight: 700; +} + +.cat-chip:hover { + border-color: var(--active-color); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +.cat-chip:hover .cat-emoji { + transform: scale(1.1) rotate(5deg); +} .cat-chip--active { background: var(--active-color); border-color: var(--active-color); color: #101820; + box-shadow: 0 4px 15px rgba(254, 231, 21, 0.3); +} + +.cat-chip--active .cat-emoji { + background: rgba(0, 0, 0, 0.1); } /* ═══════════════════════════════════════════ @@ -654,8 +699,9 @@ function resetFilters() { } .biz-card:hover { - transform: translateY(-4px); + transform: translateY(-6px) scale(1.02); border-color: var(--active-color); + box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3); } .biz-img-wrap { diff --git a/frontend/src/views/TransporteLayout.vue b/frontend/src/views/TransporteLayout.vue index 4e33f03..5482511 100644 --- a/frontend/src/views/TransporteLayout.vue +++ b/frontend/src/views/TransporteLayout.vue @@ -100,6 +100,8 @@ onMounted(async () => { border: 1px solid var(--border-color); width: 100%; max-width: 400px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(8px); } .hub-tab { @@ -118,6 +120,30 @@ onMounted(async () => { justify-content: center; gap: 8px; text-decoration: none; + overflow: hidden; + position: relative; +} + +.hub-tab::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 100%; + background: white; + border-radius: 50%; + opacity: 0; + transform: translate(-50%, -50%) scale(0); + transition: all 0.5s ease; +} + +.hub-tab:active::after { + width: 200%; + height: 200%; + opacity: 0.1; + transform: translate(-50%, -50%) scale(1); + transition: 0s; } .hub-tab.active { @@ -135,9 +161,9 @@ onMounted(async () => { width: calc(50% - 6px); background: #FEE715; border-radius: 12px; - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); z-index: 1; - box-shadow: 0 4px 15px rgba(254, 231, 21, 0.4); + box-shadow: 0 4px 20px rgba(254, 231, 21, 0.4); } .fade-enter-active, diff --git a/frontend/src/views/transporte/TaxisLocales.vue b/frontend/src/views/transporte/TaxisLocales.vue index 6b1533b..dc35cc1 100644 --- a/frontend/src/views/transporte/TaxisLocales.vue +++ b/frontend/src/views/transporte/TaxisLocales.vue @@ -1,7 +1,6 @@ + \ No newline at end of file +.empty-state { + grid-column: 1 / -1; + text-align: center; + padding: 4rem 2rem; + color: var(--text-secondary); +} + +.empty-state .material-icons { + font-size: 4rem; + margin-bottom: 1rem; + opacity: 0.5; +} + +