8.1 KiB
Order Status Tabs UI (订单状态标签页UI)
Feature
Redesigned the fulfillment status filter from a dropdown select to clickable tabs for better user experience and faster filtering.
Changes Made
File: admin/src/views/consumer/prescription/order_list.vue
1. Replaced Dropdown with Tab UI
Before:
<el-form-item class="w-[180px]" label="履约状态">
<el-select v-model="queryParams.fulfillment_status" placeholder="全部" clearable>
<el-option label="待双审通过" :value="1" />
<el-option label="履约中" :value="2" />
<el-option label="已发货" :value="5" />
<el-option label="已完成" :value="3" />
<el-option label="已取消" :value="4" />
</el-select>
</el-form-item>
After:
<!-- 状态标签页 -->
<el-card class="!border-none shadow-sm mb-4" shadow="never">
<div class="flex items-center gap-2 flex-wrap">
<div
v-for="tab in statusTabs"
:key="tab.value"
:class="[
'px-4 py-2 rounded-lg cursor-pointer transition-all duration-200 select-none',
queryParams.fulfillment_status === tab.value
? 'bg-primary text-white shadow-md'
: 'bg-gray-50 text-gray-600 hover:bg-gray-100'
]"
@click="handleStatusTabClick(tab.value)"
>
<div class="flex items-center gap-2">
<span class="font-medium">{{ tab.label }}</span>
<span v-if="tab.count !== undefined" :class="[
'text-xs px-1.5 py-0.5 rounded',
queryParams.fulfillment_status === tab.value
? 'bg-white/20'
: 'bg-gray-200'
]">
{{ tab.count }}
</span>
</div>
</div>
</div>
</el-card>
2. Added Status Tabs Configuration
// 状态标签页配置
const statusTabs = ref([
{ label: '全部', value: '' as number | '', count: undefined },
{ label: '待双审通过', value: 1, count: undefined },
{ label: '履约中', value: 2, count: undefined },
{ label: '已发货', value: 5, count: undefined },
{ label: '已完成', value: 3, count: undefined },
{ label: '已取消', value: 4, count: undefined }
])
3. Added Click Handler
// 处理状态标签点击
const handleStatusTabClick = (value: number | '') => {
queryParams.fulfillment_status = value
resetPage()
}
UI Design
Visual States
Active Tab:
- Primary color background (
bg-primary) - White text
- Shadow effect
- Badge with semi-transparent white background
Inactive Tab:
- Light gray background (
bg-gray-50) - Gray text
- Hover effect (lighter gray)
- Badge with gray background
Layout
- Horizontal flex layout with gap
- Wraps on smaller screens
- Smooth transitions (200ms)
- Rounded corners
- Consistent padding
Badge (Count Display)
- Small text size
- Rounded badge
- Shows count for each status (optional feature)
- Different styling for active/inactive states
User Experience Improvements
Before (Dropdown):
- User clicks dropdown
- Dropdown opens with options
- User scrolls to find status
- User clicks option
- Dropdown closes
- User clicks "查询" button
Total: 3-4 clicks + scrolling
After (Tabs):
- User clicks tab
- Filter applies immediately
Total: 1 click
Benefits:
- ✅ Faster filtering: One-click access to any status
- ✅ Visual feedback: Clear indication of current filter
- ✅ Better discoverability: All options visible at once
- ✅ No extra clicks: Auto-triggers search on click
- ✅ Modern UI: Follows common tab pattern
- ✅ Mobile friendly: Wraps on small screens
Features
1. Active State Indication
The currently selected tab is highlighted with primary color, making it immediately clear which filter is active.
2. Hover Effects
Inactive tabs show a subtle hover effect, indicating they are clickable.
3. Count Badges (Optional)
Each tab can display a count badge showing the number of orders in that status. Currently set to undefined but can be populated with actual counts.
4. Responsive Design
Tabs wrap to multiple lines on smaller screens using flex-wrap.
5. Smooth Transitions
All state changes have smooth 200ms transitions for a polished feel.
Implementation Details
Tab Configuration
{
label: string, // Display text
value: number | '', // Filter value ('' for "All")
count: number | undefined // Optional count badge
}
Click Handler Logic
const handleStatusTabClick = (value: number | '') => {
queryParams.fulfillment_status = value // Update filter
resetPage() // Trigger search
}
Styling Classes
bg-primary: Primary brand color (active state)bg-gray-50: Light gray (inactive state)hover:bg-gray-100: Hover effectshadow-md: Shadow for active tabtransition-all duration-200: Smooth transitionsselect-none: Prevent text selection on click
Future Enhancements
1. Add Count Badges
Fetch and display order counts for each status:
// After fetching data
const updateStatusCounts = (data: any) => {
statusTabs.value[0].count = data.total
statusTabs.value[1].count = data.pending
statusTabs.value[2].count = data.processing
// ... etc
}
2. Add Icons
Add status-specific icons for better visual recognition:
<svg class="w-4 h-4" v-if="tab.value === 1">
<!-- Clock icon for pending -->
</svg>
3. Add Keyboard Navigation
Support arrow keys for tab navigation:
const handleKeydown = (e: KeyboardEvent) => {
if (e.key === 'ArrowLeft') {
// Navigate to previous tab
} else if (e.key === 'ArrowRight') {
// Navigate to next tab
}
}
4. Add Loading State
Show loading indicator on active tab while fetching:
<el-icon v-if="pager.loading && queryParams.fulfillment_status === tab.value" class="is-loading">
<Loading />
</el-icon>
Testing Steps
1. Test Tab Switching
- Open order list page
- Click on different status tabs
- Verify:
- Active tab is highlighted
- Table updates with filtered results
- URL parameters update (if using router)
2. Test Visual States
- Hover over inactive tabs
- Verify hover effect appears
- Click a tab
- Verify active state styling applies
3. Test "全部" Tab
- Click "全部" tab
- Verify all orders are shown
- Verify no status filter is applied
4. Test Responsive Behavior
- Resize browser window to small width
- Verify tabs wrap to multiple lines
- Verify all tabs remain accessible
5. Test with Search
- Enter order number in search
- Click different status tabs
- Verify both filters work together
Accessibility
Current Implementation:
- ✅ Keyboard accessible (clickable divs)
- ✅ Visual feedback on hover
- ✅ Clear active state indication
- ✅ Sufficient color contrast
Recommended Improvements:
- Add
role="tab"andaria-selectedattributes - Add
tabindex="0"for keyboard navigation - Add keyboard event handlers (Enter/Space)
- Add
aria-labelfor screen readers
Example:
<div
role="tab"
:aria-selected="queryParams.fulfillment_status === tab.value"
:tabindex="0"
@keydown.enter="handleStatusTabClick(tab.value)"
@keydown.space.prevent="handleStatusTabClick(tab.value)"
>
Related Files
Frontend:
admin/src/views/consumer/prescription/order_list.vue- Added status tabs UI
- Added
statusTabsconfiguration - Added
handleStatusTabClickhandler - Removed dropdown select
Summary
✅ Replaced dropdown with clickable tabs
✅ One-click filtering (no need to click "查询")
✅ Visual active state indication
✅ Hover effects for better UX
✅ Responsive design with flex-wrap
✅ Smooth transitions
✅ Support for count badges (optional)
✅ Cleaner, more modern UI
The status filter is now much more intuitive and efficient, following modern UI patterns commonly seen in admin dashboards!