Files
teknav-bak/app/src/pages/DirectoryListPage.jsx
T
arsam 28accf8f7b Import source: app/src/pages/DirectoryListPage
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
2026-09-18 23:25:10 +03:30

68 lines
3.6 KiB
React
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
}