hookehuyr

refactor(components): 替换Tabs组件为内联实现

在ActivityDetail.vue和UserProfile.vue中,将Tabs组件替换为内联实现,以提高代码的可读性和维护性。同时修复了路径中的空格问题,并调整了路由参数的命名。
......@@ -10,7 +10,6 @@
"preview": "vite preview"
},
"dependencies": {
"@vitejs/plugin-vue-jsx": "4.1.2",
"axios": "^1.8.4",
"pinia": "^2.1.7",
"vue": "^3.4.21",
......@@ -18,6 +17,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "4.1.2",
"@vue/compiler-sfc": "^3.4.21",
"autoprefixer": "^10.4.20",
"eslint": "^9.9.0",
......
......@@ -8,9 +8,6 @@ importers:
.:
dependencies:
'@vitejs/plugin-vue-jsx':
specifier: 4.1.2
version: 4.1.2(vite@5.4.18)(vue@3.5.13)
axios:
specifier: ^1.8.4
version: 1.8.4
......@@ -27,6 +24,9 @@ importers:
'@vitejs/plugin-vue':
specifier: ^5.0.4
version: 5.2.3(vite@5.4.18)(vue@3.5.13)
'@vitejs/plugin-vue-jsx':
specifier: 4.1.2
version: 4.1.2(vite@5.4.18)(vue@3.5.13)
'@vue/compiler-sfc':
specifier: ^3.4.21
version: 3.5.13
......
......@@ -16,7 +16,7 @@
<!-- Tab content -->
<div class="pt-4">
<component :is="tabs[currentTab]?.content" />
<component :is="tabs[currentTab]?.component" />
</div>
</div>
</template>
......
/*
* @Date: 2025-04-17 14:26:17
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-04-21 13:26:32
* @FilePath: /mlaj-reading-club/src/main.js
* @Description: 文件描述
*/
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { createRouter, createWebHistory } from 'vue-router'
......@@ -16,7 +23,7 @@ const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('./pages/HomePage.vue') },
{ path: '/activity/:activityId', component: () => import('./pages/ActivityDetail.vue') },
{ path: '/activity/:id', component: () => import('./pages/ActivityDetail.vue') },
{ path: '/create-activity', component: () => import('./pages/CreateActivity.vue') },
{ path: '/profile', component: () => import('./pages/UserProfile.vue') },
{ path: '/registration/:activityId', component: () => import('./pages/Registration.vue') },
......
......@@ -75,7 +75,64 @@
</div>
<!-- Activity Tabs -->
<Tabs :tabs="tabs" />
<div>
<!-- Tab headers -->
<div class="flex border-b border-gray-200">
<button v-for="(tab, index) in tabs" :key="index"
class="text-base py-2 px-4 font-medium transition-all duration-200 focus:outline-none border-b-2"
:class="currentTab === index
? 'border-green-500 text-green-600'
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'"
@click="currentTab = index" role="tab" :aria-selected="currentTab === index">
{{ tab.label }}
</button>
</div>
<!-- Tab content -->
<div class="pt-4">
<div v-if="tabs[currentTab].label === '活动详情'">
<div class="space-y-4">
<div v-for="(paragraph, idx) in activity.description.split('\n')" :key="idx"
class="mb-4">
{{ paragraph }}
</div>
</div>
</div>
<div v-if="tabs[currentTab].label === '参与须知'">
<div class="space-y-4">
<h3 class="font-medium text-lg">参与须知</h3>
<ul class="list-disc pl-5 space-y-2">
<li>请准时到达活动地点或登录线上会议</li>
<li>请提前阅读相关书籍或材料</li>
<li>活动开始后,请将手机调至静音模式</li>
<li>尊重他人发言,不打断他人</li>
<li>可携带笔记本进行记录</li>
<li>如需取消参与,请提前24小时通知主办方</li>
</ul>
</div>
</div>
<div v-if="tabs[currentTab].label === '常见问题'">
<div class="space-y-6">
<div>
<h4 class="font-medium text-gray-900">如何取消报名?</h4>
<p class="mt-2 text-gray-600">
您可以在"我的活动"页面找到已报名的活动,点击"取消报名"按钮即可。请注意,活动开始前24小时内取消将无法获得退款。</p>
</div>
<div>
<h4 class="font-medium text-gray-900">活动材料如何获取?</h4>
<p class="mt-2 text-gray-600">报名成功后,您将在"我的活动"页面看到活动详情,相关材料可在页面底部下载或通过邮件接收。
</p>
</div>
<div>
<h4 class="font-medium text-gray-900">线上活动如何参加?</h4>
<p class="mt-2 text-gray-600">
线上活动将在活动开始前30分钟发送会议链接到您的邮箱和手机短信,您也可以在"我的活动"页面找到入口链接。</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Sidebar -->
......@@ -226,13 +283,17 @@
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { ref, computed, onMounted, h, defineComponent } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAppStore } from '../stores/app'
import Button from '../components/shared/Button.vue'
import Modal from '../components/shared/Modal.vue'
import Tabs from '../components/shared/Tabs.vue'
import ActivityCard from '../components/shared/ActivityCard.vue'
import activitiesData from '../data/activities.json'
import registrationsData from '../data/registrations.json'
const activities = ref(activitiesData.activities)
const registrations = ref(registrationsData.registrations)
const route = useRoute()
const router = useRouter()
......@@ -246,6 +307,7 @@ const showRegisterModal = ref(false)
const similarActivities = ref([])
const hasRegistered = ref(false)
const registrationStatus = ref(null)
const currentTab = ref(0)
// Computed
const activityStatus = computed(() => {
......@@ -305,44 +367,13 @@ const registrationStatusBadge = computed(() => {
const tabs = computed(() => [
{
label: '活动详情',
content: activity.value?.description.split('\n').map((paragraph, idx) => (
`<p key="${idx}" class="mb-4">${paragraph}</p>`
)).join('')
},
{
label: '参与须知',
content: `
<h3 class="font-medium text-lg mb-4">参与须知</h3>
<ul class="list-disc pl-5 space-y-2">
<li>请准时到达活动地点或登录线上会议</li>
<li>请提前阅读相关书籍或材料</li>
<li>活动开始后,请将手机调至静音模式</li>
<li>尊重他人发言,不打断他人</li>
<li>可携带笔记本进行记录</li>
<li>如需取消参与,请提前24小时通知主办方</li>
</ul>
`
},
{
label: '常见问题',
content: `
<div className="py-4">
<div className="space-y-6">
<div>
<h4 className="font-medium text-gray-900">如何取消报名?</h4>
<p className="mt-2 text-gray-600">您可以在"我的活动"页面找到已报名的活动,点击"取消报名"按钮即可。请注意,活动开始前24小时内取消将无法获得退款。</p>
</div>
<div>
<h4 className="font-medium text-gray-900">活动材料如何获取?</h4>
<p className="mt-2 text-gray-600">报名成功后,您将在"我的活动"页面看到活动详情,相关材料可在页面底部下载或通过邮件接收。</p>
</div>
<div>
<h4 className="font-medium text-gray-900">线上活动如何参加?</h4>
<p className="mt-2 text-gray-600">线上活动将在活动开始前30分钟发送会议链接到您的邮箱和手机短信,您也可以在"我的活动"页面找到入口链接。</p>
</div>
</div>
</div>
`}
}
])
// Functions
......@@ -351,7 +382,7 @@ const goBack = () => {
}
const getActivityImage = (activityId) => {
return `/ assets / images / activities / ${activityId}.jpg`
return `/assets/images/activities/${activityId}.jpg`
}
const formatDate = (dateString) => {
......
This diff is collapsed. Click to expand it.