feat: 新增可复用底部导航栏组件并重构页面使用
- 新增 `TabBar.vue` 组件,统一底部导航栏样式与交互逻辑 - 在 `components.d.ts` 中注册 `TabBar` 和 `NutButton` 组件 - 重构首页、入职页、签单页,移除重复的导航栏代码,统一使用 `TabBar` 组件 - 替换首页自定义按钮为 NutUI 的 `nut-button` 组件,保持原有视觉样式 - 更新 CHANGELOG.md 记录相关变更
Showing
6 changed files
with
123 additions
and
130 deletions
| ... | @@ -8,11 +8,13 @@ export {} | ... | @@ -8,11 +8,13 @@ export {} |
| 8 | declare module 'vue' { | 8 | declare module 'vue' { |
| 9 | export interface GlobalComponents { | 9 | export interface GlobalComponents { |
| 10 | IndexNav: typeof import('./src/components/indexNav.vue')['default'] | 10 | IndexNav: typeof import('./src/components/indexNav.vue')['default'] |
| 11 | + NutButton: typeof import('@nutui/nutui-taro')['Button'] | ||
| 11 | Picker: typeof import('./src/components/time-picker-data/picker.vue')['default'] | 12 | Picker: typeof import('./src/components/time-picker-data/picker.vue')['default'] |
| 12 | PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default'] | 13 | PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default'] |
| 13 | QrCode: typeof import('./src/components/qrCode.vue')['default'] | 14 | QrCode: typeof import('./src/components/qrCode.vue')['default'] |
| 14 | QrCodeSearch: typeof import('./src/components/qrCodeSearch.vue')['default'] | 15 | QrCodeSearch: typeof import('./src/components/qrCodeSearch.vue')['default'] |
| 15 | RouterLink: typeof import('vue-router')['RouterLink'] | 16 | RouterLink: typeof import('vue-router')['RouterLink'] |
| 16 | RouterView: typeof import('vue-router')['RouterView'] | 17 | RouterView: typeof import('vue-router')['RouterView'] |
| 18 | + TabBar: typeof import('./src/components/TabBar.vue')['default'] | ||
| 17 | } | 19 | } |
| 18 | } | 20 | } | ... | ... |
| ... | @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. | ... | @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. |
| 14 | - 注册新页面路由至 `src/app.config.js` | 14 | - 注册新页面路由至 `src/app.config.js` |
| 15 | - 新增 "签单相关" 页面 (`src/pages/signing`),复用 "入职相关" 页面布局 | 15 | - 新增 "签单相关" 页面 (`src/pages/signing`),复用 "入职相关" 页面布局 |
| 16 | - 为 "签单相关" 页面配置自定义导航栏与渐变色背景样式 | 16 | - 为 "签单相关" 页面配置自定义导航栏与渐变色背景样式 |
| 17 | +- 新增可复用的底部导航栏组件 (`src/components/TabBar.vue`),统一各页面的导航交互 | ||
| 17 | 18 | ||
| 18 | ### Changed | 19 | ### Changed |
| 19 | - 暂时禁用授权模式功能 (`ENABLE_AUTH_MODE = false`) | 20 | - 暂时禁用授权模式功能 (`ENABLE_AUTH_MODE = false`) |
| ... | @@ -35,6 +36,11 @@ All notable changes to this project will be documented in this file. | ... | @@ -35,6 +36,11 @@ All notable changes to this project will be documented in this file. |
| 35 | - 替换 "入职相关" 页面图标为 NutUI 标准图标库,提升加载性能与清晰度 | 36 | - 替换 "入职相关" 页面图标为 NutUI 标准图标库,提升加载性能与清晰度 |
| 36 | - 优化 "入职相关" 与 "签单相关" 页面的视觉体验,引入渐变色背景系统(Header 及各板块标题) | 37 | - 优化 "入职相关" 与 "签单相关" 页面的视觉体验,引入渐变色背景系统(Header 及各板块标题) |
| 37 | - 修复 "入职相关" 页面首个板块与导航栏重叠的布局问题 | 38 | - 修复 "入职相关" 页面首个板块与导航栏重叠的布局问题 |
| 39 | +- 优化底部导航栏样式,移除 Home Indicator (底部灰条) 以符合设计稿 | ||
| 40 | +- 重构 TabBar 布局,移除绝对定位与固定高度,改用 Flexbox + Padding 实现更自然的垂直居中与适配 | ||
| 41 | +- 增加底部导航栏 `active` 属性,支持不同页面高亮状态切换 | ||
| 42 | +- 重构首页、入职页、签单页,统一使用 `TabBar` 组件 | ||
| 43 | +- 替换首页 (`src/pages/index`) 自定义按钮为 NutUI `nut-button` 组件,并保留原有视觉样式 | ||
| 38 | 44 | ||
| 39 | ### Removed | 45 | ### Removed |
| 40 | - 删除项目所有离线功能相关逻辑 | 46 | - 删除项目所有离线功能相关逻辑 | ... | ... |
src/components/TabBar.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2026-01-29 20:33:23 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2026-01-29 20:42:52 | ||
| 5 | + * @FilePath: /manulife-weapp/src/components/TabBar.vue | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <view class="fixed bottom-0 left-0 w-full bg-white shadow-[0_-4rpx_16rpx_rgba(0,0,0,0.05)] pb-[env(safe-area-inset-bottom)] z-50"> | ||
| 10 | + <view class="flex items-center justify-around py-[32rpx]"> | ||
| 11 | + <view | ||
| 12 | + class="flex-1 flex flex-col items-center justify-center" | ||
| 13 | + v-for="(item, index) in tabs" | ||
| 14 | + :key="index" | ||
| 15 | + @tap="handleTabClick(item)" | ||
| 16 | + > | ||
| 17 | + <component | ||
| 18 | + :is="item.icon" | ||
| 19 | + :class="[current === item.key ? 'text-blue-600' : 'text-gray-400']" | ||
| 20 | + size="24" | ||
| 21 | + /> | ||
| 22 | + <text | ||
| 23 | + class="text-[20rpx] mt-[8rpx]" | ||
| 24 | + :class="[current === item.key ? 'text-blue-600' : 'text-gray-400']" | ||
| 25 | + >{{ item.label }}</text> | ||
| 26 | + </view> | ||
| 27 | + </view> | ||
| 28 | + </view> | ||
| 29 | +</template> | ||
| 30 | + | ||
| 31 | +<script setup> | ||
| 32 | +import { ref } from 'vue' | ||
| 33 | +import { Home, Service, My } from '@nutui/icons-vue-taro' | ||
| 34 | +import { useGo } from '@/hooks/useGo' | ||
| 35 | +import Taro from '@tarojs/taro' | ||
| 36 | + | ||
| 37 | +const props = defineProps({ | ||
| 38 | + current: { | ||
| 39 | + type: String, | ||
| 40 | + default: 'home' | ||
| 41 | + } | ||
| 42 | +}) | ||
| 43 | + | ||
| 44 | +const go = useGo() | ||
| 45 | + | ||
| 46 | +const tabs = ref([ | ||
| 47 | + { | ||
| 48 | + key: 'home', | ||
| 49 | + label: '首页', | ||
| 50 | + icon: Home, | ||
| 51 | + path: '/pages/index/index' | ||
| 52 | + }, | ||
| 53 | + { | ||
| 54 | + key: 'ai', | ||
| 55 | + label: 'AI答疑', | ||
| 56 | + icon: Service, | ||
| 57 | + path: '/pages/ai/index' // Placeholder path | ||
| 58 | + }, | ||
| 59 | + { | ||
| 60 | + key: 'me', | ||
| 61 | + label: '我的', | ||
| 62 | + icon: My, | ||
| 63 | + path: '/pages/me/index' // Placeholder path | ||
| 64 | + } | ||
| 65 | +]) | ||
| 66 | + | ||
| 67 | +const handleTabClick = (item) => { | ||
| 68 | + if (item.key === props.current) return | ||
| 69 | + | ||
| 70 | + if (item.key === 'home') { | ||
| 71 | + go(item.path) | ||
| 72 | + } else if (item.key === 'me') { | ||
| 73 | + // Check if 'me' page exists, otherwise show toast or just go | ||
| 74 | + // For now, assuming me page might not exist or we just navigate | ||
| 75 | + // go(item.path) | ||
| 76 | + // Based on existing logic in index.vue: | ||
| 77 | + // Taro.redirectTo({ url: '/pages/me/index' }); | ||
| 78 | + // But wait, standard tab bar usually uses switchTab or redirectTo. | ||
| 79 | + // Since this is a custom tab bar, we use useGo (which uses navigateTo usually). | ||
| 80 | + // Ideally for tab switching we might want reLaunch or redirectTo to avoid stack buildup. | ||
| 81 | + // However, useGo defaults to navigateTo. | ||
| 82 | + // Let's use reLaunch to simulate tab switching behavior if it's a "tab bar" | ||
| 83 | + | ||
| 84 | + // Actually, let's look at index.vue logic: | ||
| 85 | + // if (item.key === 'me') Taro.redirectTo({ url: '/pages/me/index' }); | ||
| 86 | + // if (item.key === 'ai') Taro.showToast({ title: '功能开发中', icon: 'none' }); | ||
| 87 | + | ||
| 88 | + // I will replicate this logic for now but make it more generic if possible. | ||
| 89 | + // Since 'me' and 'ai' might not be fully implemented, I will stick to what I know. | ||
| 90 | + // But 'onboarding' and 'signing' pages use this tab bar too. | ||
| 91 | + | ||
| 92 | + // If we are on 'onboarding' (which is seemingly a sub-page but has a tab bar), | ||
| 93 | + // clicking 'Home' should probably go back to Home. | ||
| 94 | + | ||
| 95 | + Taro.reLaunch({ url: item.path }) | ||
| 96 | + } else if (item.key === 'ai') { | ||
| 97 | + Taro.showToast({ | ||
| 98 | + title: '功能开发中', | ||
| 99 | + icon: 'none' | ||
| 100 | + }) | ||
| 101 | + } | ||
| 102 | +} | ||
| 103 | +</script> |
| ... | @@ -59,12 +59,8 @@ | ... | @@ -59,12 +59,8 @@ |
| 59 | </view> | 59 | </view> |
| 60 | </view> | 60 | </view> |
| 61 | <view class="flex justify-between gap-[24rpx]"> | 61 | <view class="flex justify-between gap-[24rpx]"> |
| 62 | - <view class="flex-1 h-[64rpx] flex items-center justify-center border border-blue-600 rounded-[16rpx] bg-white"> | 62 | + <nut-button plain color="#2563EB" class="flex-1 !h-[64rpx] !rounded-[16rpx] !text-[26rpx] !m-0 !border-blue-600">产品资料</nut-button> |
| 63 | - <text class="text-blue-600 text-[26rpx]">产品资料</text> | 63 | + <nut-button color="#2563EB" class="flex-1 !h-[64rpx] !rounded-[16rpx] !text-[26rpx] !m-0">计划书</nut-button> |
| 64 | - </view> | ||
| 65 | - <view class="flex-1 h-[64rpx] flex items-center justify-center bg-blue-600 rounded-[16rpx]"> | ||
| 66 | - <text class="text-white text-[26rpx]">计划书</text> | ||
| 67 | - </view> | ||
| 68 | </view> | 64 | </view> |
| 69 | </view> | 65 | </view> |
| 70 | 66 | ||
| ... | @@ -83,12 +79,8 @@ | ... | @@ -83,12 +79,8 @@ |
| 83 | </view> | 79 | </view> |
| 84 | </view> | 80 | </view> |
| 85 | <view class="flex justify-between gap-[24rpx]"> | 81 | <view class="flex justify-between gap-[24rpx]"> |
| 86 | - <view class="flex-1 h-[64rpx] flex items-center justify-center border border-blue-600 rounded-[16rpx] bg-white"> | 82 | + <nut-button plain color="#2563EB" class="flex-1 !h-[64rpx] !rounded-[16rpx] !text-[26rpx] !m-0 !border-blue-600">产品资料</nut-button> |
| 87 | - <text class="text-blue-600 text-[26rpx]">产品资料</text> | 83 | + <nut-button color="#2563EB" class="flex-1 !h-[64rpx] !rounded-[16rpx] !text-[26rpx] !m-0">计划书</nut-button> |
| 88 | - </view> | ||
| 89 | - <view class="flex-1 h-[64rpx] flex items-center justify-center bg-blue-600 rounded-[16rpx]"> | ||
| 90 | - <text class="text-white text-[26rpx]">计划书</text> | ||
| 91 | - </view> | ||
| 92 | </view> | 84 | </view> |
| 93 | </view> | 85 | </view> |
| 94 | </view> | 86 | </view> |
| ... | @@ -145,27 +137,7 @@ | ... | @@ -145,27 +137,7 @@ |
| 145 | </view> | 137 | </view> |
| 146 | 138 | ||
| 147 | <!-- Bottom Tab Bar --> | 139 | <!-- Bottom Tab Bar --> |
| 148 | - <view class="fixed bottom-0 left-0 w-full bg-white shadow-[0_-4rpx_16rpx_rgba(0,0,0,0.05)] pb-safe z-50"> | 140 | + <TabBar current="home" /> |
| 149 | - <view class="flex h-[110rpx] items-center"> | ||
| 150 | - <view | ||
| 151 | - class="flex-1 flex flex-col items-center justify-center" | ||
| 152 | - v-for="(item, index) in loopData1" | ||
| 153 | - :key="index" | ||
| 154 | - @tap="handleTabClick(item)" | ||
| 155 | - > | ||
| 156 | - <component | ||
| 157 | - :is="item.icon" | ||
| 158 | - :class="[item.key === 'home' ? 'text-blue-600' : 'text-gray-400']" | ||
| 159 | - size="24" | ||
| 160 | - /> | ||
| 161 | - <text | ||
| 162 | - class="text-[20rpx] mt-[8rpx]" | ||
| 163 | - :class="[item.key === 'home' ? 'text-blue-600' : 'text-gray-400']" | ||
| 164 | - >{{ item.lanhutext0 }}</text> | ||
| 165 | - </view> | ||
| 166 | - </view> | ||
| 167 | - <view class="w-[268rpx] h-[10rpx] mx-auto bg-gray-200 rounded-full mb-[10rpx]" /> | ||
| 168 | - </view> | ||
| 169 | </view> | 141 | </view> |
| 170 | </template> | 142 | </template> |
| 171 | 143 | ||
| ... | @@ -173,6 +145,7 @@ | ... | @@ -173,6 +145,7 @@ |
| 173 | import { ref } from 'vue'; | 145 | import { ref } from 'vue'; |
| 174 | import Taro, { useShareAppMessage } from '@tarojs/taro'; | 146 | import Taro, { useShareAppMessage } from '@tarojs/taro'; |
| 175 | import { useGo } from '@/hooks/useGo'; | 147 | import { useGo } from '@/hooks/useGo'; |
| 148 | +import TabBar from '@/components/TabBar.vue'; | ||
| 176 | import { | 149 | import { |
| 177 | Search, | 150 | Search, |
| 178 | RectRight, | 151 | RectRight, |
| ... | @@ -213,40 +186,9 @@ const loopData0 = ref([ | ... | @@ -213,40 +186,9 @@ const loopData0 = ref([ |
| 213 | }, | 186 | }, |
| 214 | ]); | 187 | ]); |
| 215 | 188 | ||
| 216 | -const loopData1 = ref([ | ||
| 217 | - { | ||
| 218 | - icon: Home, | ||
| 219 | - lanhutext0: '首页', | ||
| 220 | - key: 'home' | ||
| 221 | - }, | ||
| 222 | - { | ||
| 223 | - icon: Service, | ||
| 224 | - lanhutext0: 'AI答疑', | ||
| 225 | - key: 'ai' | ||
| 226 | - }, | ||
| 227 | - { | ||
| 228 | - icon: My, | ||
| 229 | - lanhutext0: '我的', | ||
| 230 | - key: 'me' | ||
| 231 | - }, | ||
| 232 | -]); | ||
| 233 | - | ||
| 234 | // Navigation | 189 | // Navigation |
| 235 | const go = useGo(); | 190 | const go = useGo(); |
| 236 | 191 | ||
| 237 | -const handleTabClick = (item) => { | ||
| 238 | - if (item.key === 'me') { | ||
| 239 | - Taro.redirectTo({ | ||
| 240 | - url: '/pages/me/index' | ||
| 241 | - }); | ||
| 242 | - } else if (item.key === 'ai') { | ||
| 243 | - Taro.showToast({ | ||
| 244 | - title: '功能开发中', | ||
| 245 | - icon: 'none' | ||
| 246 | - }); | ||
| 247 | - } | ||
| 248 | -}; | ||
| 249 | - | ||
| 250 | useShareAppMessage(() => { | 192 | useShareAppMessage(() => { |
| 251 | return { | 193 | return { |
| 252 | title: '臻奇智荟圈', | 194 | title: '臻奇智荟圈', | ... | ... |
| ... | @@ -36,28 +36,14 @@ | ... | @@ -36,28 +36,14 @@ |
| 36 | </div> | 36 | </div> |
| 37 | 37 | ||
| 38 | <!-- Tab Bar --> | 38 | <!-- Tab Bar --> |
| 39 | - <div class="fixed bottom-0 left-0 w-full bg-white border-t border-gray-100 pb-[env(safe-area-inset-bottom)] z-50"> | 39 | + <TabBar current="me" /> |
| 40 | - <div class="flex justify-around items-center h-[110rpx]"> | ||
| 41 | - <div class="flex flex-col items-center justify-center w-1/3" @tap="switchTab('home')"> | ||
| 42 | - <Home class="text-gray-400" size="24" /> | ||
| 43 | - <span class="text-[#9ca3af] text-[24rpx] mt-[8rpx]">首页</span> | ||
| 44 | - </div> | ||
| 45 | - <div class="flex flex-col items-center justify-center w-1/3" @tap="switchTab('ai')"> | ||
| 46 | - <Service class="text-gray-400" size="24" /> | ||
| 47 | - <span class="text-[#9ca3af] text-[24rpx] mt-[8rpx]">AI答疑</span> | ||
| 48 | - </div> | ||
| 49 | - <div class="flex flex-col items-center justify-center w-1/3"> | ||
| 50 | - <My class="text-[#007aff]" size="24" /> | ||
| 51 | - <span class="text-[#007aff] text-[24rpx] mt-[8rpx]">我的</span> | ||
| 52 | - </div> | ||
| 53 | - </div> | ||
| 54 | - </div> | ||
| 55 | </div> | 40 | </div> |
| 56 | </template> | 41 | </template> |
| 57 | 42 | ||
| 58 | <script setup> | 43 | <script setup> |
| 59 | import { ref } from 'vue' | 44 | import { ref } from 'vue' |
| 60 | import { useGo } from '@/hooks/useGo' | 45 | import { useGo } from '@/hooks/useGo' |
| 46 | +import TabBar from '@/components/TabBar.vue' | ||
| 61 | import { | 47 | import { |
| 62 | Edit, | 48 | Edit, |
| 63 | Find, | 49 | Find, |
| ... | @@ -68,10 +54,7 @@ import { | ... | @@ -68,10 +54,7 @@ import { |
| 68 | Star, | 54 | Star, |
| 69 | Top, | 55 | Top, |
| 70 | PlayCircleFill, | 56 | PlayCircleFill, |
| 71 | - RectRight, | 57 | + RectRight |
| 72 | - Home, | ||
| 73 | - Service, | ||
| 74 | - My | ||
| 75 | } from '@nutui/icons-vue-taro' | 58 | } from '@nutui/icons-vue-taro' |
| 76 | 59 | ||
| 77 | const go = useGo() | 60 | const go = useGo() |
| ... | @@ -150,19 +133,6 @@ const handleItemClick = (item) => { | ... | @@ -150,19 +133,6 @@ const handleItemClick = (item) => { |
| 150 | console.log('Clicked:', item.title) | 133 | console.log('Clicked:', item.title) |
| 151 | // TODO: Navigate to respective page | 134 | // TODO: Navigate to respective page |
| 152 | } | 135 | } |
| 153 | - | ||
| 154 | -/** | ||
| 155 | - * Switch tab | ||
| 156 | - * @param {string} tab - Tab key | ||
| 157 | - */ | ||
| 158 | -const switchTab = (tab) => { | ||
| 159 | - if (tab === 'home') { | ||
| 160 | - go('/pages/index/index') | ||
| 161 | - } else if (tab === 'ai') { | ||
| 162 | - // go('/pages/ai/index') // Assuming there is an AI page | ||
| 163 | - console.log('Switch to AI tab') | ||
| 164 | - } | ||
| 165 | -} | ||
| 166 | </script> | 136 | </script> |
| 167 | 137 | ||
| 168 | <script> | 138 | <script> | ... | ... |
| ... | @@ -36,28 +36,14 @@ | ... | @@ -36,28 +36,14 @@ |
| 36 | </div> | 36 | </div> |
| 37 | 37 | ||
| 38 | <!-- Tab Bar --> | 38 | <!-- Tab Bar --> |
| 39 | - <div class="fixed bottom-0 left-0 w-full bg-white border-t border-gray-100 pb-[env(safe-area-inset-bottom)] z-50"> | 39 | + <TabBar current="me" /> |
| 40 | - <div class="flex justify-around items-center h-[110rpx]"> | ||
| 41 | - <div class="flex flex-col items-center justify-center w-1/3" @tap="switchTab('home')"> | ||
| 42 | - <Home class="text-gray-400" size="24" /> | ||
| 43 | - <span class="text-[#9ca3af] text-[24rpx] mt-[8rpx]">首页</span> | ||
| 44 | - </div> | ||
| 45 | - <div class="flex flex-col items-center justify-center w-1/3" @tap="switchTab('ai')"> | ||
| 46 | - <Service class="text-gray-400" size="24" /> | ||
| 47 | - <span class="text-[#9ca3af] text-[24rpx] mt-[8rpx]">AI答疑</span> | ||
| 48 | - </div> | ||
| 49 | - <div class="flex flex-col items-center justify-center w-1/3"> | ||
| 50 | - <My class="text-[#007aff]" size="24" /> | ||
| 51 | - <span class="text-[#007aff] text-[24rpx] mt-[8rpx]">我的</span> | ||
| 52 | - </div> | ||
| 53 | - </div> | ||
| 54 | - </div> | ||
| 55 | </div> | 40 | </div> |
| 56 | </template> | 41 | </template> |
| 57 | 42 | ||
| 58 | <script setup> | 43 | <script setup> |
| 59 | import { ref } from 'vue' | 44 | import { ref } from 'vue' |
| 60 | import { useGo } from '@/hooks/useGo' | 45 | import { useGo } from '@/hooks/useGo' |
| 46 | +import TabBar from '@/components/TabBar.vue' | ||
| 61 | import { | 47 | import { |
| 62 | Shop, | 48 | Shop, |
| 63 | Category, | 49 | Category, |
| ... | @@ -70,10 +56,7 @@ import { | ... | @@ -70,10 +56,7 @@ import { |
| 70 | Clock, | 56 | Clock, |
| 71 | Refresh, | 57 | Refresh, |
| 72 | Location, | 58 | Location, |
| 73 | - RectRight, | 59 | + RectRight |
| 74 | - Home, | ||
| 75 | - Service, | ||
| 76 | - My | ||
| 77 | } from '@nutui/icons-vue-taro' | 60 | } from '@nutui/icons-vue-taro' |
| 78 | 61 | ||
| 79 | const go = useGo() | 62 | const go = useGo() |
| ... | @@ -174,19 +157,6 @@ const handleItemClick = (item) => { | ... | @@ -174,19 +157,6 @@ const handleItemClick = (item) => { |
| 174 | console.log('Clicked:', item.title) | 157 | console.log('Clicked:', item.title) |
| 175 | // TODO: Navigate to respective page | 158 | // TODO: Navigate to respective page |
| 176 | } | 159 | } |
| 177 | - | ||
| 178 | -/** | ||
| 179 | - * Switch tab | ||
| 180 | - * @param {string} tab - Tab key | ||
| 181 | - */ | ||
| 182 | -const switchTab = (tab) => { | ||
| 183 | - if (tab === 'home') { | ||
| 184 | - go('/pages/index/index') | ||
| 185 | - } else if (tab === 'ai') { | ||
| 186 | - // go('/pages/ai/index') // Assuming there is an AI page | ||
| 187 | - console.log('Switch to AI tab') | ||
| 188 | - } | ||
| 189 | -} | ||
| 190 | </script> | 160 | </script> |
| 191 | 161 | ||
| 192 | <script> | 162 | <script> | ... | ... |
-
Please register or login to post a comment