feat(projects): داده‌های واقعی پروژه‌ها — ستون‌های تازه و حذف داده‌های ماک

- دیتابیس/مدل/اسکیما: land_area (مساحت عرصه)، pilot_floors (طبقات روی
  همکف/پیلوت) و سه ستون واحدها (مسکونی/تجاری/اداری) به‌جای «واحدها»ی تکی
- فایل استاتیک projectsData (داده‌های ماک) حذف شد؛ لیست، جزئیات و
  «پروژه‌های شاخص» همه از دیتابیس می‌خوانند
- برچسب‌های i18n فهرست مشخصات مطابق شیت تیم
This commit is contained in:
aramesh-site deploy
2026-09-28 10:50:39 +00:00
parent 0c87a287a3
commit 182a1bb674
10 changed files with 60 additions and 117 deletions
+6 -3
View File
@@ -54,11 +54,14 @@ export function ProjectDetail() {
const facts = [
{ label: t('specStatus'), value: statusLabel },
{ label: t('specYear'), value: project.year },
{ label: t('specFloors'), value: project.floors },
{ label: t('specUnits'), value: project.units },
{ label: t('specProjectType'), value: project.project_type },
{ label: t('specLandArea'), value: project.land_area },
{ label: t('specArea'), value: project.area },
{ label: t('specUsage'), value: project.usage },
{ label: t('specPilotFloors'), value: project.pilot_floors },
{ label: t('specFloors'), value: project.floors },
{ label: t('specUnitsResidential'), value: project.units_residential },
{ label: t('specUnitsCommercial'), value: project.units_commercial },
{ label: t('specUnitsOffice'), value: project.units_office },
].filter((f) => String(f.value ?? '').trim() !== '')
return (
+6 -22
View File
@@ -10,7 +10,6 @@ import { useLang } from '../i18n/lang';
import { useFieldSaver } from '../admin/AdminContext';
import { InlineEdit } from '../components/admin/InlineEdit';
import { AddItemButton, EditableItem } from '../admin/Editable';
import { projectsData } from '../data/projectsData';
import { LazyProjectsMapAll } from '../map/LazyMaps';
import { MAP_PROJECTS, type MapProject } from '../data/mapProjects';
@@ -38,11 +37,7 @@ export function Projects() {
// پروژه‌ها از دیتابیس خوانده می‌شوند تا ویرایش پنل همان‌جا دیده شود؛
// فایل استاتیک فقط وقتی دیتابیس خالی است جانشین می‌شود (محتوای قدیمی).
const fromDb = dbProjects.length > 0;
const cardProjects = useMemo(() => {
if (fromDb) return dbProjects;
return projectsData.map((p) => ({ ...p, id: Number(p.id) }));
}, [fromDb, dbProjects]);
const cardProjects = useMemo(() => dbProjects, [dbProjects]);
// Filtering and Pagination State
const [page, setPage] = useState(1);
@@ -83,11 +78,7 @@ export function Projects() {
const dbMatch = dbProjects.find(
(p) => p.title === mapProject.name || p.title_en === mapProject.name,
);
if (dbMatch) return `/projects/${dbMatch.slug}`;
const match = projectsData.find(
(p) => p.name.fa === mapProject.name || p.name.en === mapProject.name,
);
return match ? `/projects/${match.slug}` : undefined;
return dbMatch ? `/projects/${dbMatch.slug}` : undefined;
};
return (
@@ -147,29 +138,22 @@ export function Projects() {
{displayedProjects.map((project, index) => {
// تصویر رکورد دیتابیس اولویت دارد؛ فقط ردیف‌های بدون تصویر از
// تصاویر جایگزین تکراری استفاده می‌کنند.
const hasOwnImage = 'image' in project && Boolean((project as { image?: string }).image);
const imageUrl = hasOwnImage ? undefined : `${BASE_IMG_URL}${(index % 6) + 1}.png`;
const card = (
<ProjectCard
project={project}
imageUrl={imageUrl}
detailHref={`/projects/${project.slug}`}
/>
);
return (
<Reveal key={project.id} delay={0.05 * (index % itemsPerPage)} className="h-full">
{fromDb ? (
<EditableItem resource="projects" item={project} editHref={`/admin/projects/${project.id}`} className="h-full">
{card}
</EditableItem>
) : (
card
)}
<EditableItem resource="projects" item={project} editHref={`/admin/projects/${project.id}`} className="h-full">
{card}
</EditableItem>
</Reveal>
);
})}
{fromDb && <AddItemButton resource="projects" editHrefBase="/admin/projects" />}
<AddItemButton resource="projects" editHrefBase="/admin/projects" />
</div>
{/* Load More Button */}