216 lines
7.1 KiB
TypeScript
216 lines
7.1 KiB
TypeScript
import { View, Text, Image, Input, Button, Swiper, SwiperItem } from '@tarojs/components'
|
|
import Taro from '@tarojs/taro'
|
|
import { useState } from 'react'
|
|
import './index.scss'
|
|
import { CATEGORIES } from '../../utils/productConfig'
|
|
import { assetUrl } from '../../utils/asset'
|
|
import { useThemeContext } from '../../context/ThemeContext'
|
|
import { useSafeArea } from '../../hooks/useSafeArea'
|
|
import { useStatusBar } from '../../hooks/useStatusBar'
|
|
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
|
|
|
// 成品展示配图(从 img 里取对应实物图)
|
|
const SHOWCASE_LIST = [
|
|
{
|
|
title: '毕业纪念笔记本',
|
|
desc: '全班名字组成校徽',
|
|
priceText: '¥45 起',
|
|
categoryId: 'notebook-large',
|
|
image: assetUrl('/img/book_small/The1.jpg')
|
|
},
|
|
{
|
|
title: '铜质杯垫',
|
|
desc: '金属质感桌面艺术',
|
|
priceText: '¥25 起',
|
|
categoryId: 'coaster',
|
|
image: assetUrl('/img/cup/The1.jpg')
|
|
},
|
|
{
|
|
title: '竹制笔盒',
|
|
desc: '自然竹纹文房雅器',
|
|
priceText: '¥75 起',
|
|
categoryId: 'penbox',
|
|
image: assetUrl('/img/penbox/The1.jpg')
|
|
},
|
|
{
|
|
title: '书本型灯',
|
|
desc: '温暖光影点亮心意',
|
|
priceText: '¥45 起',
|
|
categoryId: 'booklamp',
|
|
image: assetUrl('/img/booklight/The1.jpg')
|
|
},
|
|
{
|
|
title: '情侣定制礼',
|
|
desc: '两个人的名字交织',
|
|
priceText: '¥45 起',
|
|
categoryId: 'notebook-large',
|
|
image: assetUrl('/img/book_big/The1.jpg')
|
|
},
|
|
{
|
|
title: '企业年会礼',
|
|
desc: '员工名字组成Logo',
|
|
priceText: '¥75 起',
|
|
categoryId: 'penbox',
|
|
image: assetUrl('/img/penbox/The2.jpg')
|
|
}
|
|
]
|
|
|
|
// 品类对应的实物照片映射(首页卡片顶部大图)
|
|
const PRODUCT_IMG_MAP: Record<string, string> = {
|
|
'notebook-small': assetUrl('/img/book_small/The1.jpg'),
|
|
'notebook-large': assetUrl('/img/book_big/The1.jpg'),
|
|
'coaster': assetUrl('/img/cup/The1.jpg'),
|
|
'penbox': assetUrl('/img/penbox/The1.jpg'),
|
|
'booklamp': assetUrl('/img/booklight/The1.jpg')
|
|
}
|
|
|
|
export default function Index() {
|
|
const { theme, resolvedTheme } = useThemeContext()
|
|
const safe = useSafeArea()
|
|
useStatusBar(resolvedTheme)
|
|
const [searchKey, setSearchKey] = useState('')
|
|
|
|
const navigateToProduct = (categoryId: string) => {
|
|
Taro.navigateTo({ url: `/pages/product/index?id=${categoryId}` })
|
|
}
|
|
|
|
const navigateFromShowcase = (item: { categoryId?: string; title: string }) => {
|
|
if (item.categoryId) {
|
|
navigateToProduct(item.categoryId)
|
|
return
|
|
}
|
|
Taro.showToast({
|
|
title: `“${item.title}”定制通道即将开放`,
|
|
icon: 'none'
|
|
})
|
|
}
|
|
|
|
const filteredCategories = searchKey.trim()
|
|
? CATEGORIES.filter(
|
|
(c) => c.name.includes(searchKey) || c.desc.includes(searchKey)
|
|
)
|
|
: CATEGORIES
|
|
|
|
const handleSearch = (e: any) => {
|
|
setSearchKey(e.detail.value)
|
|
}
|
|
|
|
return (
|
|
<View className={`theme-${resolvedTheme}`}>
|
|
<ThemedPageMeta />
|
|
<View className='index-page'>
|
|
|
|
{/* 页头 */}
|
|
<View className='home-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
|
<Text className='home-title'>智绘微刻</Text>
|
|
</View>
|
|
|
|
{/* 搜索 */}
|
|
<View className='searchbox'>
|
|
<Image className='search-icon-img' src={assetUrl('/icon/搜索.svg')} mode='aspectFit' />
|
|
<Input
|
|
className='search-input'
|
|
type='text'
|
|
placeholder='搜索定制品类:笔记本、杯垫、书灯...'
|
|
value={searchKey}
|
|
onInput={handleSearch}
|
|
confirmType='search'
|
|
/>
|
|
</View>
|
|
{searchKey.trim() && (
|
|
<View className='search-result-hint'>
|
|
<Text className='hint-text'>
|
|
{filteredCategories.length > 0
|
|
? `找到 ${filteredCategories.length} 个相关品类`
|
|
: '没有找到相关品类,试试看其他关键词'}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
|
|
{/* 定制成品展示 */}
|
|
<View className='showcase-section'>
|
|
<Text className='home-section-title'>定制成品展示</Text>
|
|
<Swiper
|
|
className='showcase-swiper'
|
|
circular
|
|
autoplay
|
|
interval={3000}
|
|
duration={500}
|
|
indicatorDots
|
|
>
|
|
{SHOWCASE_LIST.map((item, idx) => (
|
|
<SwiperItem key={idx} className='showcase-swiper-item'>
|
|
<View className='hero-block'>
|
|
<Image className='hero-media' src={item.image} mode='aspectFill' />
|
|
<View className='glass-overlay'>
|
|
<Text className='hero-title'>{item.title}</Text>
|
|
<Text className='hero-desc'>{item.desc}</Text>
|
|
</View>
|
|
</View>
|
|
</SwiperItem>
|
|
))}
|
|
</Swiper>
|
|
</View>
|
|
|
|
{/* 热门品类 */}
|
|
<View className='category-section'>
|
|
<Text className='home-section-title'>热门品类</Text>
|
|
<View className='home-grid'>
|
|
{filteredCategories.map((cat) => (
|
|
<View
|
|
key={cat.id}
|
|
className='media-card'
|
|
onTap={() => navigateToProduct(cat.id)}
|
|
>
|
|
<View className='media-card-image'>
|
|
<Image
|
|
className='media-card-img'
|
|
src={PRODUCT_IMG_MAP[cat.id] || assetUrl('/icon/四角星.svg')}
|
|
mode='aspectFill'
|
|
/>
|
|
</View>
|
|
<View className='media-card-body'>
|
|
<Text className='media-card-title'>{cat.name}</Text>
|
|
<Text className='media-card-desc'>{cat.desc}</Text>
|
|
<Text className='media-card-price'>¥{cat.price} 起</Text>
|
|
</View>
|
|
</View>
|
|
))}
|
|
</View>
|
|
{filteredCategories.length === 0 && (
|
|
<View className='empty-category'>
|
|
<Image className='empty-icon-img' src={assetUrl('/icon/搜索.svg')} mode='aspectFit' />
|
|
<Text className='empty-text'>未找到匹配的品类</Text>
|
|
<Text className='empty-sub'>尝试搜索“笔记本”、“杯垫”等</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
|
|
{/* 为你推荐 */}
|
|
<View className='recommend-section'>
|
|
<Text className='home-section-title'>为你推荐</Text>
|
|
<View className='home-grid'>
|
|
{SHOWCASE_LIST.slice(0, 4).map((item, idx) => (
|
|
<View
|
|
key={idx}
|
|
className='media-card'
|
|
onTap={() => navigateFromShowcase(item)}
|
|
>
|
|
<View className='media-card-image'>
|
|
<Image className='media-card-img' src={item.image} mode='aspectFill' />
|
|
</View>
|
|
<View className='media-card-body'>
|
|
<Text className='media-card-title'>{item.title}</Text>
|
|
<Text className='media-card-desc'>{item.desc}</Text>
|
|
<Text className='media-card-price'>{item.priceText}</Text>
|
|
</View>
|
|
</View>
|
|
))}
|
|
</View>
|
|
</View>
|
|
|
|
</View>
|
|
</View>
|
|
)
|
|
}
|