Files
xin-school-taro/src/pages/tasks/index.tsx
T
2026-07-06 11:32:58 +08:00

104 lines
3.2 KiB
TypeScript

import { useState, useMemo } from 'react'
import Taro from '@tarojs/taro'
import { View, ScrollView } from '@tarojs/components'
import { Search } from '@antmjs/vantui'
import TaskCard from '@/components/TaskCard'
import { tasks } from '@/mock/tasks'
import './index.less'
/** 筛选标签 */
const FILTER_TABS = [
{ title: '全部', value: 'all' as const },
{ title: '快递代取', value: 'express' as const },
{ title: '二手交易', value: 'secondhand' as const },
{ title: '求助', value: 'help' as const },
{ title: '活动', value: 'activity' as const },
{ title: '拼车', value: 'carpool' as const },
]
/** 任务类型 → emoji */
const TYPE_EMOJI: Record<string, string> = {
all: '📋',
express: '📦',
secondhand: '🛍️',
help: '🆘',
activity: '🎉',
carpool: '🚗',
}
export default function Tasks() {
const [activeFilter, setActiveFilter] = useState(0)
const [searchValue, setSearchValue] = useState('')
const filteredTasks = useMemo(() => {
const filterValue = FILTER_TABS[activeFilter]?.value || 'all'
let list = filterValue === 'all' ? tasks : tasks.filter((t) => t.type === filterValue)
if (searchValue.trim()) {
const kw = searchValue.trim().toLowerCase()
list = list.filter(
(t) =>
t.title.toLowerCase().includes(kw) ||
t.desc.toLowerCase().includes(kw) ||
t.location.toLowerCase().includes(kw),
)
}
return list
}, [activeFilter, searchValue])
const handleTaskClick = (id: string) => {
Taro.navigateTo({ url: `/pages/task-detail/index?id=${id}` })
}
return (
<View className='tasks-page'>
{/* 搜索栏 */}
<View className='tasks-search-bar'>
<Search
value={searchValue}
placeholder='搜索校园任务...'
shape='round'
onChange={(e) => setSearchValue(e.detail)}
onClear={() => setSearchValue('')}
/>
</View>
{/* 分类标签 */}
<View className='tasks-filter'>
<ScrollView scrollX enhanced showScrollbar={false} className='filter-scroll'>
<View className='filter-tabs'>
{FILTER_TABS.map((tab, idx) => (
<View
key={tab.value}
className={`filter-tab ${activeFilter === idx ? 'active' : ''}`}
onClick={() => setActiveFilter(idx)}
>
<View className='filter-emoji'>{TYPE_EMOJI[tab.value]}</View>
<View className='filter-label'>{tab.title}</View>
</View>
))}
</View>
</ScrollView>
</View>
{/* 任务列表 */}
<ScrollView className='tasks-scroll' scrollY enhanced showScrollbar={false}>
<View className='tasks-list'>
{filteredTasks.map((task) => (
<View
key={task.id}
className='task-card-wrap'
onClick={() => handleTaskClick(task.id)}
>
<TaskCard task={task} />
</View>
))}
{filteredTasks.length === 0 && (
<View className='empty-tip'>暂无相关任务</View>
)}
</View>
<View className='bottom-safe' />
</ScrollView>
</View>
)
}