Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
68 lines
3.6 KiB
React
68 lines
3.6 KiB
React
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>
|
||
);
|
||
}
|