Browse Source

'UI基本做完'

main
hflllll 2 weeks ago
parent
commit
e10f349d6a
5 changed files with 493 additions and 0 deletions
  1. +43
    -0
      src/i18n/locales/en.json
  2. +43
    -0
      src/i18n/locales/ja.json
  3. +43
    -0
      src/i18n/locales/zh.json
  4. +5
    -0
      src/router/index.ts
  5. +359
    -0
      src/views/Resources.vue

+ 43
- 0
src/i18n/locales/en.json View File

@ -65,6 +65,49 @@
"docs": "Documentation"
}
},
"resources": {
"hero": {
"title": "Resources",
"subtitle": "Access documentation, tutorials, SDKs, and other resources to help you build on MOSE"
},
"categories": {
"all": "All Resources",
"docs": "Documentation",
"tutorials": "Tutorials",
"sdks": "SDKs & APIs",
"tools": "Tools",
"community": "Community"
},
"items": {
"docs_title": "Developer Documentation",
"docs_description": "Comprehensive guides and reference documentation for building on MOSE",
"api_title": "API Reference",
"api_description": "Detailed API documentation for integrating with the MOSE blockchain",
"tutorial_beginner_title": "Getting Started Guide",
"tutorial_beginner_description": "Step-by-step tutorials for beginners to start building on MOSE",
"tutorial_advanced_title": "Advanced Tutorials",
"tutorial_advanced_description": "In-depth guides for experienced developers to build complex applications",
"sdk_js_title": "JavaScript SDK",
"sdk_js_description": "Official JavaScript SDK for interacting with the MOSE blockchain",
"sdk_python_title": "Python SDK",
"sdk_python_description": "Official Python SDK for building applications on MOSE",
"explorer_title": "Block Explorer",
"explorer_description": "Explore transactions, blocks, and accounts on the MOSE blockchain",
"wallet_title": "MOSE Wallet",
"wallet_description": "Secure wallet for managing your MOSE assets and interacting with dApps",
"forum_title": "Developer Forum",
"forum_description": "Connect with other developers and get help from the MOSE community",
"github_title": "GitHub Repository",
"github_description": "Access the open-source code, contribute, and report issues"
},
"explore": "Explore",
"newsletter": {
"title": "Stay Updated",
"subtitle": "Subscribe to our newsletter to receive the latest updates, tutorials, and resources",
"placeholder": "Enter your email address",
"button": "Subscribe"
}
},
"about": {
"hero": {
"title": "About Us",


+ 43
- 0
src/i18n/locales/ja.json View File

@ -65,6 +65,49 @@
"docs": "ドキュメント"
}
},
"resources": {
"hero": {
"title": "リソース",
"subtitle": "MOSEでの開発に役立つドキュメント、チュートリアル、SDK、その他のリソースにアクセスする"
},
"categories": {
"all": "すべてのリソース",
"docs": "ドキュメント",
"tutorials": "チュートリアル",
"sdks": "SDKとAPI",
"tools": "ツール",
"community": "コミュニティ"
},
"items": {
"docs_title": "開発者ドキュメント",
"docs_description": "MOSEでの開発のための包括的なガイドとリファレンスドキュメント",
"api_title": "APIリファレンス",
"api_description": "MOSEブロックチェーンと統合するための詳細なAPIドキュメント",
"tutorial_beginner_title": "入門ガイド",
"tutorial_beginner_description": "初心者がMOSEでの開発を始めるためのステップバイステップのチュートリアル",
"tutorial_advanced_title": "高度なチュートリアル",
"tutorial_advanced_description": "経験豊富な開発者が複雑なアプリケーションを構築するための詳細なガイド",
"sdk_js_title": "JavaScript SDK",
"sdk_js_description": "MOSEブロックチェーンと対話するための公式JavaScript SDK",
"sdk_python_title": "Python SDK",
"sdk_python_description": "MOSEでアプリケーションを構築するための公式Python SDK",
"explorer_title": "ブロックエクスプローラー",
"explorer_description": "MOSEブロックチェーン上のトランザクション、ブロック、アカウントを探索する",
"wallet_title": "MOSEウォレット",
"wallet_description": "MOSEの資産を管理し、分散型アプリケーションと対話するための安全なウォレット",
"forum_title": "開発者フォーラム",
"forum_description": "他の開発者と繋がり、MOSEコミュニティからサポートを受ける",
"github_title": "GitHubリポジトリ",
"github_description": "オープンソースコードにアクセスし、貢献し、問題を報告する"
},
"explore": "探索する",
"newsletter": {
"title": "最新情報を入手",
"subtitle": "ニュースレターを購読して、最新の更新情報、チュートリアル、リソースを受け取る",
"placeholder": "メールアドレスを入力",
"button": "購読する"
}
},
"about": {
"hero": {
"title": "私たちについて",


+ 43
- 0
src/i18n/locales/zh.json View File

@ -65,6 +65,49 @@
"docs": "文档"
}
},
"resources": {
"hero": {
"title": "资源",
"subtitle": "获取文档、教程、SDK和其他资源,帮助您在MOSE上进行开发"
},
"categories": {
"all": "所有资源",
"docs": "文档",
"tutorials": "教程",
"sdks": "SDK和API",
"tools": "工具",
"community": "社区"
},
"items": {
"docs_title": "开发者文档",
"docs_description": "全面的指南和参考文档,用于在MOSE上进行开发",
"api_title": "API参考",
"api_description": "详细的API文档,用于与MOSE区块链集成",
"tutorial_beginner_title": "入门指南",
"tutorial_beginner_description": "为初学者提供的分步教程,开始在MOSE上构建应用",
"tutorial_advanced_title": "高级教程",
"tutorial_advanced_description": "为有经验的开发者提供的深入指南,用于构建复杂应用",
"sdk_js_title": "JavaScript SDK",
"sdk_js_description": "官方JavaScript SDK,用于与MOSE区块链交互",
"sdk_python_title": "Python SDK",
"sdk_python_description": "官方Python SDK,用于在MOSE上构建应用",
"explorer_title": "区块浏览器",
"explorer_description": "探索MOSE区块链上的交易、区块和账户",
"wallet_title": "MOSE钱包",
"wallet_description": "安全的钱包,用于管理您的MOSE资产和与去中心化应用交互",
"forum_title": "开发者论坛",
"forum_description": "与其他开发者联系并从MOSE社区获取帮助",
"github_title": "GitHub仓库",
"github_description": "访问开源代码,做出贡献并报告问题"
},
"explore": "探索",
"newsletter": {
"title": "保持更新",
"subtitle": "订阅我们的通讯,接收最新的更新、教程和资源",
"placeholder": "输入您的电子邮箱",
"button": "订阅"
}
},
"about": {
"hero": {
"title": "关于我们",


+ 5
- 0
src/router/index.ts View File

@ -16,6 +16,11 @@ const routes = [
name: 'About',
component: () => import('@/views/About.vue')
},
{
path: '/resources',
name: 'Resources',
component: () => import('@/views/Resources.vue')
},
{
path: '/community',
name: 'Community',


+ 359
- 0
src/views/Resources.vue View File

@ -0,0 +1,359 @@
<script setup lang="ts">
import { ref, onMounted, h } from 'vue';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// Resource categories
const categories = ref([
{ id: 'all', name: t('resources.categories.all') },
{ id: 'docs', name: t('resources.categories.docs') },
{ id: 'tutorials', name: t('resources.categories.tutorials') },
{ id: 'sdks', name: t('resources.categories.sdks') },
{ id: 'tools', name: t('resources.categories.tools') },
{ id: 'community', name: t('resources.categories.community') }
]);
// Active category
const activeCategory = ref('all');
// Resources list
const resources = ref([
{
id: 1,
title: t('resources.items.docs_title'),
description: t('resources.items.docs_description'),
link: 'https://docs.mose.io',
category: 'docs',
icon: 'document'
},
{
id: 2,
title: t('resources.items.api_title'),
description: t('resources.items.api_description'),
link: 'https://api.mose.io',
category: 'docs',
icon: 'code'
},
{
id: 3,
title: t('resources.items.tutorial_beginner_title'),
description: t('resources.items.tutorial_beginner_description'),
link: 'https://learn.mose.io/beginner',
category: 'tutorials',
icon: 'academic-cap'
},
{
id: 4,
title: t('resources.items.tutorial_advanced_title'),
description: t('resources.items.tutorial_advanced_description'),
link: 'https://learn.mose.io/advanced',
category: 'tutorials',
icon: 'academic-cap'
},
{
id: 5,
title: t('resources.items.sdk_js_title'),
description: t('resources.items.sdk_js_description'),
link: 'https://github.com/mose/js-sdk',
category: 'sdks',
icon: 'code-bracket'
},
{
id: 6,
title: t('resources.items.sdk_python_title'),
description: t('resources.items.sdk_python_description'),
link: 'https://github.com/mose/python-sdk',
category: 'sdks',
icon: 'code-bracket'
},
{
id: 7,
title: t('resources.items.explorer_title'),
description: t('resources.items.explorer_description'),
link: 'https://explorer.mose.io',
category: 'tools',
icon: 'magnifying-glass'
},
{
id: 8,
title: t('resources.items.wallet_title'),
description: t('resources.items.wallet_description'),
link: 'https://wallet.mose.io',
category: 'tools',
icon: 'wallet'
},
{
id: 9,
title: t('resources.items.forum_title'),
description: t('resources.items.forum_description'),
link: 'https://forum.mose.io',
category: 'community',
icon: 'chat-bubble-left-right'
},
{
id: 10,
title: t('resources.items.github_title'),
description: t('resources.items.github_description'),
link: 'https://github.com/mose',
category: 'community',
icon: 'code-bracket'
}
]);
// Filtered resources based on active category
const filteredResources = ref([]);
// Filter resources based on active category
const filterResources = () => {
if (activeCategory.value === 'all') {
filteredResources.value = resources.value;
} else {
filteredResources.value = resources.value.filter(resource => resource.category === activeCategory.value);
}
};
// Set active category
const setActiveCategory = (category: string) => {
activeCategory.value = category;
filterResources();
};
// Initialize with all resources
onMounted(() => {
filterResources();
});
// Icon components as Vue render functions
const DocumentIcon = {
render() {
return h('svg', {
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
'stroke-width': '1.5',
stroke: 'currentColor',
class: 'w-6 h-6'
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
d: 'M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z'
})
]);
}
};
const CodeIcon = {
render() {
return h('svg', {
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
'stroke-width': '1.5',
stroke: 'currentColor',
class: 'w-6 h-6'
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
d: 'M14.25 9.75 16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0 0 20.25 18V6A2.25 2.25 0 0 0 18 3.75H6A2.25 2.25 0 0 0 3.75 6v12A2.25 2.25 0 0 0 6 20.25Z'
})
]);
}
};
const AcademicCapIcon = {
render() {
return h('svg', {
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
'stroke-width': '1.5',
stroke: 'currentColor',
class: 'w-6 h-6'
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
d: 'M4.26 10.147a60.438 60.438 0 0 0-.491 6.347A48.62 48.62 0 0 1 12 20.904a48.62 48.62 0 0 1 8.232-4.41 60.46 60.46 0 0 0-.491-6.347m-15.482 0a50.636 50.636 0 0 0-2.658-.813A59.906 59.906 0 0 1 12 3.493a59.903 59.903 0 0 1 10.399 5.84c-.896.248-1.783.52-2.658.814m-15.482 0A50.717 50.717 0 0 1 12 13.489a50.702 50.702 0 0 1 7.74-3.342M6.75 15a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm0 0v-3.675A55.378 55.378 0 0 1 12 8.443m-7.007 11.55A5.981 5.981 0 0 0 6.75 15.75v-1.5'
})
]);
}
};
const CodeBracketIcon = {
render() {
return h('svg', {
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
'stroke-width': '1.5',
stroke: 'currentColor',
class: 'w-6 h-6'
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
d: 'M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5'
})
]);
}
};
const MagnifyingGlassIcon = {
render() {
return h('svg', {
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
'stroke-width': '1.5',
stroke: 'currentColor',
class: 'w-6 h-6'
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
d: 'm21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z'
})
]);
}
};
const WalletIcon = {
render() {
return h('svg', {
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
'stroke-width': '1.5',
stroke: 'currentColor',
class: 'w-6 h-6'
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
d: 'M21 12a2.25 2.25 0 0 0-2.25-2.25H15a3 3 0 1 1-6 0H5.25A2.25 2.25 0 0 0 3 12m18 0v6a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18v-6m18 0V9M3 12V9m18 0a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 9m18 0V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v3'
})
]);
}
};
const ChatBubbleLeftRightIcon = {
render() {
return h('svg', {
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
'stroke-width': '1.5',
stroke: 'currentColor',
class: 'w-6 h-6'
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
d: 'M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155'
})
]);
}
};
// Icon component mapping
const getIconComponent = (iconName: string) => {
switch (iconName) {
case 'document':
return DocumentIcon;
case 'code':
return CodeIcon;
case 'academic-cap':
return AcademicCapIcon;
case 'code-bracket':
return CodeBracketIcon;
case 'magnifying-glass':
return MagnifyingGlassIcon;
case 'wallet':
return WalletIcon;
case 'chat-bubble-left-right':
return ChatBubbleLeftRightIcon;
default:
return DocumentIcon;
}
};
</script>
<template>
<div class="py-12 px-6 md:px-12 lg:px-24">
<!-- Hero Section -->
<div class="text-center mb-12 animate__animated animate__fadeIn">
<h1 class="text-4xl md:text-5xl font-bold mb-4 text-text">{{ t('resources.hero.title') }}</h1>
<p class="text-xl text-text-secondary max-w-3xl mx-auto">{{ t('resources.hero.subtitle') }}</p>
</div>
<!-- Categories Filter -->
<div class="flex flex-wrap justify-center gap-4 mb-12 animate__animated animate__fadeInUp animate__delay-xs">
<button
v-for="category in categories"
:key="category.id"
@click="setActiveCategory(category.id)"
class="px-4 py-2 rounded-full transition-all duration-300 hover:scale-105"
:class="activeCategory === category.id
? 'bg-primary text-background font-medium shadow-lg'
: 'bg-background-light text-text-secondary hover:bg-background hover:text-text'"
>
{{ category.name }}
</button>
</div>
<!-- Resources Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div
v-for="resource in filteredResources"
:key="resource.id"
class="bg-background-light rounded-lg p-6 shadow-md transition-all duration-300 hover:shadow-xl hover:translate-y-[-4px] animate__animated animate__fadeIn"
>
<div class="flex items-start mb-4">
<div class="p-3 rounded-full bg-primary/10 text-primary mr-4">
<component :is="getIconComponent(resource.icon)" />
</div>
<div>
<h3 class="text-xl font-semibold text-text mb-2">{{ resource.title }}</h3>
<p class="text-text-secondary mb-4">{{ resource.description }}</p>
</div>
</div>
<a
:href="resource.link"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center text-primary hover:text-primary-light transition-colors"
>
{{ t('resources.explore') }}
<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="M14 5l7 7m0 0l-7 7m7-7H3" />
</svg>
</a>
</div>
</div>
<!-- Newsletter Section -->
<div class="mt-16 bg-background-dark rounded-xl p-8 md:p-12 animate__animated animate__fadeIn">
<div class="max-w-4xl mx-auto">
<h2 class="text-2xl md:text-3xl font-bold mb-4 text-text">{{ t('resources.newsletter.title') }}</h2>
<p class="text-text-secondary mb-6">{{ t('resources.newsletter.subtitle') }}</p>
<form class="flex flex-col md:flex-row gap-4">
<input
type="email"
:placeholder="t('resources.newsletter.placeholder')"
class="flex-grow px-4 py-3 rounded-lg bg-background border border-background-light focus:outline-none focus:ring-2 focus:ring-primary"
/>
<button
type="submit"
class="px-6 py-3 bg-primary text-background font-medium rounded-lg hover:bg-primary-light transition-colors duration-300"
>
{{ t('resources.newsletter.button') }}
</button>
</form>
</div>
</div>
</div>
</template>

Loading…
Cancel
Save