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:
arsam
2026-09-18 23:25:10 +03:30
parent c168cd90cb
commit 28accf8f7b
+67
View File
@@ -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>
);
}