Import source: app/src/pages/DirectoryListPage
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,67 @@
|
|||||||
|
import { useState, useMemo } from 'react';
|
||||||
|
import { TeknavData } from '../../teknav-data.js';
|
||||||
|
import { useNav, EmptyState, inputStyle } from '../../teknav-ui.jsx';
|
||||||
|
|
||||||
|
export function DirectoryListPage() {
|
||||||
|
const { navigate } = useNav();
|
||||||
|
const [companies] = useState(() => TeknavData.companies ?? []);
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
|
||||||
|
const filtered = useMemo(() => {
|
||||||
|
if (!search.trim()) return companies;
|
||||||
|
const q = search.trim().toLocaleLowerCase('fa-IR');
|
||||||
|
return companies.filter((c) =>
|
||||||
|
c.name.toLocaleLowerCase('fa-IR').includes(q) ||
|
||||||
|
c.description.toLocaleLowerCase('fa-IR').includes(q) ||
|
||||||
|
(c.techStack || []).some((t) => t.toLocaleLowerCase('en-US').includes(q)),
|
||||||
|
);
|
||||||
|
}, [companies, search]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ maxWidth: 960, margin: '0 auto', padding: '24px 16px 80px', direction: 'rtl', fontFamily: 'Vazirmatn,sans-serif' }}>
|
||||||
|
<nav style={{ fontSize: 13, color: '#5F6B6D', marginBottom: 24, display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||||
|
<span style={{ cursor: 'pointer', color: '#0F6B73' }} onClick={() => navigate('/')}>تکناو</span>
|
||||||
|
<span>›</span>
|
||||||
|
<span>دایرکتوری شرکتهای فناوری</span>
|
||||||
|
</nav>
|
||||||
|
<h1 style={{ fontSize: 'clamp(22px,4vw,30px)', fontWeight: 800, color: '#0C1E22', marginBottom: 8 }}>
|
||||||
|
دایرکتوری شرکتهای فناوری ایران
|
||||||
|
</h1>
|
||||||
|
<p style={{ fontSize: 15, color: '#5F6B6D', lineHeight: 1.8, marginBottom: 28 }}>
|
||||||
|
پروفایل شرکتهای فناوری ایران همراه با استک فنی، اطلاعات تماس و نشان تأیید.
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
placeholder="جستوجو در شرکتها…"
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
style={{ ...inputStyle, marginBottom: 24, width: '100%', maxWidth: 400 }}
|
||||||
|
/>
|
||||||
|
{filtered.length === 0 && (
|
||||||
|
<EmptyState title="شرکتی یافت نشد" subtitle="جستوجوی دیگری امتحان کنید" />
|
||||||
|
)}
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill,minmax(280px,1fr))', gap: 16 }}>
|
||||||
|
{filtered.map((company) => (
|
||||||
|
<div
|
||||||
|
key={company.slug}
|
||||||
|
onClick={() => navigate(`/directory/${company.slug}`)}
|
||||||
|
style={{ background: '#fff', border: '1px solid #E4DDD2', borderRadius: 12, padding: 20, cursor: 'pointer', transition: 'box-shadow 0.2s' }}
|
||||||
|
onMouseEnter={(e) => { e.currentTarget.style.boxShadow = '0 4px 16px rgba(0,0,0,0.1)'; }}
|
||||||
|
onMouseLeave={(e) => { e.currentTarget.style.boxShadow = ''; }}
|
||||||
|
>
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 10 }}>
|
||||||
|
<span style={{ fontSize: 18, fontWeight: 700, color: '#0C1E22' }}>{company.name}</span>
|
||||||
|
{company.verified && <span style={{ fontSize: 11, background: '#E8F5E9', color: '#2E7D32', padding: '2px 8px', borderRadius: 20, fontWeight: 600 }}>✓ تأیید</span>}
|
||||||
|
</div>
|
||||||
|
<p style={{ fontSize: 13, color: '#5F6B6D', lineHeight: 1.7, marginBottom: 12 }}>{company.description.slice(0, 100)}…</p>
|
||||||
|
<div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
|
||||||
|
{(company.techStack || []).slice(0, 4).map((t) => (
|
||||||
|
<span key={t} style={{ background: '#F4EFE6', color: '#263238', fontSize: 11, padding: '2px 8px', borderRadius: 20 }}>{t}</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user