| @ -0,0 +1,293 @@ | |||||
| <script setup lang="ts"> | |||||
| import { useI18n } from 'vue-i18n'; | |||||
| import { ref } from 'vue'; | |||||
| const { t } = useI18n(); | |||||
| // 社区活动数据 | |||||
| const upcomingEvents = ref([ | |||||
| { | |||||
| id: 1, | |||||
| title: 'MOSE 开发者大会', | |||||
| date: '2023-12-15', | |||||
| type: 'virtual', | |||||
| image: '/public/images.png' | |||||
| }, | |||||
| { | |||||
| id: 2, | |||||
| title: 'MOSE 区块链峰会', | |||||
| date: '2024-01-20', | |||||
| type: 'inperson', | |||||
| image: '/public/images.png' | |||||
| }, | |||||
| { | |||||
| id: 3, | |||||
| title: 'MOSE 黑客松', | |||||
| date: '2024-02-10', | |||||
| type: 'virtual', | |||||
| image: '/public/images.png' | |||||
| } | |||||
| ]); | |||||
| const pastEvents = ref([ | |||||
| { | |||||
| id: 4, | |||||
| title: 'MOSE 生态系统发布会', | |||||
| date: '2023-06-05', | |||||
| type: 'virtual', | |||||
| image: '/public/images.png', | |||||
| recording: '#' | |||||
| }, | |||||
| { | |||||
| id: 5, | |||||
| title: 'MOSE 技术研讨会', | |||||
| date: '2023-08-12', | |||||
| type: 'inperson', | |||||
| image: '/public/images.png', | |||||
| recording: '#' | |||||
| } | |||||
| ]); | |||||
| // 社区贡献者数据 | |||||
| const contributors = ref([ | |||||
| { | |||||
| id: 1, | |||||
| name: 'Alex Johnson', | |||||
| role: 'Core Developer', | |||||
| image: '/public/vite.svg', | |||||
| github: 'https://github.com' | |||||
| }, | |||||
| { | |||||
| id: 2, | |||||
| name: 'Sarah Chen', | |||||
| role: 'UI/UX Designer', | |||||
| image: '/public/vite.svg', | |||||
| github: 'https://github.com' | |||||
| }, | |||||
| { | |||||
| id: 3, | |||||
| name: 'David Kim', | |||||
| role: 'Community Manager', | |||||
| image: '/public/vite.svg', | |||||
| github: 'https://github.com' | |||||
| }, | |||||
| { | |||||
| id: 4, | |||||
| name: 'Maria Rodriguez', | |||||
| role: 'Documentation', | |||||
| image: '/public/vite.svg', | |||||
| github: 'https://github.com' | |||||
| } | |||||
| ]); | |||||
| </script> | |||||
| <template> | |||||
| <div class="bg-background min-h-screen"> | |||||
| <!-- Hero Section --> | |||||
| <section class="relative py-32 px-6 md:px-12 lg:px-24 bg-background-dark overflow-hidden"> | |||||
| <div class="container mx-auto relative z-10"> | |||||
| <div class="max-w-3xl mx-auto text-center"> | |||||
| <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-text mb-6 wow animate__animated animate__fadeInDown animate__duration-fast"> | |||||
| {{ t('community.hero.title') }} | |||||
| </h1> | |||||
| <p class="text-lg md:text-xl text-text-secondary mb-8 wow animate__animated animate__fadeIn animate__delay-sm"> | |||||
| {{ t('community.hero.subtitle') }} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| <!-- Background Decoration --> | |||||
| <div class="absolute top-0 left-0 w-full h-full overflow-hidden opacity-10"> | |||||
| <div class="absolute -top-24 -left-24 w-64 h-64 rounded-full bg-secondary blur-3xl wow animate__animated animate__pulse animate__infinite"></div> | |||||
| <div class="absolute top-1/2 right-0 w-80 h-80 rounded-full bg-primary blur-3xl wow animate__animated animate__pulse animate__infinite animate__delay-sm"></div> | |||||
| <div class="absolute -bottom-24 left-1/3 w-72 h-72 rounded-full bg-accent blur-3xl wow animate__animated animate__pulse animate__infinite animate__delay-md"></div> | |||||
| </div> | |||||
| </section> | |||||
| <!-- Community Channels Section --> | |||||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||||
| <div class="container mx-auto"> | |||||
| <div class="max-w-3xl mx-auto text-center mb-16"> | |||||
| <h2 class="text-3xl font-bold text-text mb-4 wow animate__animated animate__fadeInUp"> | |||||
| {{ t('community.join.title') }} | |||||
| </h2> | |||||
| <p class="text-text-secondary wow animate__animated animate__fadeInUp animate__delay-xs"> | |||||
| {{ t('community.join.subtitle') }} | |||||
| </p> | |||||
| </div> | |||||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> | |||||
| <!-- Discord --> | |||||
| <div class="bg-background-light rounded-xl p-6 shadow-card wow animate__animated animate__fadeInUp"> | |||||
| <div class="h-16 w-16 bg-primary/20 rounded-full flex items-center justify-center mb-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-primary-light" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.608 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1634-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/> | |||||
| </svg> | |||||
| </div> | |||||
| <h3 class="text-xl font-bold text-text mb-2">{{ t('community.channels.discord.title') }}</h3> | |||||
| <p class="text-text-secondary mb-4">{{ t('community.channels.discord.description') }}</p> | |||||
| <a href="#" class="inline-block px-6 py-2 bg-primary text-text rounded-lg btn-hover-float"> | |||||
| {{ t('community.channels.discord.button') }} | |||||
| </a> | |||||
| </div> | |||||
| <!-- Telegram --> | |||||
| <div class="bg-background-light rounded-xl p-6 shadow-card wow animate__animated animate__fadeInUp animate__delay-xs"> | |||||
| <div class="h-16 w-16 bg-primary/20 rounded-full flex items-center justify-center mb-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-primary-light" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.96 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/> | |||||
| </svg> | |||||
| </div> | |||||
| <h3 class="text-xl font-bold text-text mb-2">{{ t('community.channels.telegram.title') }}</h3> | |||||
| <p class="text-text-secondary mb-4">{{ t('community.channels.telegram.description') }}</p> | |||||
| <a href="#" class="inline-block px-6 py-2 bg-primary text-text rounded-lg btn-hover-float"> | |||||
| {{ t('community.channels.telegram.button') }} | |||||
| </a> | |||||
| </div> | |||||
| <!-- Twitter --> | |||||
| <div class="bg-background-light rounded-xl p-6 shadow-card wow animate__animated animate__fadeInUp animate__delay-sm"> | |||||
| <div class="h-16 w-16 bg-primary/20 rounded-full flex items-center justify-center mb-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-primary-light" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/> | |||||
| </svg> | |||||
| </div> | |||||
| <h3 class="text-xl font-bold text-text mb-2">{{ t('community.channels.twitter.title') }}</h3> | |||||
| <p class="text-text-secondary mb-4">{{ t('community.channels.twitter.description') }}</p> | |||||
| <a href="#" class="inline-block px-6 py-2 bg-primary text-text rounded-lg btn-hover-float"> | |||||
| {{ t('community.channels.twitter.button') }} | |||||
| </a> | |||||
| </div> | |||||
| <!-- Forum --> | |||||
| <div class="bg-background-light rounded-xl p-6 shadow-card wow animate__animated animate__fadeInUp animate__delay-md"> | |||||
| <div class="h-16 w-16 bg-primary/20 rounded-full flex items-center justify-center mb-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-primary-light" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z" /> | |||||
| </svg> | |||||
| </div> | |||||
| <h3 class="text-xl font-bold text-text mb-2">{{ t('community.channels.forum.title') }}</h3> | |||||
| <p class="text-text-secondary mb-4">{{ t('community.channels.forum.description') }}</p> | |||||
| <a href="#" class="inline-block px-6 py-2 bg-primary text-text rounded-lg btn-hover-float"> | |||||
| {{ t('community.channels.forum.button') }} | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </section> | |||||
| <!-- Community Events Section --> | |||||
| <section class="py-16 px-6 md:px-12 lg:px-24 bg-background-light"> | |||||
| <div class="container mx-auto"> | |||||
| <h2 class="text-3xl font-bold text-text mb-12 text-center wow animate__animated animate__fadeInUp"> | |||||
| {{ t('community.events.title') }} | |||||
| </h2> | |||||
| <!-- Upcoming Events --> | |||||
| <div class="mb-16"> | |||||
| <h3 class="text-2xl font-bold text-text mb-6 wow animate__animated animate__fadeInUp"> | |||||
| {{ t('community.events.upcoming') }} | |||||
| </h3> | |||||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |||||
| <div v-for="event in upcomingEvents" :key="event.id" class="bg-background rounded-xl overflow-hidden shadow-card wow animate__animated animate__fadeInUp"> | |||||
| <div class="relative h-48 overflow-hidden"> | |||||
| <img :src="event.image" :alt="event.title" class="w-full h-full object-cover" /> | |||||
| <div class="absolute top-4 right-4 px-3 py-1 rounded-full" :class="event.type === 'virtual' ? 'bg-secondary' : 'bg-accent'"> | |||||
| <span class="text-xs font-medium text-text"> | |||||
| {{ t(`community.events.${event.type}`) }} | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| <div class="p-6"> | |||||
| <h4 class="text-xl font-bold text-text mb-2">{{ event.title }}</h4> | |||||
| <p class="text-text-secondary mb-4">{{ event.date }}</p> | |||||
| <button class="px-6 py-2 bg-primary text-text rounded-lg w-full btn-hover-glow"> | |||||
| {{ t('community.events.register') }} | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- Past Events --> | |||||
| <div> | |||||
| <h3 class="text-2xl font-bold text-text mb-6 wow animate__animated animate__fadeInUp"> | |||||
| {{ t('community.events.past') }} | |||||
| </h3> | |||||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |||||
| <div v-for="event in pastEvents" :key="event.id" class="bg-background rounded-xl overflow-hidden shadow-card wow animate__animated animate__fadeInUp"> | |||||
| <div class="relative h-48 overflow-hidden"> | |||||
| <img :src="event.image" :alt="event.title" class="w-full h-full object-cover opacity-70" /> | |||||
| <div class="absolute top-4 right-4 px-3 py-1 rounded-full" :class="event.type === 'virtual' ? 'bg-secondary' : 'bg-accent'"> | |||||
| <span class="text-xs font-medium text-text"> | |||||
| {{ t(`community.events.${event.type}`) }} | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| <div class="p-6"> | |||||
| <h4 class="text-xl font-bold text-text mb-2">{{ event.title }}</h4> | |||||
| <p class="text-text-secondary mb-4">{{ event.date }}</p> | |||||
| <a :href="event.recording" class="px-6 py-2 bg-transparent border border-primary-light text-primary-light rounded-lg flex items-center justify-center btn-hover-shadow"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" /> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> | |||||
| </svg> | |||||
| {{ t('community.events.watch') }} | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </section> | |||||
| <!-- Community Contributors Section --> | |||||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||||
| <div class="container mx-auto"> | |||||
| <div class="max-w-3xl mx-auto text-center mb-12"> | |||||
| <h2 class="text-3xl font-bold text-text mb-4 wow animate__animated animate__fadeInUp"> | |||||
| {{ t('community.contributors.title') }} | |||||
| </h2> | |||||
| <p class="text-text-secondary wow animate__animated animate__fadeInUp animate__delay-xs"> | |||||
| {{ t('community.contributors.description') }} | |||||
| </p> | |||||
| </div> | |||||
| <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-12"> | |||||
| <div v-for="contributor in contributors" :key="contributor.id" class="bg-background-light rounded-xl p-6 text-center shadow-card wow animate__animated animate__fadeInUp"> | |||||
| <div class="w-24 h-24 rounded-full mx-auto mb-4 overflow-hidden"> | |||||
| <img :src="contributor.image" :alt="contributor.name" class="w-full h-full object-cover" /> | |||||
| </div> | |||||
| <h4 class="text-xl font-bold text-text mb-1">{{ contributor.name }}</h4> | |||||
| <p class="text-text-secondary mb-4">{{ contributor.role }}</p> | |||||
| <a :href="contributor.github" class="text-primary-light hover:text-primary flex items-center justify-center"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/> | |||||
| </svg> | |||||
| GitHub | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="text-center"> | |||||
| <a href="#" class="inline-block px-8 py-3 bg-primary text-text rounded-lg btn-hover-scale"> | |||||
| {{ t('community.contributors.become') }} | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| </section> | |||||
| </div> | |||||
| </template> | |||||
| <style scoped> | |||||
| .shadow-card { | |||||
| transition: transform 0.3s ease, box-shadow 0.3s ease; | |||||
| } | |||||
| .shadow-card:hover { | |||||
| transform: translateY(-5px); | |||||
| box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2); | |||||
| } | |||||
| </style> | |||||
| @ -0,0 +1,286 @@ | |||||
| <script setup lang="ts"> | |||||
| import { useI18n } from 'vue-i18n'; | |||||
| import { ref } from 'vue'; | |||||
| const { t } = useI18n(); | |||||
| // 表单数据 | |||||
| const formData = ref({ | |||||
| name: '', | |||||
| email: '', | |||||
| subject: '', | |||||
| message: '' | |||||
| }); | |||||
| // 表单状态 | |||||
| const isSubmitting = ref(false); | |||||
| const formSubmitted = ref(false); | |||||
| const formError = ref(false); | |||||
| // 提交表单 | |||||
| const submitForm = () => { | |||||
| isSubmitting.value = true; | |||||
| // 模拟API调用 | |||||
| setTimeout(() => { | |||||
| isSubmitting.value = false; | |||||
| formSubmitted.value = true; | |||||
| // 重置表单 | |||||
| formData.value = { | |||||
| name: '', | |||||
| email: '', | |||||
| subject: '', | |||||
| message: '' | |||||
| }; | |||||
| // 3秒后重置状态 | |||||
| setTimeout(() => { | |||||
| formSubmitted.value = false; | |||||
| }, 3000); | |||||
| }, 1000); | |||||
| }; | |||||
| </script> | |||||
| <template> | |||||
| <div class="bg-background min-h-screen"> | |||||
| <!-- Hero Section --> | |||||
| <section class="relative py-32 px-6 md:px-12 lg:px-24 bg-background-dark overflow-hidden"> | |||||
| <div class="container mx-auto relative z-10"> | |||||
| <div class="max-w-3xl mx-auto text-center"> | |||||
| <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-text mb-6 wow animate__animated animate__fadeInDown animate__duration-fast"> | |||||
| {{ t('contact.hero.title') }} | |||||
| </h1> | |||||
| <p class="text-lg md:text-xl text-text-secondary mb-8 wow animate__animated animate__fadeIn animate__delay-sm"> | |||||
| {{ t('contact.hero.subtitle') }} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| <!-- Background Decoration --> | |||||
| <div class="absolute top-0 left-0 w-full h-full overflow-hidden opacity-10"> | |||||
| <div class="absolute -top-24 -left-24 w-64 h-64 rounded-full bg-primary blur-3xl wow animate__animated animate__pulse animate__infinite"></div> | |||||
| <div class="absolute top-1/2 right-0 w-80 h-80 rounded-full bg-secondary blur-3xl wow animate__animated animate__pulse animate__infinite animate__delay-sm"></div> | |||||
| <div class="absolute -bottom-24 left-1/3 w-72 h-72 rounded-full bg-accent blur-3xl wow animate__animated animate__pulse animate__infinite animate__delay-md"></div> | |||||
| </div> | |||||
| </section> | |||||
| <!-- Contact Form Section --> | |||||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||||
| <div class="container mx-auto"> | |||||
| <div class="grid grid-cols-1 lg:grid-cols-5 gap-12"> | |||||
| <!-- Contact Form --> | |||||
| <div class="lg:col-span-3 wow animate__animated animate__fadeInLeft"> | |||||
| <div class="bg-background-light rounded-xl p-8 shadow-card"> | |||||
| <h2 class="text-2xl font-bold text-text mb-6">{{ t('contact.hero.title') }}</h2> | |||||
| <!-- Success Message --> | |||||
| <div v-if="formSubmitted" class="mb-6 p-4 bg-secondary bg-opacity-20 rounded-lg border border-secondary"> | |||||
| <p class="text-secondary">{{ t('contact.form.success') }}</p> | |||||
| </div> | |||||
| <!-- Error Message --> | |||||
| <div v-if="formError" class="mb-6 p-4 bg-red-500 bg-opacity-20 rounded-lg border border-red-500"> | |||||
| <p class="text-red-500">{{ t('contact.form.error') }}</p> | |||||
| </div> | |||||
| <!-- Form --> | |||||
| <form @submit.prevent="submitForm"> | |||||
| <div class="mb-4"> | |||||
| <label for="name" class="block text-text-secondary mb-2">{{ t('contact.form.name') }}</label> | |||||
| <input | |||||
| type="text" | |||||
| id="name" | |||||
| v-model="formData.name" | |||||
| class="w-full px-4 py-3 bg-background rounded-lg text-text focus:outline-none focus:ring-2 focus:ring-primary" | |||||
| required | |||||
| /> | |||||
| </div> | |||||
| <div class="mb-4"> | |||||
| <label for="email" class="block text-text-secondary mb-2">{{ t('contact.form.email') }}</label> | |||||
| <input | |||||
| type="email" | |||||
| id="email" | |||||
| v-model="formData.email" | |||||
| class="w-full px-4 py-3 bg-background rounded-lg text-text focus:outline-none focus:ring-2 focus:ring-primary" | |||||
| required | |||||
| /> | |||||
| </div> | |||||
| <div class="mb-4"> | |||||
| <label for="subject" class="block text-text-secondary mb-2">{{ t('contact.form.subject') }}</label> | |||||
| <input | |||||
| type="text" | |||||
| id="subject" | |||||
| v-model="formData.subject" | |||||
| class="w-full px-4 py-3 bg-background rounded-lg text-text focus:outline-none focus:ring-2 focus:ring-primary" | |||||
| required | |||||
| /> | |||||
| </div> | |||||
| <div class="mb-6"> | |||||
| <label for="message" class="block text-text-secondary mb-2">{{ t('contact.form.message') }}</label> | |||||
| <textarea | |||||
| id="message" | |||||
| v-model="formData.message" | |||||
| rows="5" | |||||
| class="w-full px-4 py-3 bg-background rounded-lg text-text focus:outline-none focus:ring-2 focus:ring-primary" | |||||
| required | |||||
| ></textarea> | |||||
| </div> | |||||
| <button | |||||
| type="submit" | |||||
| class="w-full px-6 py-3 bg-primary text-text rounded-lg shadow-button btn-hover-glow" | |||||
| :disabled="isSubmitting" | |||||
| > | |||||
| <span v-if="isSubmitting">{{ t('common.loading') }}</span> | |||||
| <span v-else>{{ t('contact.form.submit') }}</span> | |||||
| </button> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| <!-- Contact Info --> | |||||
| <div class="lg:col-span-2 wow animate__animated animate__fadeInRight"> | |||||
| <div class="bg-background-light rounded-xl p-8 shadow-card mb-8"> | |||||
| <h3 class="text-xl font-bold text-text mb-6">{{ t('contact.info.title') }}</h3> | |||||
| <div class="space-y-6"> | |||||
| <div class="flex items-start"> | |||||
| <div class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center mr-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-primary-light" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" /> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" /> | |||||
| </svg> | |||||
| </div> | |||||
| <div> | |||||
| <h4 class="text-text font-medium mb-1">{{ t('contact.info.address') }}</h4> | |||||
| <p class="text-text-secondary">{{ t('contact.info.address_value') }}</p> | |||||
| </div> | |||||
| </div> | |||||
| <div class="flex items-start"> | |||||
| <div class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center mr-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-primary-light" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /> | |||||
| </svg> | |||||
| </div> | |||||
| <div> | |||||
| <h4 class="text-text font-medium mb-1">Email</h4> | |||||
| <p class="text-text-secondary">{{ t('contact.email.info') }}</p> | |||||
| <p class="text-text-secondary">{{ t('contact.email.support') }}</p> | |||||
| </div> | |||||
| </div> | |||||
| <div class="flex items-start"> | |||||
| <div class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center mr-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-primary-light" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" /> | |||||
| </svg> | |||||
| </div> | |||||
| <div> | |||||
| <h4 class="text-text font-medium mb-1">{{ t('contact.info.phone') }}</h4> | |||||
| <p class="text-text-secondary">{{ t('contact.info.phone_value') }}</p> | |||||
| </div> | |||||
| </div> | |||||
| <div class="flex items-start"> | |||||
| <div class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center mr-4"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-primary-light" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> | |||||
| </svg> | |||||
| </div> | |||||
| <div> | |||||
| <h4 class="text-text font-medium mb-1">{{ t('contact.info.hours') }}</h4> | |||||
| <p class="text-text-secondary">{{ t('contact.info.hours_value') }}</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- Social Media --> | |||||
| <div class="bg-background-light rounded-xl p-8 shadow-card"> | |||||
| <h3 class="text-xl font-bold text-text mb-6">{{ t('contact.social.title') }}</h3> | |||||
| <p class="text-text-secondary mb-4">{{ t('contact.social.follow') }}</p> | |||||
| <div class="flex space-x-4"> | |||||
| <a href="#" class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center text-primary-light hover:bg-primary hover:text-text transition-colors btn-hover-scale"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/> | |||||
| </svg> | |||||
| </a> | |||||
| <a href="#" class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center text-primary-light hover:bg-primary hover:text-text transition-colors btn-hover-scale"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M12 0C5.373 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.6.113.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/> | |||||
| </svg> | |||||
| </a> | |||||
| <a href="#" class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center text-primary-light hover:bg-primary hover:text-text transition-colors btn-hover-scale"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> | |||||
| </svg> | |||||
| </a> | |||||
| <a href="#" class="h-10 w-10 bg-primary/20 rounded-full flex items-center justify-center text-primary-light hover:bg-primary hover:text-text transition-colors btn-hover-scale"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"> | |||||
| <path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.608 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1634-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/> | |||||
| </svg> | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </section> | |||||
| <!-- Map Section --> | |||||
| <section class="py-16 px-6 md:px-12 lg:px-24 bg-background-light"> | |||||
| <div class="container mx-auto"> | |||||
| <div class="max-w-5xl mx-auto"> | |||||
| <div class="bg-background rounded-xl overflow-hidden shadow-card h-96 wow animate__animated animate__fadeIn"> | |||||
| <!-- Map Placeholder (in a real app, you'd use a real map API) --> | |||||
| <div class="w-full h-full bg-background-dark flex items-center justify-center"> | |||||
| <div class="text-center"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-text-secondary mx-auto mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" /> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" /> | |||||
| </svg> | |||||
| <p class="text-text-secondary">{{ t('contact.info.address_value') }}</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </section> | |||||
| </div> | |||||
| </template> | |||||
| <style scoped> | |||||
| input, textarea { | |||||
| transition: box-shadow 0.3s ease; | |||||
| } | |||||
| input:focus, textarea:focus { | |||||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3); | |||||
| } | |||||
| .btn-hover-scale { | |||||
| transition: transform 0.3s ease; | |||||
| } | |||||
| .btn-hover-scale:hover { | |||||
| transform: scale(1.1); | |||||
| } | |||||
| .shadow-card { | |||||
| transition: transform 0.3s ease, box-shadow 0.3s ease; | |||||
| } | |||||
| .shadow-card:hover { | |||||
| transform: translateY(-5px); | |||||
| box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2); | |||||
| } | |||||
| </style> | |||||
| @ -0,0 +1,267 @@ | |||||
| <script setup lang="ts"> | |||||
| import { useI18n } from 'vue-i18n'; | |||||
| import { ref, computed } from 'vue'; | |||||
| const { t } = useI18n(); | |||||
| // 当前选中的分类 | |||||
| const selectedCategory = ref('all'); | |||||
| // 搜索关键词 | |||||
| const searchQuery = ref(''); | |||||
| // 问题列表 | |||||
| const allQuestions = computed(() => { | |||||
| return [ | |||||
| { | |||||
| id: 'what_is_mose', | |||||
| category: 'general', | |||||
| question: t('faq.questions.general.what_is_mose.question'), | |||||
| answer: t('faq.questions.general.what_is_mose.answer') | |||||
| }, | |||||
| { | |||||
| id: 'how_started', | |||||
| category: 'general', | |||||
| question: t('faq.questions.general.how_started.question'), | |||||
| answer: t('faq.questions.general.how_started.answer') | |||||
| }, | |||||
| { | |||||
| id: 'consensus', | |||||
| category: 'technical', | |||||
| question: t('faq.questions.technical.consensus.question'), | |||||
| answer: t('faq.questions.technical.consensus.answer') | |||||
| }, | |||||
| { | |||||
| id: 'tps', | |||||
| category: 'technical', | |||||
| question: t('faq.questions.technical.tps.question'), | |||||
| answer: t('faq.questions.technical.tps.answer') | |||||
| }, | |||||
| { | |||||
| id: 'projects', | |||||
| category: 'ecosystem', | |||||
| question: t('faq.questions.ecosystem.projects.question'), | |||||
| answer: t('faq.questions.ecosystem.projects.answer') | |||||
| }, | |||||
| { | |||||
| id: 'partners', | |||||
| category: 'ecosystem', | |||||
| question: t('faq.questions.ecosystem.partners.question'), | |||||
| answer: t('faq.questions.ecosystem.partners.answer') | |||||
| } | |||||
| ]; | |||||
| }); | |||||
| // 过滤后的问题列表 | |||||
| const filteredQuestions = computed(() => { | |||||
| let questions = allQuestions.value; | |||||
| // 按分类过滤 | |||||
| if (selectedCategory.value !== 'all') { | |||||
| questions = questions.filter(q => q.category === selectedCategory.value); | |||||
| } | |||||
| // 按搜索关键词过滤 | |||||
| if (searchQuery.value) { | |||||
| const query = searchQuery.value.toLowerCase(); | |||||
| questions = questions.filter(q => | |||||
| q.question.toLowerCase().includes(query) || | |||||
| q.answer.toLowerCase().includes(query) | |||||
| ); | |||||
| } | |||||
| return questions; | |||||
| }); | |||||
| // 切换分类 | |||||
| const setCategory = (category: string) => { | |||||
| selectedCategory.value = category; | |||||
| }; | |||||
| // 展开/折叠问题 | |||||
| const expandedQuestions = ref<string[]>([]); | |||||
| const toggleQuestion = (id: string) => { | |||||
| const index = expandedQuestions.value.indexOf(id); | |||||
| if (index === -1) { | |||||
| expandedQuestions.value.push(id); | |||||
| } else { | |||||
| expandedQuestions.value.splice(index, 1); | |||||
| } | |||||
| }; | |||||
| const isExpanded = (id: string) => { | |||||
| return expandedQuestions.value.includes(id); | |||||
| }; | |||||
| </script> | |||||
| <template> | |||||
| <div class="bg-background min-h-screen"> | |||||
| <!-- Hero Section --> | |||||
| <section class="relative py-32 px-6 md:px-12 lg:px-24 bg-background-dark overflow-hidden"> | |||||
| <div class="container mx-auto relative z-10"> | |||||
| <div class="max-w-3xl mx-auto text-center"> | |||||
| <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-text mb-6 wow animate__animated animate__fadeInDown animate__duration-fast"> | |||||
| {{ t('faq.hero.title') }} | |||||
| </h1> | |||||
| <p class="text-lg md:text-xl text-text-secondary mb-8 wow animate__animated animate__fadeIn animate__delay-sm"> | |||||
| {{ t('faq.hero.subtitle') }} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| <!-- Background Decoration --> | |||||
| <div class="absolute top-0 left-0 w-full h-full overflow-hidden opacity-10"> | |||||
| <div class="absolute -top-24 -left-24 w-64 h-64 rounded-full bg-accent blur-3xl wow animate__animated animate__pulse animate__infinite"></div> | |||||
| <div class="absolute top-1/2 right-0 w-80 h-80 rounded-full bg-primary blur-3xl wow animate__animated animate__pulse animate__infinite animate__delay-sm"></div> | |||||
| <div class="absolute -bottom-24 left-1/3 w-72 h-72 rounded-full bg-secondary blur-3xl wow animate__animated animate__pulse animate__infinite animate__delay-md"></div> | |||||
| </div> | |||||
| </section> | |||||
| <!-- Search and Filter Section --> | |||||
| <section class="py-12 px-6 md:px-12 lg:px-24"> | |||||
| <div class="container mx-auto"> | |||||
| <div class="max-w-3xl mx-auto mb-12"> | |||||
| <!-- Search Bar --> | |||||
| <div class="relative mb-8 wow animate__animated animate__fadeIn"> | |||||
| <input | |||||
| type="text" | |||||
| v-model="searchQuery" | |||||
| :placeholder="t('faq.search.placeholder')" | |||||
| class="w-full py-4 px-6 pr-12 bg-background-light text-text rounded-xl focus:outline-none focus:ring-2 focus:ring-primary" | |||||
| /> | |||||
| <button class="absolute right-4 top-1/2 transform -translate-y-1/2 text-text-secondary hover:text-primary transition-colors btn-hover-scale"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /> | |||||
| </svg> | |||||
| </button> | |||||
| </div> | |||||
| <!-- Categories --> | |||||
| <div class="flex flex-wrap gap-3 justify-center wow animate__animated animate__fadeIn animate__delay-sm"> | |||||
| <button | |||||
| @click="setCategory('all')" | |||||
| class="px-4 py-2 rounded-lg text-sm font-medium transition-colors btn-hover-float" | |||||
| :class="selectedCategory === 'all' ? 'bg-primary text-text' : 'bg-background-light text-text-secondary hover:bg-background-light/80'" | |||||
| > | |||||
| {{ t('faq.categories.all') }} | |||||
| </button> | |||||
| <button | |||||
| @click="setCategory('general')" | |||||
| class="px-4 py-2 rounded-lg text-sm font-medium transition-colors btn-hover-float" | |||||
| :class="selectedCategory === 'general' ? 'bg-primary text-text' : 'bg-background-light text-text-secondary hover:bg-background-light/80'" | |||||
| > | |||||
| {{ t('faq.categories.general') }} | |||||
| </button> | |||||
| <button | |||||
| @click="setCategory('technical')" | |||||
| class="px-4 py-2 rounded-lg text-sm font-medium transition-colors btn-hover-float" | |||||
| :class="selectedCategory === 'technical' ? 'bg-primary text-text' : 'bg-background-light text-text-secondary hover:bg-background-light/80'" | |||||
| > | |||||
| {{ t('faq.categories.technical') }} | |||||
| </button> | |||||
| <button | |||||
| @click="setCategory('ecosystem')" | |||||
| class="px-4 py-2 rounded-lg text-sm font-medium transition-colors btn-hover-float" | |||||
| :class="selectedCategory === 'ecosystem' ? 'bg-primary text-text' : 'bg-background-light text-text-secondary hover:bg-background-light/80'" | |||||
| > | |||||
| {{ t('faq.categories.ecosystem') }} | |||||
| </button> | |||||
| <button | |||||
| @click="setCategory('token')" | |||||
| class="px-4 py-2 rounded-lg text-sm font-medium transition-colors btn-hover-float" | |||||
| :class="selectedCategory === 'token' ? 'bg-primary text-text' : 'bg-background-light text-text-secondary hover:bg-background-light/80'" | |||||
| > | |||||
| {{ t('faq.categories.token') }} | |||||
| </button> | |||||
| <button | |||||
| @click="setCategory('development')" | |||||
| class="px-4 py-2 rounded-lg text-sm font-medium transition-colors btn-hover-float" | |||||
| :class="selectedCategory === 'development' ? 'bg-primary text-text' : 'bg-background-light text-text-secondary hover:bg-background-light/80'" | |||||
| > | |||||
| {{ t('faq.categories.development') }} | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| <!-- FAQ Questions --> | |||||
| <div class="max-w-3xl mx-auto"> | |||||
| <div v-if="filteredQuestions.length === 0" class="text-center py-8 text-text-secondary wow animate__animated animate__fadeIn"> | |||||
| {{ t('faq.search.noresults') }} | |||||
| </div> | |||||
| <div v-else class="space-y-4"> | |||||
| <div | |||||
| v-for="question in filteredQuestions" | |||||
| :key="question.id" | |||||
| class="bg-background-light rounded-xl overflow-hidden wow animate__animated animate__fadeIn" | |||||
| > | |||||
| <button | |||||
| @click="toggleQuestion(question.id)" | |||||
| class="w-full px-6 py-4 flex justify-between items-center text-left hover:bg-background-light/80 transition-colors" | |||||
| > | |||||
| <h3 class="text-lg font-medium text-text">{{ question.question }}</h3> | |||||
| <svg | |||||
| xmlns="http://www.w3.org/2000/svg" | |||||
| class="h-5 w-5 text-text-secondary transition-transform duration-300" | |||||
| :class="{ 'transform rotate-180': isExpanded(question.id) }" | |||||
| fill="none" | |||||
| viewBox="0 0 24 24" | |||||
| stroke="currentColor" | |||||
| > | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> | |||||
| </svg> | |||||
| </button> | |||||
| <div | |||||
| v-show="isExpanded(question.id)" | |||||
| class="px-6 py-4 border-t border-background" | |||||
| > | |||||
| <p class="text-text-secondary">{{ question.answer }}</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </section> | |||||
| <!-- More Questions Section --> | |||||
| <section class="py-16 px-6 md:px-12 lg:px-24 bg-background-light"> | |||||
| <div class="container mx-auto"> | |||||
| <div class="max-w-3xl mx-auto text-center"> | |||||
| <h2 class="text-2xl font-bold text-text mb-4 wow animate__animated animate__fadeInUp"> | |||||
| {{ t('faq.more.title') }} | |||||
| </h2> | |||||
| <div class="flex flex-col sm:flex-row justify-center gap-4 mt-8 wow animate__animated animate__fadeInUp animate__delay-sm"> | |||||
| <router-link | |||||
| to="/contact" | |||||
| class="px-8 py-3 bg-primary text-text rounded-lg hover:bg-primary-dark transition-colors duration-300 shadow-button btn-hover-glow" | |||||
| > | |||||
| {{ t('faq.more.contact') }} | |||||
| </router-link> | |||||
| <router-link | |||||
| to="/community" | |||||
| class="px-8 py-3 bg-transparent border border-primary-light text-primary-light rounded-lg hover:bg-primary-light hover:bg-opacity-10 transition-colors duration-300 btn-hover-shadow" | |||||
| > | |||||
| {{ t('faq.more.community') }} | |||||
| </router-link> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </section> | |||||
| </div> | |||||
| </template> | |||||
| <style scoped> | |||||
| button { | |||||
| outline: none; | |||||
| } | |||||
| .btn-hover-float { | |||||
| transition: transform 0.3s ease; | |||||
| } | |||||
| .btn-hover-float:hover { | |||||
| transform: translateY(-3px); | |||||
| } | |||||
| </style> | |||||