From 0eab8ed7566605ad2efdcf90a0e6e10f3de11995 Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:25:35 +0330 Subject: [PATCH] Import source: app/src/pages/SearchPage Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- app/src/pages/SearchPage.jsx | 121 +++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 app/src/pages/SearchPage.jsx diff --git a/app/src/pages/SearchPage.jsx b/app/src/pages/SearchPage.jsx new file mode 100644 index 0000000..bb6dddc --- /dev/null +++ b/app/src/pages/SearchPage.jsx @@ -0,0 +1,121 @@ +import { useState, useCallback, useEffect } from 'react'; +import { TeknavData } from '../../teknav-data.js'; +import { + useNav, EmptyState, + CategoryBadge, inputStyle, pillBtn, +} from '../../teknav-ui.jsx'; +import { ArticleRow } from '../../teknav-articles.jsx'; +import { contentApi } from '../../src/lib/content-api.js'; + +function SearchResult({ article, q, highlight, idx }) { + const { navigate } = useNav(); + return ( +
navigate('/article/' + article.slug)} style={{ + padding: '24px 0', borderBottom: '1px solid #E4DDD2', cursor: 'pointer', + opacity: 0, animation: `fadeIn 0.3s ${idx * 40}ms forwards`, + }}> +
+ + {article.date} · {article.readTime} دقیقه +
+

+

+

+ ); +} + +export function SearchPage({ initQ = '' }) { + const [q, setQ] = useState(initQ); + const [input, setInput] = useState(initQ); + const [filters, setFilters] = useState({ category: '', author: '', type: '', tag: '', dateRange: '' }); + const [items, setItems] = useState([]); + const [loading, setLoading] = useState(false); + const { navigate } = useNav(); + + const load = useCallback(() => { + setLoading(true); + const params = { + q, + category: filters.category, + author: filters.author, + type: filters.type, + tag: filters.tag, + limit: 50, + }; + const apiCall = q ? contentApi.search(params) : contentApi.listArticles(params); + apiCall + .then(res => setItems(res.items ?? [])) + .finally(() => setLoading(false)); + }, [q, filters]); + + useEffect(() => { load(); }, [load]); + + const doSearch = (e) => { e.preventDefault(); setQ(input); }; + + const highlightText = (text, query) => { + if (!query) return text; + const parts = text.split(new RegExp(`(${query})`, 'gi')); + return parts.map((part, i) => + part.toLowerCase() === query.toLowerCase() + ? `${part}` + : part + ).join(''); + }; + + return ( +
+
+

جستجوی پیشرفته

+ +
+ setInput(e.target.value)} placeholder="جستجو در مقاله‌ها..." + style={{ flex: 1, ...inputStyle, fontSize: 16 }} dir="rtl" autoFocus /> + +
+ +
+ + +
+ {loading ? : ( + <> + {items.length === 0 ? : ( +
+
{items.length.toLocaleString('fa-IR')} نتیجه پیدا شد
+ {items.map((a, i) => )} +
+ )} + + )} +
+
+
+ +
+ ); +}