| @ -0,0 +1,24 @@ | |||
| # Logs | |||
| logs | |||
| *.log | |||
| npm-debug.log* | |||
| yarn-debug.log* | |||
| yarn-error.log* | |||
| pnpm-debug.log* | |||
| lerna-debug.log* | |||
| node_modules | |||
| dist | |||
| dist-ssr | |||
| *.local | |||
| # Editor directories and files | |||
| .vscode/* | |||
| !.vscode/extensions.json | |||
| .idea | |||
| .DS_Store | |||
| *.suo | |||
| *.ntvs* | |||
| *.njsproj | |||
| *.sln | |||
| *.sw? | |||
| @ -0,0 +1,3 @@ | |||
| { | |||
| "recommendations": ["Vue.volar"] | |||
| } | |||
| @ -0,0 +1,65 @@ | |||
| # MOSE Web | |||
| MOSE Web 是一个基于 Vue 3 和 Tailwind CSS v4 的多语言区块链项目网站。 | |||
| ## 特点 | |||
| - 使用 Vue 3 和 TypeScript 构建 | |||
| - 使用 Tailwind CSS v4 进行样式设计 | |||
| - 支持多语言(中文、英文、日语) | |||
| - 响应式设计,适配桌面、平板和移动端 | |||
| - 模块化组件结构 | |||
| ## 页面 | |||
| - 首页:展示项目概览和核心特点 | |||
| - 生态系统:展示项目生态系统中的应用和合作伙伴 | |||
| - 关于我们:介绍项目团队和发展历程 | |||
| - 404页面:自定义错误页面 | |||
| ## 技术栈 | |||
| - Vue 3:前端框架 | |||
| - Vue Router:路由管理 | |||
| - Vue I18n:国际化 | |||
| - Tailwind CSS v4:CSS 框架 | |||
| - Vite:构建工具 | |||
| ## 开发 | |||
| ```bash | |||
| # 安装依赖 | |||
| npm install | |||
| # 启动开发服务器 | |||
| npm run dev | |||
| # 构建生产版本 | |||
| npm run build | |||
| # 预览生产版本 | |||
| npm run preview | |||
| ``` | |||
| ## 项目结构 | |||
| ``` | |||
| MOSE Web/ | |||
| ├── public/ # 静态资源 | |||
| ├── src/ | |||
| │ ├── assets/ # 项目资源文件 | |||
| │ ├── components/ # 组件 | |||
| │ │ └── layout/ # 布局组件 | |||
| │ ├── i18n/ # 国际化 | |||
| │ │ └── locales/ # 语言文件 | |||
| │ ├── router/ # 路由 | |||
| │ ├── views/ # 页面 | |||
| │ ├── App.vue # 根组件 | |||
| │ ├── main.ts # 入口文件 | |||
| │ └── style.css # 全局样式 | |||
| ├── index.html # HTML 模板 | |||
| ├── package.json # 项目配置 | |||
| ├── tailwind.config.js # Tailwind 配置 | |||
| ├── tsconfig.json # TypeScript 配置 | |||
| └── vite.config.ts # Vite 配置 | |||
| ``` | |||
| @ -0,0 +1,20 @@ | |||
| <!doctype html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8" /> | |||
| <link rel="icon" type="image/svg+xml" href="/vite.svg" /> | |||
| <link href="/src/style.css" rel="stylesheet"> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
| <meta name="description" content="MOSE Blockchain - Next-generation blockchain platform for high performance, security, and scalability" /> | |||
| <meta name="keywords" content="blockchain, crypto, MOSE, DeFi, NFT, DAO" /> | |||
| <title>MOSE Blockchain</title> | |||
| <!-- Google Fonts --> | |||
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |||
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |||
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Montserrat:wght@500;600;700;800&display=swap" rel="stylesheet"> | |||
| </head> | |||
| <body class="bg-background"> | |||
| <div id="app"></div> | |||
| <script type="module" src="/src/main.ts"></script> | |||
| </body> | |||
| </html> | |||
| @ -0,0 +1,26 @@ | |||
| { | |||
| "name": "mose-web", | |||
| "private": true, | |||
| "version": "0.0.0", | |||
| "type": "module", | |||
| "scripts": { | |||
| "dev": "vite", | |||
| "build": "vue-tsc -b && vite build", | |||
| "preview": "vite preview" | |||
| }, | |||
| "dependencies": { | |||
| "@tailwindcss/vite": "^4.1.11", | |||
| "tailwindcss": "^4.1.11", | |||
| "vue": "^3.5.13", | |||
| "vue-i18n": "^11.1.9", | |||
| "vue-router": "^4.5.1" | |||
| }, | |||
| "devDependencies": { | |||
| "@types/node": "^24.0.13", | |||
| "@vitejs/plugin-vue": "^5.2.1", | |||
| "@vue/tsconfig": "^0.7.0", | |||
| "typescript": "~5.7.2", | |||
| "vite": "^6.1.0", | |||
| "vue-tsc": "^2.2.0" | |||
| } | |||
| } | |||
| @ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg> | |||
| @ -0,0 +1,43 @@ | |||
| <script setup lang="ts"> | |||
| import { ref } from 'vue'; | |||
| import { useI18n } from 'vue-i18n'; | |||
| import NavBar from '@/components/layout/NavBar.vue'; | |||
| import Footer from '@/components/layout/Footer.vue'; | |||
| const { locale } = useI18n(); | |||
| // 切换语言 | |||
| const changeLanguage = (lang: string) => { | |||
| locale.value = lang; | |||
| localStorage.setItem('language', lang); | |||
| }; | |||
| </script> | |||
| <template> | |||
| <div class="min-h-screen flex flex-col bg-background text-text"> | |||
| <NavBar @change-language="changeLanguage" /> | |||
| <main class="flex-grow"> | |||
| <router-view v-slot="{ Component }"> | |||
| <transition name="fade" mode="out-in"> | |||
| <component :is="Component" /> | |||
| </transition> | |||
| </router-view> | |||
| </main> | |||
| <Footer /> | |||
| </div> | |||
| </template> | |||
| <style> | |||
| .fade-enter-active, | |||
| .fade-leave-active { | |||
| transition: opacity 0.3s ease; | |||
| } | |||
| .fade-enter-from, | |||
| .fade-leave-to { | |||
| opacity: 0; | |||
| } | |||
| </style> | |||
| @ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg> | |||
| @ -0,0 +1,41 @@ | |||
| <script setup lang="ts"> | |||
| import { ref } from 'vue' | |||
| defineProps<{ msg: string }>() | |||
| const count = ref(0) | |||
| </script> | |||
| <template> | |||
| <h1>{{ msg }}</h1> | |||
| <div class="card"> | |||
| <button type="button" @click="count++">count is {{ count }}</button> | |||
| <p> | |||
| Edit | |||
| <code>components/HelloWorld.vue</code> to test HMR | |||
| </p> | |||
| </div> | |||
| <p> | |||
| Check out | |||
| <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank" | |||
| >create-vue</a | |||
| >, the official Vue + Vite starter | |||
| </p> | |||
| <p> | |||
| Learn more about IDE Support for Vue in the | |||
| <a | |||
| href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support" | |||
| target="_blank" | |||
| >Vue Docs Scaling up Guide</a | |||
| >. | |||
| </p> | |||
| <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p> | |||
| </template> | |||
| <style scoped> | |||
| .read-the-docs { | |||
| color: #888; | |||
| } | |||
| </style> | |||
| @ -0,0 +1,102 @@ | |||
| <script setup lang="ts"> | |||
| import { useI18n } from 'vue-i18n'; | |||
| const { t } = useI18n(); | |||
| // 社交媒体链接 | |||
| const socialLinks = [ | |||
| { name: 'Twitter', icon: 'twitter', url: 'https://twitter.com/mose' }, | |||
| { name: 'Discord', icon: 'discord', url: 'https://discord.gg/mose' }, | |||
| { name: 'Telegram', icon: 'telegram', url: 'https://t.me/mose' }, | |||
| { name: 'GitHub', icon: 'github', url: 'https://github.com/mose' }, | |||
| ]; | |||
| // 当前年份 | |||
| const currentYear = new Date().getFullYear(); | |||
| </script> | |||
| <template> | |||
| <footer class="bg-background-dark text-text-secondary py-12 px-6 md:px-12 lg:px-24"> | |||
| <div class="container mx-auto"> | |||
| <!-- Footer Top Section --> | |||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 mb-12"> | |||
| <!-- Logo & Description --> | |||
| <div> | |||
| <div class="flex items-center mb-4"> | |||
| <img src="/public/vite.svg" alt="MOSE Logo" class="h-8 w-auto mr-2" /> | |||
| <span class="text-xl font-bold text-primary-light">MOSE</span> | |||
| </div> | |||
| <p class="text-sm mb-6"> | |||
| MOSE is a next-generation blockchain platform designed for high performance, security, and scalability. | |||
| </p> | |||
| <!-- Social Links --> | |||
| <div class="flex space-x-4"> | |||
| <a | |||
| v-for="link in socialLinks" | |||
| :key="link.name" | |||
| :href="link.url" | |||
| target="_blank" | |||
| rel="noopener noreferrer" | |||
| class="text-text-secondary hover:text-primary-light transition-colors duration-200" | |||
| > | |||
| <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"> | |||
| <!-- Simplified SVG icons for demo purposes --> | |||
| <path v-if="link.icon === 'twitter'" d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path> | |||
| <path v-if="link.icon === 'discord'" d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.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"></path> | |||
| <path v-if="link.icon === 'telegram'" d="M24 12c0 6.627-5.373 12-12 12S0 18.627 0 12 5.373 0 12 0s12 5.373 12 12zm-6.465-3.192c-.379-.12-1.68-.523-3.037-.763a9.45 9.45 0 0 0-.398-.053c-.813-.095-1.49.597-1.001 1.319.26.437.54.873.547 1.519a20.32 20.32 0 0 1-.172 2.313c-.19.256-.385.186-.53.074a22.813 22.813 0 0 1-1.287-1.048c-.145-.127-.349-.21-.571-.264-.782-.188-1.296.276-1.001.913.026.061.074.138.148.256a9.98 9.98 0 0 0 1.579 1.911c.947.933 2.422 2.153 3.134 2.612.932.593 2.16.638 2.504.695.485.067 1.284-.117 1.478-.491.112-.214.183-.492.22-.797.073-.594.128-1.344.107-2.116a2.24 2.24 0 0 0-.169-.868c-.098-.231-.382-.454-.753-.563z"></path> | |||
| <path v-if="link.icon === 'github'" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path> | |||
| </svg> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| <!-- Quick Links --> | |||
| <div> | |||
| <h3 class="text-lg font-medium text-text mb-4">{{ t('nav.ecosystem') }}</h3> | |||
| <ul class="space-y-2"> | |||
| <li><router-link to="/ecosystem/defi" class="hover:text-primary-light transition-colors duration-200">DeFi</router-link></li> | |||
| <li><router-link to="/ecosystem/nft" class="hover:text-primary-light transition-colors duration-200">NFT</router-link></li> | |||
| <li><router-link to="/ecosystem/dao" class="hover:text-primary-light transition-colors duration-200">DAO</router-link></li> | |||
| <li><router-link to="/ecosystem/gaming" class="hover:text-primary-light transition-colors duration-200">{{ t('ecosystem.categories.gaming') }}</router-link></li> | |||
| </ul> | |||
| </div> | |||
| <!-- Resources --> | |||
| <div> | |||
| <h3 class="text-lg font-medium text-text mb-4">{{ t('nav.resources') }}</h3> | |||
| <ul class="space-y-2"> | |||
| <li><router-link to="/resources/docs" class="hover:text-primary-light transition-colors duration-200">{{ t('ecosystem.resources.docs') }}</router-link></li> | |||
| <li><router-link to="/resources/github" class="hover:text-primary-light transition-colors duration-200">{{ t('ecosystem.resources.github') }}</router-link></li> | |||
| <li><router-link to="/resources/grants" class="hover:text-primary-light transition-colors duration-200">{{ t('ecosystem.resources.grants') }}</router-link></li> | |||
| <li><router-link to="/resources/community" class="hover:text-primary-light transition-colors duration-200">{{ t('ecosystem.resources.community') }}</router-link></li> | |||
| </ul> | |||
| </div> | |||
| <!-- Contact --> | |||
| <div> | |||
| <h3 class="text-lg font-medium text-text mb-4">{{ t('nav.contact') }}</h3> | |||
| <ul class="space-y-2"> | |||
| <li><a href="mailto:info@mose.io" class="hover:text-primary-light transition-colors duration-200">info@mose.io</a></li> | |||
| <li><a href="mailto:support@mose.io" class="hover:text-primary-light transition-colors duration-200">support@mose.io</a></li> | |||
| <li><router-link to="/contact" class="hover:text-primary-light transition-colors duration-200">{{ t('nav.contact') }}</router-link></li> | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| <!-- Footer Bottom --> | |||
| <div class="pt-8 border-t border-background-light flex flex-col md:flex-row justify-between items-center"> | |||
| <p class="text-sm mb-4 md:mb-0"> | |||
| © {{ currentYear }} MOSE. {{ t('footer.rights') }}. | |||
| </p> | |||
| <div class="flex space-x-6 text-sm"> | |||
| <router-link to="/privacy" class="hover:text-primary-light transition-colors duration-200"> | |||
| {{ t('footer.privacy') }} | |||
| </router-link> | |||
| <router-link to="/terms" class="hover:text-primary-light transition-colors duration-200"> | |||
| {{ t('footer.terms') }} | |||
| </router-link> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </footer> | |||
| </template> | |||
| @ -0,0 +1,171 @@ | |||
| <script setup lang="ts"> | |||
| import { ref, computed } from 'vue'; | |||
| import { useI18n } from 'vue-i18n'; | |||
| import { useRouter } from 'vue-router'; | |||
| const { t, locale } = useI18n(); | |||
| const router = useRouter(); | |||
| const isMenuOpen = ref(false); | |||
| // 切换菜单 | |||
| const toggleMenu = () => { | |||
| isMenuOpen.value = !isMenuOpen.value; | |||
| }; | |||
| // 切换语言 | |||
| const changeLanguage = (lang: string) => { | |||
| emit('changeLanguage', lang); | |||
| }; | |||
| // 语言选项 | |||
| const languages = [ | |||
| { code: 'en', name: 'English' }, | |||
| { code: 'zh', name: '中文' }, | |||
| { code: 'ja', name: '日本語' } | |||
| ]; | |||
| // 当前语言 | |||
| const currentLanguage = computed(() => { | |||
| return languages.find(lang => lang.code === locale.value)?.name || 'English'; | |||
| }); | |||
| // 导航菜单 | |||
| const navItems = [ | |||
| { name: t('nav.home'), path: '/' }, | |||
| { name: t('nav.ecosystem'), path: '/ecosystem' }, | |||
| { name: t('nav.about'), path: '/about' }, | |||
| { name: t('nav.resources'), path: '/resources' }, | |||
| { name: t('nav.community'), path: '/community' }, | |||
| { name: t('nav.faq'), path: '/faq' }, | |||
| { name: t('nav.contact'), path: '/contact' } | |||
| ]; | |||
| // 语言下拉菜单 | |||
| const isLangDropdownOpen = ref(false); | |||
| const toggleLangDropdown = () => { | |||
| isLangDropdownOpen.value = !isLangDropdownOpen.value; | |||
| }; | |||
| // 定义emit | |||
| const emit = defineEmits(['changeLanguage']); | |||
| </script> | |||
| <template> | |||
| <header class="bg-background-dark text-text py-4 px-6 md:px-12 lg:px-24 fixed w-full z-50"> | |||
| <div class="container mx-auto flex justify-between items-center"> | |||
| <!-- Logo --> | |||
| <router-link to="/" class="flex items-center"> | |||
| <img src="/public/vite.svg" alt="MOSE Logo" class="h-8 w-auto mr-2" /> | |||
| <span class="text-xl font-bold text-primary-light">MOSE</span> | |||
| </router-link> | |||
| <!-- Desktop Navigation --> | |||
| <nav class="hidden md:flex items-center space-x-6"> | |||
| <router-link | |||
| v-for="item in navItems" | |||
| :key="item.path" | |||
| :to="item.path" | |||
| class="text-text-secondary hover:text-text transition-colors duration-200" | |||
| :class="{ 'text-primary-light font-medium': $route.path === item.path }" | |||
| > | |||
| {{ item.name }} | |||
| </router-link> | |||
| <!-- Language Selector --> | |||
| <div class="relative"> | |||
| <button | |||
| @click="toggleLangDropdown" | |||
| class="flex items-center text-text-secondary hover:text-text" | |||
| > | |||
| {{ currentLanguage }} | |||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ml-1" 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="isLangDropdownOpen" | |||
| class="absolute right-0 mt-2 w-40 bg-background-light rounded-md shadow-lg py-1 z-10" | |||
| > | |||
| <button | |||
| v-for="lang in languages" | |||
| :key="lang.code" | |||
| @click="changeLanguage(lang.code); toggleLangDropdown()" | |||
| class="block w-full text-left px-4 py-2 text-text-secondary hover:bg-background hover:text-text" | |||
| :class="{ 'text-primary-light': locale === lang.code }" | |||
| > | |||
| {{ lang.name }} | |||
| </button> | |||
| </div> | |||
| </div> | |||
| </nav> | |||
| <!-- Mobile Menu Button --> | |||
| <button | |||
| @click="toggleMenu" | |||
| class="md:hidden text-text-secondary hover:text-text focus:outline-none" | |||
| > | |||
| <svg | |||
| xmlns="http://www.w3.org/2000/svg" | |||
| class="h-6 w-6" | |||
| fill="none" | |||
| viewBox="0 0 24 24" | |||
| stroke="currentColor" | |||
| > | |||
| <path | |||
| v-if="!isMenuOpen" | |||
| stroke-linecap="round" | |||
| stroke-linejoin="round" | |||
| stroke-width="2" | |||
| d="M4 6h16M4 12h16M4 18h16" | |||
| /> | |||
| <path | |||
| v-else | |||
| stroke-linecap="round" | |||
| stroke-linejoin="round" | |||
| stroke-width="2" | |||
| d="M6 18L18 6M6 6l12 12" | |||
| /> | |||
| </svg> | |||
| </button> | |||
| </div> | |||
| <!-- Mobile Menu --> | |||
| <div | |||
| v-show="isMenuOpen" | |||
| class="md:hidden bg-background-light mt-4 rounded-lg py-4 px-6 shadow-lg" | |||
| > | |||
| <div class="flex flex-col space-y-4"> | |||
| <router-link | |||
| v-for="item in navItems" | |||
| :key="item.path" | |||
| :to="item.path" | |||
| class="text-text-secondary hover:text-text py-2" | |||
| :class="{ 'text-primary-light font-medium': $route.path === item.path }" | |||
| @click="isMenuOpen = false" | |||
| > | |||
| {{ item.name }} | |||
| </router-link> | |||
| <!-- Mobile Language Selector --> | |||
| <div class="py-2 border-t border-background"> | |||
| <p class="text-text-secondary mb-2">{{ t('language.en') }}</p> | |||
| <div class="flex flex-col space-y-2"> | |||
| <button | |||
| v-for="lang in languages" | |||
| :key="lang.code" | |||
| @click="changeLanguage(lang.code); isMenuOpen = false" | |||
| class="text-left text-text-secondary hover:text-text" | |||
| :class="{ 'text-primary-light': locale === lang.code }" | |||
| > | |||
| {{ lang.name }} | |||
| </button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </header> | |||
| <!-- Spacer to prevent content from hiding under fixed header --> | |||
| <div class="h-16"></div> | |||
| </template> | |||
| @ -0,0 +1,34 @@ | |||
| import { createI18n } from 'vue-i18n' | |||
| import en from './locales/en.json' | |||
| import zh from './locales/zh.json' | |||
| import ja from './locales/ja.json' | |||
| // 获取浏览器语言或从本地存储中获取 | |||
| const getBrowserLanguage = () => { | |||
| const storedLanguage = localStorage.getItem('language') | |||
| if (storedLanguage) { | |||
| return storedLanguage | |||
| } | |||
| const browserLanguage = navigator.language.toLowerCase() | |||
| if (browserLanguage.includes('zh')) { | |||
| return 'zh' | |||
| } else if (browserLanguage.includes('ja')) { | |||
| return 'ja' | |||
| } else { | |||
| return 'en' // 默认英语 | |||
| } | |||
| } | |||
| const i18n = createI18n({ | |||
| legacy: false, // 使用组合式API | |||
| locale: getBrowserLanguage(), | |||
| fallbackLocale: 'en', | |||
| messages: { | |||
| en, | |||
| zh, | |||
| ja | |||
| } | |||
| }) | |||
| export default i18n | |||
| @ -0,0 +1,55 @@ | |||
| { | |||
| "nav": { | |||
| "home": "Home", | |||
| "ecosystem": "Ecosystem", | |||
| "about": "About", | |||
| "resources": "Resources", | |||
| "community": "Community", | |||
| "faq": "FAQ", | |||
| "contact": "Contact" | |||
| }, | |||
| "ecosystem": { | |||
| "title": "Ecosystem", | |||
| "subtitle": "Explore the MOSE ecosystem and discover the various projects and applications built on our platform", | |||
| "categories": { | |||
| "all": "All", | |||
| "defi": "DeFi", | |||
| "nft": "NFT", | |||
| "dao": "DAO", | |||
| "gaming": "Gaming", | |||
| "infrastructure": "Infrastructure", | |||
| "social": "Social" | |||
| }, | |||
| "projects": { | |||
| "featured": "Featured Projects", | |||
| "viewAll": "View All", | |||
| "learnMore": "Learn More" | |||
| }, | |||
| "partners": { | |||
| "title": "Strategic Partners", | |||
| "subtitle": "Organizations and projects that work with us to expand the MOSE ecosystem" | |||
| }, | |||
| "join": { | |||
| "title": "Join Our Ecosystem", | |||
| "subtitle": "Build the next generation of decentralized applications on MOSE", | |||
| "cta": "Apply Now" | |||
| }, | |||
| "resources": { | |||
| "title": "Developer Resources", | |||
| "docs": "Documentation", | |||
| "github": "GitHub", | |||
| "grants": "Grants Program", | |||
| "community": "Developer Community" | |||
| } | |||
| }, | |||
| "footer": { | |||
| "rights": "All rights reserved", | |||
| "privacy": "Privacy Policy", | |||
| "terms": "Terms of Service" | |||
| }, | |||
| "language": { | |||
| "en": "English", | |||
| "zh": "中文", | |||
| "ja": "日本語" | |||
| } | |||
| } | |||
| @ -0,0 +1,55 @@ | |||
| { | |||
| "nav": { | |||
| "home": "ホーム", | |||
| "ecosystem": "エコシステム", | |||
| "about": "私たちについて", | |||
| "resources": "リソース", | |||
| "community": "コミュニティ", | |||
| "faq": "よくある質問", | |||
| "contact": "お問い合わせ" | |||
| }, | |||
| "ecosystem": { | |||
| "title": "エコシステム", | |||
| "subtitle": "MOSEエコシステムを探索し、プラットフォーム上に構築されたさまざまなプロジェクトとアプリケーションを発見しましょう", | |||
| "categories": { | |||
| "all": "すべて", | |||
| "defi": "DeFi", | |||
| "nft": "NFT", | |||
| "dao": "DAO", | |||
| "gaming": "ゲーム", | |||
| "infrastructure": "インフラストラクチャ", | |||
| "social": "ソーシャル" | |||
| }, | |||
| "projects": { | |||
| "featured": "注目のプロジェクト", | |||
| "viewAll": "すべて表示", | |||
| "learnMore": "詳細を見る" | |||
| }, | |||
| "partners": { | |||
| "title": "戦略的パートナー", | |||
| "subtitle": "MOSEエコシステムの拡大に協力する組織とプロジェクト" | |||
| }, | |||
| "join": { | |||
| "title": "エコシステムに参加する", | |||
| "subtitle": "MOSEで次世代の分散型アプリケーションを構築する", | |||
| "cta": "今すぐ申し込む" | |||
| }, | |||
| "resources": { | |||
| "title": "開発者リソース", | |||
| "docs": "ドキュメント", | |||
| "github": "GitHub", | |||
| "grants": "助成金プログラム", | |||
| "community": "開発者コミュニティ" | |||
| } | |||
| }, | |||
| "footer": { | |||
| "rights": "全著作権所有", | |||
| "privacy": "プライバシーポリシー", | |||
| "terms": "利用規約" | |||
| }, | |||
| "language": { | |||
| "en": "English", | |||
| "zh": "中文", | |||
| "ja": "日本語" | |||
| } | |||
| } | |||
| @ -0,0 +1,55 @@ | |||
| { | |||
| "nav": { | |||
| "home": "首页", | |||
| "ecosystem": "生态系统", | |||
| "about": "关于我们", | |||
| "resources": "资源", | |||
| "community": "社区", | |||
| "faq": "常见问题", | |||
| "contact": "联系我们" | |||
| }, | |||
| "ecosystem": { | |||
| "title": "生态系统", | |||
| "subtitle": "探索MOSE生态系统,发现在我们平台上构建的各种项目和应用", | |||
| "categories": { | |||
| "all": "全部", | |||
| "defi": "去中心化金融", | |||
| "nft": "非同质化代币", | |||
| "dao": "去中心化自治组织", | |||
| "gaming": "游戏", | |||
| "infrastructure": "基础设施", | |||
| "social": "社交" | |||
| }, | |||
| "projects": { | |||
| "featured": "精选项目", | |||
| "viewAll": "查看全部", | |||
| "learnMore": "了解更多" | |||
| }, | |||
| "partners": { | |||
| "title": "战略合作伙伴", | |||
| "subtitle": "与我们合作拓展MOSE生态系统的组织和项目" | |||
| }, | |||
| "join": { | |||
| "title": "加入我们的生态系统", | |||
| "subtitle": "在MOSE上构建下一代去中心化应用", | |||
| "cta": "立即申请" | |||
| }, | |||
| "resources": { | |||
| "title": "开发者资源", | |||
| "docs": "文档", | |||
| "github": "GitHub", | |||
| "grants": "资助计划", | |||
| "community": "开发者社区" | |||
| } | |||
| }, | |||
| "footer": { | |||
| "rights": "版权所有", | |||
| "privacy": "隐私政策", | |||
| "terms": "服务条款" | |||
| }, | |||
| "language": { | |||
| "en": "English", | |||
| "zh": "中文", | |||
| "ja": "日本語" | |||
| } | |||
| } | |||
| @ -0,0 +1,12 @@ | |||
| import { createApp } from 'vue' | |||
| import './style.css' | |||
| import App from './App.vue' | |||
| import router from './router' | |||
| import i18n from './i18n' | |||
| const app = createApp(App) | |||
| app.use(router) | |||
| app.use(i18n) | |||
| app.mount('#app') | |||
| @ -0,0 +1,34 @@ | |||
| import { createRouter, createWebHistory } from 'vue-router' | |||
| const routes = [ | |||
| { | |||
| path: '/', | |||
| name: 'Home', | |||
| component: () => import('@/views/Home.vue') | |||
| }, | |||
| { | |||
| path: '/ecosystem', | |||
| name: 'Ecosystem', | |||
| component: () => import('@/views/Ecosystem.vue') | |||
| }, | |||
| { | |||
| path: '/about', | |||
| name: 'About', | |||
| component: () => import('@/views/About.vue') | |||
| }, | |||
| { | |||
| path: '/:pathMatch(.*)*', | |||
| name: 'NotFound', | |||
| component: () => import('@/views/NotFound.vue') | |||
| } | |||
| ] | |||
| const router = createRouter({ | |||
| history: createWebHistory(), | |||
| routes, | |||
| scrollBehavior() { | |||
| return { top: 0 } | |||
| } | |||
| }) | |||
| export default router | |||
| @ -0,0 +1,213 @@ | |||
| @import "tailwindcss"; | |||
| @layer base { | |||
| :root { | |||
| --color-primary: #1E40AF; | |||
| --color-primary-light: #3B82F6; | |||
| --color-primary-dark: #1E3A8A; | |||
| --color-secondary: #10B981; | |||
| --color-secondary-light: #34D399; | |||
| --color-secondary-dark: #059669; | |||
| --color-background: #0F172A; | |||
| --color-background-light: #1E293B; | |||
| --color-background-dark: #020617; | |||
| --color-accent: #F59E0B; | |||
| --color-accent-light: #FBBF24; | |||
| --color-accent-dark: #D97706; | |||
| --color-text: #F8FAFC; | |||
| --color-text-secondary: #94A3B8; | |||
| --color-text-dark: #1E293B; | |||
| } | |||
| html { | |||
| scroll-behavior: smooth; | |||
| } | |||
| body { | |||
| font-family: 'Inter', system-ui, sans-serif; | |||
| line-height: 1.5; | |||
| -webkit-font-smoothing: antialiased; | |||
| -moz-osx-font-smoothing: grayscale; | |||
| background-color: var(--color-background); | |||
| color: var(--color-text); | |||
| } | |||
| h1, h2, h3, h4, h5, h6 { | |||
| font-family: 'Montserrat', sans-serif; | |||
| line-height: 1.2; | |||
| } | |||
| } | |||
| /* 自定义颜色类 */ | |||
| .bg-primary { | |||
| background-color: var(--color-primary); | |||
| } | |||
| .bg-primary-light { | |||
| background-color: var(--color-primary-light); | |||
| } | |||
| .bg-primary-dark { | |||
| background-color: var(--color-primary-dark); | |||
| } | |||
| .bg-secondary { | |||
| background-color: var(--color-secondary); | |||
| } | |||
| .bg-secondary-light { | |||
| background-color: var(--color-secondary-light); | |||
| } | |||
| .bg-secondary-dark { | |||
| background-color: var(--color-secondary-dark); | |||
| } | |||
| .bg-background { | |||
| background-color: var(--color-background); | |||
| } | |||
| .bg-background-light { | |||
| background-color: var(--color-background-light); | |||
| } | |||
| .bg-background-dark { | |||
| background-color: var(--color-background-dark); | |||
| } | |||
| .bg-accent { | |||
| background-color: var(--color-accent); | |||
| } | |||
| .bg-accent-light { | |||
| background-color: var(--color-accent-light); | |||
| } | |||
| .bg-accent-dark { | |||
| background-color: var(--color-accent-dark); | |||
| } | |||
| .text-primary { | |||
| color: var(--color-primary); | |||
| } | |||
| .text-primary-light { | |||
| color: var(--color-primary-light); | |||
| } | |||
| .text-primary-dark { | |||
| color: var(--color-primary-dark); | |||
| } | |||
| .text-secondary { | |||
| color: var(--color-secondary); | |||
| } | |||
| .text-text { | |||
| color: var(--color-text); | |||
| } | |||
| .text-text-secondary { | |||
| color: var(--color-text-secondary); | |||
| } | |||
| .text-text-dark { | |||
| color: var(--color-text-dark); | |||
| } | |||
| .border-primary { | |||
| border-color: var(--color-primary); | |||
| } | |||
| .border-primary-light { | |||
| border-color: var(--color-primary-light); | |||
| } | |||
| /* 自定义容器和按钮样式 */ | |||
| .container { | |||
| width: 100%; | |||
| margin-left: auto; | |||
| margin-right: auto; | |||
| padding-left: 1rem; | |||
| padding-right: 1rem; | |||
| } | |||
| @media (min-width: 640px) { | |||
| .container { | |||
| max-width: 640px; | |||
| } | |||
| } | |||
| @media (min-width: 768px) { | |||
| .container { | |||
| max-width: 768px; | |||
| padding-left: 1.5rem; | |||
| padding-right: 1.5rem; | |||
| } | |||
| } | |||
| @media (min-width: 1024px) { | |||
| .container { | |||
| max-width: 1024px; | |||
| padding-left: 2rem; | |||
| padding-right: 2rem; | |||
| } | |||
| } | |||
| @media (min-width: 1280px) { | |||
| .container { | |||
| max-width: 1280px; | |||
| } | |||
| } | |||
| .btn { | |||
| display: inline-block; | |||
| padding: 0.75rem 1.5rem; | |||
| border-radius: 0.5rem; | |||
| font-weight: 500; | |||
| transition-property: background-color, border-color, color; | |||
| transition-duration: 300ms; | |||
| } | |||
| .btn-primary { | |||
| background-color: var(--color-primary); | |||
| color: var(--color-text); | |||
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); | |||
| } | |||
| .btn-primary:hover { | |||
| background-color: var(--color-primary-dark); | |||
| } | |||
| .btn-outline { | |||
| background-color: transparent; | |||
| border: 1px solid var(--color-primary-light); | |||
| color: var(--color-primary-light); | |||
| } | |||
| .btn-outline:hover { | |||
| background-color: var(--color-primary-light); | |||
| background-opacity: 0.1; | |||
| } | |||
| .shadow-card { | |||
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |||
| } | |||
| .shadow-button { | |||
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); | |||
| } | |||
| .blur-3xl { | |||
| --tw-blur: blur(64px); | |||
| filter: var(--tw-blur); | |||
| } | |||
| /* 自定义滚动条 */ | |||
| ::-webkit-scrollbar { | |||
| width: 8px; | |||
| height: 8px; | |||
| } | |||
| ::-webkit-scrollbar-track { | |||
| background: #1E293B; | |||
| } | |||
| ::-webkit-scrollbar-thumb { | |||
| background: #3B82F6; | |||
| border-radius: 4px; | |||
| } | |||
| ::-webkit-scrollbar-thumb:hover { | |||
| background: #2563EB; | |||
| } | |||
| @ -0,0 +1,183 @@ | |||
| <script setup lang="ts"> | |||
| import { useI18n } from 'vue-i18n'; | |||
| const { t } = useI18n(); | |||
| // 团队成员数据 | |||
| const teamMembers = [ | |||
| { | |||
| id: 1, | |||
| name: 'John Doe', | |||
| position: 'CEO & Founder', | |||
| image: '/public/images.png', | |||
| linkedin: 'https://linkedin.com' | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: 'Jane Smith', | |||
| position: 'CTO', | |||
| image: '/public/images.png', | |||
| linkedin: 'https://linkedin.com' | |||
| }, | |||
| { | |||
| id: 3, | |||
| name: 'Mike Johnson', | |||
| position: 'Lead Developer', | |||
| image: '/public/images.png', | |||
| linkedin: 'https://linkedin.com' | |||
| }, | |||
| { | |||
| id: 4, | |||
| name: 'Sarah Williams', | |||
| position: 'Marketing Director', | |||
| image: '/public/images.png', | |||
| linkedin: 'https://linkedin.com' | |||
| } | |||
| ]; | |||
| // 里程碑数据 | |||
| const milestones = [ | |||
| { | |||
| year: '2021', | |||
| title: 'MOSE Founded', | |||
| description: 'MOSE was founded with a vision to create a high-performance blockchain platform.' | |||
| }, | |||
| { | |||
| year: '2022', | |||
| title: 'Testnet Launch', | |||
| description: 'Successfully launched our testnet with key features and functionalities.' | |||
| }, | |||
| { | |||
| year: '2023', | |||
| title: 'Mainnet Beta', | |||
| description: 'Released the beta version of our mainnet with improved performance and security.' | |||
| }, | |||
| { | |||
| year: '2024', | |||
| title: 'Ecosystem Growth', | |||
| description: 'Expanded our ecosystem with various projects and partnerships.' | |||
| } | |||
| ]; | |||
| </script> | |||
| <template> | |||
| <div class="bg-background min-h-screen"> | |||
| <!-- Hero Section --> | |||
| <section class="relative py-24 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"> | |||
| 关于我们 | |||
| </h1> | |||
| <p class="text-lg md:text-xl text-text-secondary mb-8"> | |||
| 了解MOSE的愿景、使命和团队 | |||
| </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-light blur-3xl"></div> | |||
| <div class="absolute top-1/2 right-0 w-80 h-80 rounded-full bg-secondary blur-3xl"></div> | |||
| <div class="absolute -bottom-24 left-1/3 w-72 h-72 rounded-full bg-accent blur-3xl"></div> | |||
| </div> | |||
| </section> | |||
| <!-- Our Story 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"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-6">我们的故事</h2> | |||
| <div class="space-y-6 text-text-secondary"> | |||
| <p> | |||
| MOSE是一个致力于构建高性能、安全和可扩展区块链平台的项目。我们的使命是为去中心化应用提供强大的基础设施,使开发者能够构建下一代的区块链应用。 | |||
| </p> | |||
| <p> | |||
| 我们的团队由区块链技术专家、经验丰富的开发者和行业领导者组成,共同致力于推动区块链技术的发展和应用。 | |||
| </p> | |||
| <p> | |||
| MOSE的核心价值观包括去中心化、安全、可扩展性和社区驱动。我们相信通过这些价值观的指导,我们可以构建一个更加开放、公平和高效的区块链生态系统。 | |||
| </p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| <!-- Team Section --> | |||
| <section class="py-16 px-6 md:px-12 lg:px-24 bg-background-light"> | |||
| <div class="container mx-auto"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-10 text-center"> | |||
| 我们的团队 | |||
| </h2> | |||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8"> | |||
| <div | |||
| v-for="member in teamMembers" | |||
| :key="member.id" | |||
| class="bg-background rounded-xl overflow-hidden shadow-card hover:shadow-lg transition-all duration-300" | |||
| > | |||
| <img :src="member.image" :alt="member.name" class="w-full h-48 object-cover" /> | |||
| <div class="p-5"> | |||
| <h3 class="text-lg font-bold text-text mb-1">{{ member.name }}</h3> | |||
| <p class="text-text-secondary text-sm mb-3">{{ member.position }}</p> | |||
| <a | |||
| :href="member.linkedin" | |||
| target="_blank" | |||
| rel="noopener noreferrer" | |||
| class="text-primary-light hover:text-primary-dark transition-colors duration-200 flex items-center text-sm" | |||
| > | |||
| <svg class="h-4 w-4 mr-1" 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"></path> | |||
| </svg> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| <!-- Milestones Section --> | |||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||
| <div class="container mx-auto"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-10 text-center"> | |||
| 发展历程 | |||
| </h2> | |||
| <div class="max-w-4xl mx-auto"> | |||
| <div class="relative"> | |||
| <!-- Timeline Line --> | |||
| <div class="absolute top-0 left-6 md:left-1/2 w-0.5 h-full bg-primary-light transform -translate-x-1/2"></div> | |||
| <!-- Timeline Items --> | |||
| <div class="space-y-12"> | |||
| <div | |||
| v-for="(milestone, index) in milestones" | |||
| :key="index" | |||
| class="relative" | |||
| > | |||
| <div class="flex flex-col md:flex-row items-center"> | |||
| <!-- Year Bubble --> | |||
| <div | |||
| class="absolute left-6 md:left-1/2 w-12 h-12 bg-primary rounded-full flex items-center justify-center transform -translate-x-1/2 z-10" | |||
| > | |||
| <span class="text-text font-bold text-sm">{{ milestone.year }}</span> | |||
| </div> | |||
| <!-- Content --> | |||
| <div | |||
| class="ml-20 md:ml-0 md:w-1/2 md:pr-8 md:text-right" | |||
| :class="{ 'md:pl-8 md:pr-0 md:text-left md:order-2': index % 2 !== 0 }" | |||
| > | |||
| <h3 class="text-xl font-bold text-text mb-2">{{ milestone.title }}</h3> | |||
| <p class="text-text-secondary">{{ milestone.description }}</p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| </div> | |||
| </template> | |||
| @ -0,0 +1,396 @@ | |||
| <script setup lang="ts"> | |||
| import { ref, computed } from 'vue'; | |||
| import { useI18n } from 'vue-i18n'; | |||
| const { t } = useI18n(); | |||
| // 当前选中的分类 | |||
| const selectedCategory = ref('all'); | |||
| // 分类列表 | |||
| const categories = [ | |||
| { id: 'all', name: t('ecosystem.categories.all') }, | |||
| { id: 'defi', name: t('ecosystem.categories.defi') }, | |||
| { id: 'nft', name: t('ecosystem.categories.nft') }, | |||
| { id: 'dao', name: t('ecosystem.categories.dao') }, | |||
| { id: 'gaming', name: t('ecosystem.categories.gaming') }, | |||
| { id: 'infrastructure', name: t('ecosystem.categories.infrastructure') }, | |||
| { id: 'social', name: t('ecosystem.categories.social') }, | |||
| ]; | |||
| // 项目数据 | |||
| const projects = [ | |||
| { | |||
| id: 1, | |||
| name: 'MOSE Swap', | |||
| description: 'Decentralized exchange with low fees and high liquidity', | |||
| category: 'defi', | |||
| image: '/public/images.png', | |||
| url: 'https://moseswap.io', | |||
| featured: true | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: 'MOSE NFT Marketplace', | |||
| description: 'Trade unique digital assets on the MOSE blockchain', | |||
| category: 'nft', | |||
| image: '/public/images.png', | |||
| url: 'https://mosenft.io', | |||
| featured: true | |||
| }, | |||
| { | |||
| id: 3, | |||
| name: 'MOSE DAO', | |||
| description: 'Decentralized governance for the MOSE ecosystem', | |||
| category: 'dao', | |||
| image: '/public/images.png', | |||
| url: 'https://mosedao.io', | |||
| featured: true | |||
| }, | |||
| { | |||
| id: 4, | |||
| name: 'MOSE Gaming', | |||
| description: 'Play-to-earn games built on MOSE', | |||
| category: 'gaming', | |||
| image: '/public/images.png', | |||
| url: 'https://mosegaming.io', | |||
| featured: false | |||
| }, | |||
| { | |||
| id: 5, | |||
| name: 'MOSE Bridge', | |||
| description: 'Cross-chain bridge for MOSE assets', | |||
| category: 'infrastructure', | |||
| image: '/public/images.png', | |||
| url: 'https://mosebridge.io', | |||
| featured: true | |||
| }, | |||
| { | |||
| id: 6, | |||
| name: 'MOSE Social', | |||
| description: 'Decentralized social network', | |||
| category: 'social', | |||
| image: '/public/images.png', | |||
| url: 'https://mosesocial.io', | |||
| featured: false | |||
| }, | |||
| { | |||
| id: 7, | |||
| name: 'MOSE Lending', | |||
| description: 'Decentralized lending protocol', | |||
| category: 'defi', | |||
| image: '/public/images.png', | |||
| url: 'https://moselending.io', | |||
| featured: false | |||
| }, | |||
| { | |||
| id: 8, | |||
| name: 'MOSE Staking', | |||
| description: 'Stake your MOSE tokens for rewards', | |||
| category: 'defi', | |||
| image: '/public/images.png', | |||
| url: 'https://mosestaking.io', | |||
| featured: false | |||
| } | |||
| ]; | |||
| // 合作伙伴数据 | |||
| const partners = [ | |||
| { | |||
| id: 1, | |||
| name: 'Partner 1', | |||
| logo: '/public/images.png', | |||
| url: 'https://partner1.com' | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: 'Partner 2', | |||
| logo: '/public/images.png', | |||
| url: 'https://partner2.com' | |||
| }, | |||
| { | |||
| id: 3, | |||
| name: 'Partner 3', | |||
| logo: '/public/images.png', | |||
| url: 'https://partner3.com' | |||
| }, | |||
| { | |||
| id: 4, | |||
| name: 'Partner 4', | |||
| logo: '/public/images.png', | |||
| url: 'https://partner4.com' | |||
| }, | |||
| { | |||
| id: 5, | |||
| name: 'Partner 5', | |||
| logo: '/public/images.png', | |||
| url: 'https://partner5.com' | |||
| }, | |||
| { | |||
| id: 6, | |||
| name: 'Partner 6', | |||
| logo: '/public/images.png', | |||
| url: 'https://partner6.com' | |||
| } | |||
| ]; | |||
| // 筛选项目 | |||
| const filteredProjects = computed(() => { | |||
| if (selectedCategory.value === 'all') { | |||
| return projects; | |||
| } else { | |||
| return projects.filter(project => project.category === selectedCategory.value); | |||
| } | |||
| }); | |||
| // 特色项目 | |||
| const featuredProjects = computed(() => { | |||
| return projects.filter(project => project.featured); | |||
| }); | |||
| // 选择分类 | |||
| const selectCategory = (category: string) => { | |||
| selectedCategory.value = category; | |||
| }; | |||
| </script> | |||
| <template> | |||
| <div class="bg-background min-h-screen"> | |||
| <!-- Hero Section --> | |||
| <section class="relative py-24 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"> | |||
| {{ t('ecosystem.title') }} | |||
| </h1> | |||
| <p class="text-lg md:text-xl text-text-secondary mb-8"> | |||
| {{ t('ecosystem.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-light blur-3xl"></div> | |||
| <div class="absolute top-1/2 right-0 w-80 h-80 rounded-full bg-secondary blur-3xl"></div> | |||
| <div class="absolute -bottom-24 left-1/3 w-72 h-72 rounded-full bg-accent blur-3xl"></div> | |||
| </div> | |||
| </section> | |||
| <!-- Featured Projects Section --> | |||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||
| <div class="container mx-auto"> | |||
| <div class="flex justify-between items-center mb-10"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text"> | |||
| {{ t('ecosystem.projects.featured') }} | |||
| </h2> | |||
| <a href="#all-projects" class="text-primary-light hover:text-primary-dark transition-colors duration-200"> | |||
| {{ t('ecosystem.projects.viewAll') }} | |||
| </a> | |||
| </div> | |||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> | |||
| <div | |||
| v-for="project in featuredProjects" | |||
| :key="project.id" | |||
| class="bg-background-light rounded-xl overflow-hidden shadow-card hover:transform hover:scale-105 transition-all duration-300" | |||
| > | |||
| <img :src="project.image" :alt="project.name" class="w-full h-48 object-cover" /> | |||
| <div class="p-6"> | |||
| <h3 class="text-xl font-bold text-text mb-2">{{ project.name }}</h3> | |||
| <p class="text-text-secondary mb-4">{{ project.description }}</p> | |||
| <div class="flex justify-between items-center"> | |||
| <span class="px-3 py-1 bg-background text-primary-light text-xs rounded-full"> | |||
| {{ t(`ecosystem.categories.${project.category}`) }} | |||
| </span> | |||
| <a | |||
| :href="project.url" | |||
| target="_blank" | |||
| rel="noopener noreferrer" | |||
| class="text-primary-light hover:text-primary-dark transition-colors duration-200" | |||
| > | |||
| {{ t('ecosystem.projects.learnMore') }} | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| <!-- All Projects Section --> | |||
| <section id="all-projects" class="py-16 px-6 md:px-12 lg:px-24 bg-background-light"> | |||
| <div class="container mx-auto"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-10"> | |||
| {{ t('ecosystem.title') }} | |||
| </h2> | |||
| <!-- Categories Filter --> | |||
| <div class="flex flex-wrap gap-2 mb-10"> | |||
| <button | |||
| v-for="category in categories" | |||
| :key="category.id" | |||
| @click="selectCategory(category.id)" | |||
| class="px-4 py-2 rounded-full text-sm transition-colors duration-200" | |||
| :class="selectedCategory === category.id | |||
| ? 'bg-primary text-text' | |||
| : 'bg-background-dark text-text-secondary hover:bg-background hover:text-text'" | |||
| > | |||
| {{ category.name }} | |||
| </button> | |||
| </div> | |||
| <!-- Projects Grid --> | |||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"> | |||
| <div | |||
| v-for="project in filteredProjects" | |||
| :key="project.id" | |||
| class="bg-background rounded-xl overflow-hidden shadow-card hover:shadow-lg transition-all duration-300" | |||
| > | |||
| <img :src="project.image" :alt="project.name" class="w-full h-40 object-cover" /> | |||
| <div class="p-5"> | |||
| <h3 class="text-lg font-bold text-text mb-2">{{ project.name }}</h3> | |||
| <p class="text-text-secondary text-sm mb-4">{{ project.description }}</p> | |||
| <div class="flex justify-between items-center"> | |||
| <span class="px-3 py-1 bg-background-dark text-primary-light text-xs rounded-full"> | |||
| {{ t(`ecosystem.categories.${project.category}`) }} | |||
| </span> | |||
| <a | |||
| :href="project.url" | |||
| target="_blank" | |||
| rel="noopener noreferrer" | |||
| class="text-primary-light hover:text-primary-dark transition-colors duration-200 text-sm" | |||
| > | |||
| {{ t('ecosystem.projects.learnMore') }} | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| <!-- Partners Section --> | |||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||
| <div class="container mx-auto"> | |||
| <div class="text-center mb-12"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-4"> | |||
| {{ t('ecosystem.partners.title') }} | |||
| </h2> | |||
| <p class="text-text-secondary max-w-2xl mx-auto"> | |||
| {{ t('ecosystem.partners.subtitle') }} | |||
| </p> | |||
| </div> | |||
| <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-8"> | |||
| <a | |||
| v-for="partner in partners" | |||
| :key="partner.id" | |||
| :href="partner.url" | |||
| target="_blank" | |||
| rel="noopener noreferrer" | |||
| class="flex items-center justify-center p-6 bg-background-light rounded-lg hover:bg-background-dark transition-colors duration-300" | |||
| > | |||
| <img :src="partner.logo" :alt="partner.name" class="max-h-12 max-w-full" /> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| <!-- Join Ecosystem CTA --> | |||
| <section class="py-20 px-6 md:px-12 lg:px-24 bg-primary bg-opacity-10 relative overflow-hidden"> | |||
| <div class="container mx-auto relative z-10"> | |||
| <div class="max-w-3xl mx-auto text-center"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-4"> | |||
| {{ t('ecosystem.join.title') }} | |||
| </h2> | |||
| <p class="text-text-secondary mb-8"> | |||
| {{ t('ecosystem.join.subtitle') }} | |||
| </p> | |||
| <a | |||
| href="#" | |||
| class="inline-block px-8 py-3 bg-primary text-text rounded-lg hover:bg-primary-dark transition-colors duration-300 shadow-button" | |||
| > | |||
| {{ t('ecosystem.join.cta') }} | |||
| </a> | |||
| </div> | |||
| </div> | |||
| <!-- Background Decoration --> | |||
| <div class="absolute top-0 left-0 w-full h-full overflow-hidden opacity-30"> | |||
| <div class="absolute top-0 right-0 w-64 h-64 rounded-full bg-primary blur-3xl"></div> | |||
| <div class="absolute bottom-0 left-0 w-80 h-80 rounded-full bg-primary blur-3xl"></div> | |||
| </div> | |||
| </section> | |||
| <!-- Developer Resources --> | |||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||
| <div class="container mx-auto"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-10"> | |||
| {{ t('ecosystem.resources.title') }} | |||
| </h2> | |||
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> | |||
| <a | |||
| href="#" | |||
| class="bg-background-light p-6 rounded-xl flex flex-col items-center text-center hover:bg-background-dark transition-colors duration-300" | |||
| > | |||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 text-primary-light mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" /> | |||
| </svg> | |||
| <h3 class="text-lg font-bold text-text mb-2">{{ t('ecosystem.resources.docs') }}</h3> | |||
| <p class="text-text-secondary text-sm"> | |||
| Comprehensive documentation for developers | |||
| </p> | |||
| </a> | |||
| <a | |||
| href="#" | |||
| class="bg-background-light p-6 rounded-xl flex flex-col items-center text-center hover:bg-background-dark transition-colors duration-300" | |||
| > | |||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 text-primary-light mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /> | |||
| </svg> | |||
| <h3 class="text-lg font-bold text-text mb-2">{{ t('ecosystem.resources.github') }}</h3> | |||
| <p class="text-text-secondary text-sm"> | |||
| Open source code repositories | |||
| </p> | |||
| </a> | |||
| <a | |||
| href="#" | |||
| class="bg-background-light p-6 rounded-xl flex flex-col items-center text-center hover:bg-background-dark transition-colors duration-300" | |||
| > | |||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 text-primary-light mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> | |||
| </svg> | |||
| <h3 class="text-lg font-bold text-text mb-2">{{ t('ecosystem.resources.grants') }}</h3> | |||
| <p class="text-text-secondary text-sm"> | |||
| Funding for innovative projects | |||
| </p> | |||
| </a> | |||
| <a | |||
| href="#" | |||
| class="bg-background-light p-6 rounded-xl flex flex-col items-center text-center hover:bg-background-dark transition-colors duration-300" | |||
| > | |||
| <svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 text-primary-light mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /> | |||
| </svg> | |||
| <h3 class="text-lg font-bold text-text mb-2">{{ t('ecosystem.resources.community') }}</h3> | |||
| <p class="text-text-secondary text-sm"> | |||
| Join our developer community | |||
| </p> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| </div> | |||
| </template> | |||
| <style scoped> | |||
| /* 添加一些额外的动画效果 */ | |||
| .hover\:transform:hover { | |||
| transform: translateY(-5px); | |||
| } | |||
| </style> | |||
| @ -0,0 +1,90 @@ | |||
| <script setup lang="ts"> | |||
| import { useI18n } from 'vue-i18n'; | |||
| import { useRouter } from 'vue-router'; | |||
| const { t } = useI18n(); | |||
| const router = useRouter(); | |||
| const goToEcosystem = () => { | |||
| router.push('/ecosystem'); | |||
| }; | |||
| </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"> | |||
| MOSE Blockchain | |||
| </h1> | |||
| <p class="text-lg md:text-xl text-text-secondary mb-8"> | |||
| Next-generation blockchain platform for high performance, security, and scalability | |||
| </p> | |||
| <div class="flex flex-col sm:flex-row justify-center gap-4"> | |||
| <button | |||
| @click="goToEcosystem" | |||
| class="px-8 py-3 bg-primary text-text rounded-lg hover:bg-primary-dark transition-colors duration-300 shadow-button" | |||
| > | |||
| {{ t('ecosystem.title') }} | |||
| </button> | |||
| <a | |||
| href="#" | |||
| 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" | |||
| > | |||
| {{ t('ecosystem.resources.docs') }} | |||
| </a> | |||
| </div> | |||
| </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-light blur-3xl"></div> | |||
| <div class="absolute top-1/2 right-0 w-80 h-80 rounded-full bg-secondary blur-3xl"></div> | |||
| <div class="absolute -bottom-24 left-1/3 w-72 h-72 rounded-full bg-accent blur-3xl"></div> | |||
| </div> | |||
| </section> | |||
| <!-- Video Section --> | |||
| <section class="py-16 px-6 md:px-12 lg:px-24"> | |||
| <div class="container mx-auto"> | |||
| <div class="max-w-4xl mx-auto bg-background-light rounded-2xl overflow-hidden shadow-card"> | |||
| <video | |||
| src="/public/MOSEVideo.mp4" | |||
| controls | |||
| class="w-full h-auto" | |||
| poster="/public/images.png" | |||
| ></video> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| <!-- Call to Action --> | |||
| <section class="py-20 px-6 md:px-12 lg:px-24 bg-primary bg-opacity-10 relative overflow-hidden"> | |||
| <div class="container mx-auto relative z-10"> | |||
| <div class="max-w-3xl mx-auto text-center"> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-4"> | |||
| {{ t('ecosystem.join.title') }} | |||
| </h2> | |||
| <p class="text-text-secondary mb-8"> | |||
| {{ t('ecosystem.join.subtitle') }} | |||
| </p> | |||
| <button | |||
| @click="goToEcosystem" | |||
| class="inline-block px-8 py-3 bg-primary text-text rounded-lg hover:bg-primary-dark transition-colors duration-300 shadow-button" | |||
| > | |||
| {{ t('ecosystem.title') }} | |||
| </button> | |||
| </div> | |||
| </div> | |||
| <!-- Background Decoration --> | |||
| <div class="absolute top-0 left-0 w-full h-full overflow-hidden opacity-30"> | |||
| <div class="absolute top-0 right-0 w-64 h-64 rounded-full bg-primary blur-3xl"></div> | |||
| <div class="absolute bottom-0 left-0 w-80 h-80 rounded-full bg-primary blur-3xl"></div> | |||
| </div> | |||
| </section> | |||
| </div> | |||
| </template> | |||
| @ -0,0 +1,27 @@ | |||
| <script setup lang="ts"> | |||
| import { useRouter } from 'vue-router'; | |||
| const router = useRouter(); | |||
| const goHome = () => { | |||
| router.push('/'); | |||
| }; | |||
| </script> | |||
| <template> | |||
| <div class="bg-background min-h-screen flex items-center justify-center px-6 py-24"> | |||
| <div class="text-center"> | |||
| <h1 class="text-6xl md:text-8xl font-bold text-primary-light mb-4">404</h1> | |||
| <h2 class="text-2xl md:text-3xl font-bold text-text mb-6">页面未找到</h2> | |||
| <p class="text-text-secondary mb-8 max-w-md mx-auto"> | |||
| 您访问的页面不存在或已被移除。请检查URL或返回首页。 | |||
| </p> | |||
| <button | |||
| @click="goHome" | |||
| class="px-8 py-3 bg-primary text-text rounded-lg hover:bg-primary-dark transition-colors duration-300 shadow-button" | |||
| > | |||
| 返回首页 | |||
| </button> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| @ -0,0 +1 @@ | |||
| /// <reference types="vite/client" /> | |||
| @ -0,0 +1,20 @@ | |||
| { | |||
| "extends": "@vue/tsconfig/tsconfig.dom.json", | |||
| "compilerOptions": { | |||
| "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", | |||
| /* Linting */ | |||
| "strict": true, | |||
| "noUnusedLocals": true, | |||
| "noUnusedParameters": true, | |||
| "noFallthroughCasesInSwitch": true, | |||
| "noUncheckedSideEffectImports": true, | |||
| /* 路径别名 */ | |||
| "baseUrl": ".", | |||
| "paths": { | |||
| "@/*": ["./src/*"] | |||
| } | |||
| }, | |||
| "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] | |||
| } | |||
| @ -0,0 +1,7 @@ | |||
| { | |||
| "files": [], | |||
| "references": [ | |||
| { "path": "./tsconfig.app.json" }, | |||
| { "path": "./tsconfig.node.json" } | |||
| ] | |||
| } | |||
| @ -0,0 +1,26 @@ | |||
| { | |||
| "compilerOptions": { | |||
| "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", | |||
| "target": "ES2022", | |||
| "lib": ["ES2023"], | |||
| "module": "ESNext", | |||
| "skipLibCheck": true, | |||
| /* Bundler mode */ | |||
| "moduleResolution": "bundler", | |||
| "allowImportingTsExtensions": true, | |||
| "isolatedModules": true, | |||
| "moduleDetection": "force", | |||
| "noEmit": true, | |||
| /* Linting */ | |||
| "strict": true, | |||
| "noUnusedLocals": true, | |||
| "noUnusedParameters": true, | |||
| "noFallthroughCasesInSwitch": true, | |||
| "noUncheckedSideEffectImports": true, | |||
| }, | |||
| "include": ["vite.config.ts"] | |||
| } | |||
| @ -0,0 +1,20 @@ | |||
| import { defineConfig } from 'vite' | |||
| import vue from '@vitejs/plugin-vue' | |||
| import tailwindcss from '@tailwindcss/vite' | |||
| import path from 'path' | |||
| // https://vite.dev/config/ | |||
| export default defineConfig({ | |||
| plugins: [ | |||
| vue(), | |||
| tailwindcss(), | |||
| ], | |||
| server: { | |||
| port: 3000, | |||
| }, | |||
| resolve: { | |||
| alias: { | |||
| '@': path.resolve(__dirname, './src'), | |||
| }, | |||
| }, | |||
| }) | |||