任务、消息
This commit is contained in:
+81
-13
@@ -1,29 +1,97 @@
|
||||
/* ========================================
|
||||
校园任务页面
|
||||
======================================== */
|
||||
|
||||
.tasks-page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.page-placeholder {
|
||||
/* 搜索栏 */
|
||||
.tasks-search-bar {
|
||||
padding: 20px 24px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 分类筛选 */
|
||||
.tasks-filter {
|
||||
background: #fff;
|
||||
padding-bottom: 16px;
|
||||
|
||||
.filter-scroll {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-tabs {
|
||||
display: flex;
|
||||
padding: 0 24px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.filter-tab {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 300px;
|
||||
padding: 16px 20px;
|
||||
border-radius: 16px;
|
||||
background: #f7f8fa;
|
||||
flex-shrink: 0;
|
||||
min-width: 120px;
|
||||
transition: all 0.2s;
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 96px;
|
||||
margin-bottom: 24px;
|
||||
&.active {
|
||||
background: #1989fa;
|
||||
box-shadow: 0 4px 16px rgba(25, 137, 250, 0.3);
|
||||
|
||||
.filter-emoji {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
.filter-emoji {
|
||||
font-size: 36px;
|
||||
font-weight: 500;
|
||||
color: #323233;
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 6px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.placeholder-desc {
|
||||
font-size: 28px;
|
||||
color: #969799;
|
||||
.filter-label {
|
||||
font-size: 24px;
|
||||
color: #646566;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 任务列表 */
|
||||
.tasks-scroll {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tasks-list {
|
||||
padding: 16px 24px;
|
||||
|
||||
.task-card-wrap {
|
||||
margin-bottom: 16px;
|
||||
transition: transform 0.2s;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
text-align: center;
|
||||
padding: 120px 0;
|
||||
font-size: 28px;
|
||||
color: #969799;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-safe {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,106 @@
|
||||
import { View, Text } from '@tarojs/components'
|
||||
import CustomTabBar from "@/custom-tab-bar"
|
||||
import { useState, useMemo } from 'react'
|
||||
import Taro from '@tarojs/taro'
|
||||
import { View, ScrollView } from '@tarojs/components'
|
||||
import { Search, Tabs, Tab } from '@antmjs/vantui'
|
||||
import TaskCard from '@/components/TaskCard'
|
||||
import CustomTabBar from '@/custom-tab-bar'
|
||||
import { tasks } from '@/mock/tasks'
|
||||
import type { TaskType } from '@/types/task'
|
||||
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.showToast({ title: '任务详情即将上线', icon: 'none' })
|
||||
}
|
||||
|
||||
return (
|
||||
<View className='tasks-page'>
|
||||
<View className='page-placeholder'>
|
||||
<Text className='placeholder-icon'>📋</Text>
|
||||
<Text className='placeholder-text'>校园任务</Text>
|
||||
<Text className='placeholder-desc'>即将上线,敬请期待</Text>
|
||||
{/* 搜索栏 */}
|
||||
<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>
|
||||
|
||||
<CustomTabBar activeKey='tasks' />
|
||||
</View>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user