diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 4ffdfe2..aaaeec7 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -13,6 +13,7 @@ const Icon = ({ name, size = 16 }) => { edit: , trash: , x: , + settings: , } return icons[name] || icons.globe } @@ -24,7 +25,11 @@ function App() { const [searchQuery, setSearchQuery] = useState('') const [modal, setModal] = useState({ show: false, type: 'website', data: null }) const [loading, setLoading] = useState(true) - const [form, setForm] = useState({ name: '', url: '', icon: '', description: '', category_id: '', is_favorite: false, color: '#667eea', icon_name: 'folder' }) + const [showCategoryManager, setShowCategoryManager] = useState(false) + const [form, setForm] = useState({ + name: '', url: '', icon: '', description: '', category_id: '', is_favorite: false, + color: '#667eea', icon_name: 'folder', sort_order: 0 + }) useEffect(() => { loadData() }, []) @@ -32,8 +37,8 @@ function App() { setLoading(true) try { const [c, w] = await Promise.all([categoryApi.getAll(), websiteApi.getAll()]) - setCategories(c.data) - setWebsites(w.data) + setCategories(c.data || []) + setWebsites(w.data || []) } catch (e) { console.error(e) } setLoading(false) } @@ -41,7 +46,10 @@ function App() { // 过滤网站 const filteredWebsites = websites.filter(site => { const matchCat = selectedCategory === null || site.category_id === selectedCategory - const matchSearch = !searchQuery || site.name.includes(searchQuery) || (site.description && site.description.includes(searchQuery)) + const query = searchQuery.toLowerCase().trim() + const matchSearch = !query || + (site.name && site.name.toLowerCase().includes(query)) || + (site.description && site.description.toLowerCase().includes(query)) return matchCat && matchSearch }) @@ -55,9 +63,14 @@ function App() { // 打开弹窗 const openModal = (type, data = null) => { if (type === 'website') { - setForm(data ? { ...data, category_id: data.category_id || '', is_favorite: !!data.is_favorite } : { name: '', url: '', icon: '', description: '', category_id: '', is_favorite: false }) + setForm(data ? { ...data, category_id: data.category_id || '', is_favorite: !!data.is_favorite } : { name: '', url: '', icon: '', description: '', category_id: '', is_favorite: false, color: '#667eea', icon_name: 'folder', sort_order: 0 }) } else { - setForm(data ? { name: data.name, icon_name: data.icon || 'folder', color: data.color || '#667eea' } : { name: '', icon_name: 'folder', color: '#667eea' }) + setForm(data ? { + name: data.name, + icon_name: data.icon || 'folder', + color: data.color || '#667eea', + sort_order: data.sort_order || 0 + } : { name: '', icon_name: 'folder', color: '#667eea', sort_order: 0 }) } setModal({ show: true, type, data }) } @@ -71,7 +84,12 @@ function App() { const payload = { ...form, category_id: form.category_id || null } modal.data ? await websiteApi.update(modal.data.id, payload) : await websiteApi.create(payload) } else { - const payload = { name: form.name, icon: form.icon_name, color: form.color } + const payload = { + name: form.name, + icon: form.icon_name, + color: form.color, + sort_order: parseInt(form.sort_order) || 0 + } modal.data ? await categoryApi.update(modal.data.id, payload) : await categoryApi.create(payload) } closeModal() @@ -135,7 +153,12 @@ function App() {