110 lines
4.8 KiB
TypeScript
110 lines
4.8 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Search, Loader2 } from 'lucide-react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { Logo } from '../components/Logo';
|
|
import { StockItem } from '../types';
|
|
|
|
const POPULAR_STOCKS: StockItem[] = [
|
|
{ name: '贵州茅台', code: '600519.SH', change: 1.85, type: 'SH' },
|
|
];
|
|
|
|
export const SearchPage: React.FC = () => {
|
|
const navigate = useNavigate();
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [isSearching, setIsSearching] = useState(false);
|
|
|
|
const handleSearch = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (searchTerm.trim()) {
|
|
setIsSearching(true);
|
|
// Simulate loading
|
|
setTimeout(() => navigate('/dashboard'), 800);
|
|
}
|
|
};
|
|
|
|
const handleCardClick = () => {
|
|
navigate('/dashboard');
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-slate-50 flex flex-col">
|
|
{/* Header */}
|
|
<header className="h-16 bg-white border-b border-slate-200 px-6 flex items-center justify-between sticky top-0 z-10">
|
|
<Logo />
|
|
<div className="flex items-center gap-4">
|
|
<div className="w-8 h-8 rounded-full bg-blue-600 text-white flex items-center justify-center text-sm font-medium">U</div>
|
|
</div>
|
|
</header>
|
|
|
|
{/* Main Content */}
|
|
<main className="flex-1 max-w-6xl mx-auto w-full px-6 py-12 flex flex-col items-center">
|
|
|
|
{/* Search Section */}
|
|
<div className="w-full max-w-2xl mb-12 relative z-20">
|
|
<form onSubmit={handleSearch} className="relative group">
|
|
<div className="absolute inset-y-0 left-4 flex items-center pointer-events-none">
|
|
<Search className="text-slate-400" size={20} />
|
|
</div>
|
|
<input
|
|
type="text"
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
className="w-full pl-12 pr-4 py-4 bg-white border border-slate-200 rounded-2xl shadow-sm text-lg focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all placeholder:text-slate-400"
|
|
placeholder="搜索标的..."
|
|
/>
|
|
{searchTerm && (
|
|
<div className="absolute top-full left-0 right-0 mt-2 bg-white rounded-xl shadow-xl border border-slate-100 overflow-hidden animate-in fade-in slide-in-from-top-2">
|
|
<div
|
|
onClick={() => navigate('/dashboard')}
|
|
className="px-4 py-3 hover:bg-slate-50 cursor-pointer flex items-center gap-3 border-b border-slate-50 last:border-0"
|
|
>
|
|
<div className="w-10 h-10 rounded bg-slate-100 flex items-center justify-center text-xs font-bold text-slate-600">
|
|
SH
|
|
</div>
|
|
<div>
|
|
<p className="font-bold text-slate-800">贵州茅台</p>
|
|
<p className="text-xs text-slate-500">600519.SH · Stock</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</form>
|
|
</div>
|
|
|
|
{/* Grid */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 w-full">
|
|
{POPULAR_STOCKS.map((stock) => (
|
|
<div
|
|
key={stock.code}
|
|
onClick={handleCardClick}
|
|
className="bg-white p-6 rounded-2xl border border-slate-100 shadow-sm hover:shadow-md hover:border-blue-200 transition-all cursor-pointer group"
|
|
>
|
|
<div className="flex items-center justify-between mb-4">
|
|
<div className="flex items-center gap-2">
|
|
{/* Simple icon based on type */}
|
|
<div className="w-8 h-8 rounded-lg bg-slate-50 flex items-center justify-center text-slate-400 group-hover:text-blue-500 transition-colors">
|
|
<Search size={16} />
|
|
</div>
|
|
<span className="font-bold text-slate-700">{stock.name}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-slate-400 font-mono">{stock.code}</span>
|
|
<span className="bg-red-50 text-red-500 px-2 py-1 rounded text-xs font-bold font-mono">
|
|
+{stock.change.toFixed(2)}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
))}
|
|
|
|
<div className="bg-white/50 border-2 border-dashed border-slate-200 p-6 rounded-2xl flex items-center justify-center">
|
|
<div className="flex items-center gap-2 text-slate-400">
|
|
{isSearching ? <Loader2 className="animate-spin" size={20} /> : <span className="text-sm">More data loading...</span>}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}; |