HomeView.vue
4,203 bytes
| 1 | <script setup lang="ts"> |
|---|---|
| 2 | import { computed } from 'vue' |
| 3 | import { useI18n } from 'vue-i18n' |
| 4 | import { useAuthStore } from '@/stores/auth' |
| 5 | |
| 6 | const authStore = useAuthStore() |
| 7 | const { t } = useI18n() |
| 8 | |
| 9 | const features = computed(() => [ |
| 10 | { icon: 'bi-receipt-cutoff', title: t('home.features.expenseTitle'), text: t('home.features.expenseText') }, |
| 11 | { icon: 'bi-pie-chart-fill', title: t('home.features.budgetTitle'), text: t('home.features.budgetText') }, |
| 12 | { icon: 'bi-heart-fill', title: t('home.features.wishlistTitle'), text: t('home.features.wishlistText') }, |
| 13 | { icon: 'bi-bar-chart-fill', title: t('home.features.pollsTitle'), text: t('home.features.pollsText') }, |
| 14 | { icon: 'bi-arrow-left-right', title: t('home.features.settlementTitle'), text: t('home.features.settlementText') }, |
| 15 | ]) |
| 16 | </script> |
| 17 | |
| 18 | <template> |
| 19 | <div> |
| 20 | <!-- Hero Section --> |
| 21 | <div class="sa-hero"> |
| 22 | <div class="sa-hero-content"> |
| 23 | <div class="sa-hero-badge sa-animate-fade-in"> |
| 24 | <i class="bi bi-airplane-fill me-1"></i> {{ t('home.heroBadge') }} |
| 25 | </div> |
| 26 | <h1 class="sa-hero-title sa-animate-fade-in"> |
| 27 | {{ t('home.heroTitle1') }} |
| 28 | <span class="sa-hero-title-soft">{{ t('home.heroTitle2') }}</span> |
| 29 | </h1> |
| 30 | <p class="sa-hero-subtitle sa-animate-slide-up sa-stagger-1"> |
| 31 | {{ t('home.heroSubtitle') }} |
| 32 | </p> |
| 33 | |
| 34 | <div class="sa-hero-btns sa-animate-slide-up sa-stagger-2"> |
| 35 | <template v-if="authStore.isAuthenticated"> |
| 36 | <RouterLink :to="{ name: 'TripsIndex' }" class="sa-hero-btn-white"> |
| 37 | <i class="bi bi-suitcase-lg me-1"></i> {{ t('home.myTrips') }} |
| 38 | </RouterLink> |
| 39 | </template> |
| 40 | <template v-else> |
| 41 | <RouterLink :to="{ name: 'Register' }" class="sa-hero-btn-white"> |
| 42 | {{ t('home.getStartedFree') }} <i class="bi bi-arrow-right ms-1"></i> |
| 43 | </RouterLink> |
| 44 | <RouterLink :to="{ name: 'Login' }" class="sa-hero-btn-outline"> |
| 45 | {{ t('nav.signIn') }} |
| 46 | </RouterLink> |
| 47 | </template> |
| 48 | </div> |
| 49 | |
| 50 | </div> |
| 51 | </div> |
| 52 | |
| 53 | <!-- Features Grid --> |
| 54 | <div class="sa-home-section"> |
| 55 | <h2 class="text-center mb-2 sa-animate-fade-in" style="font-size: 1.75rem; font-weight: 800">{{ t('home.featuresTitle') }}</h2> |
| 56 | <p class="text-center mb-5 sa-animate-fade-in" style="color: var(--sa-gray-500); max-width: 520px; margin: 0 auto"> |
| 57 | {{ t('home.featuresSubtitle') }} |
| 58 | </p> |
| 59 | <div class="row g-4 mb-5 justify-content-center"> |
| 60 | <div |
| 61 | v-for="(feature, index) in features" |
| 62 | :key="feature.title" |
| 63 | class="col-md-6 col-lg-4 sa-animate-slide-up" |
| 64 | :class="`sa-stagger-${index + 1}`" |
| 65 | > |
| 66 | <div class="sa-card sa-feature-card sa-hover-lift h-100"> |
| 67 | <div class="sa-card-body"> |
| 68 | <div class="sa-feature-icon-wrap"> |
| 69 | <i :class="['bi', feature.icon]"></i> |
| 70 | </div> |
| 71 | <div class="sa-feature-title">{{ feature.title }}</div> |
| 72 | <div class="sa-feature-text">{{ feature.text }}</div> |
| 73 | </div> |
| 74 | </div> |
| 75 | </div> |
| 76 | </div> |
| 77 | </div> |
| 78 | </div> |
| 79 | </template> |
| 80 | |
| 81 | <style scoped> |
| 82 | .sa-home-section { |
| 83 | padding-top: var(--sa-space-8); |
| 84 | } |
| 85 | |
| 86 | .sa-hero-badge { |
| 87 | display: inline-block; |
| 88 | background: rgba(255, 255, 255, 0.2); |
| 89 | border: 1px solid rgba(255, 255, 255, 0.3); |
| 90 | border-radius: 9999px; |
| 91 | padding: 6px 16px; |
| 92 | font-size: 0.813rem; |
| 93 | font-weight: 600; |
| 94 | color: #fff; |
| 95 | margin-bottom: 20px; |
| 96 | backdrop-filter: blur(8px); |
| 97 | } |
| 98 | |
| 99 | .sa-hero-title { |
| 100 | font-size: 3rem; |
| 101 | font-weight: 900; |
| 102 | line-height: 1.15; |
| 103 | margin-bottom: 16px; |
| 104 | letter-spacing: -0.03em; |
| 105 | color: #fff; |
| 106 | } |
| 107 | |
| 108 | .sa-hero-title-soft { |
| 109 | color: rgba(255, 255, 255, 0.85); |
| 110 | font-weight: 800; |
| 111 | } |
| 112 | |
| 113 | .sa-hero-subtitle { |
| 114 | font-size: 1.125rem; |
| 115 | line-height: 1.6; |
| 116 | max-width: 520px; |
| 117 | } |
| 118 | |
| 119 | .sa-feature-icon-wrap { |
| 120 | width: 48px; |
| 121 | height: 48px; |
| 122 | border-radius: 14px; |
| 123 | display: flex; |
| 124 | align-items: center; |
| 125 | justify-content: center; |
| 126 | margin: 0 auto 16px; |
| 127 | background: var(--sa-gray-100); |
| 128 | color: var(--sa-primary); |
| 129 | font-size: 1.4rem; |
| 130 | } |
| 131 | |
| 132 | @media (max-width: 767px) { |
| 133 | .sa-hero-title { |
| 134 | font-size: 2rem; |
| 135 | } |
| 136 | } |
| 137 | </style> |
| 138 | |