- Homepage faithfully matching dejband.com (hero, services, consulting,
stats, about block, timeline, portfolio, articles) + About/Contact/
Portfolios/Articles pages under source URLs
- Meshkee API integration: live blog content, favicon, user menu,
sitemap/robots proxy, canonical /blog/{id}/{slug}
- SEO pass: one H1 per page, unique metadata + canonicals, alt text
- Contact form wired to /api/contact with toast + reset
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
139 lines
12 KiB
Markdown
139 lines
12 KiB
Markdown
# Dejband.com — Clone Project Context
|
||
|
||
> Living document. Update on **every** prompt iteration so other AI tools / developers
|
||
> can pick up work without re-discovering decisions.
|
||
|
||
## 1. Goal
|
||
|
||
Rebuild a marketing-site replica of **dejband.com** ("مهندسین مشاور دژبند قم" — Dejband
|
||
Consulting Engineers, Qom) using **Next.js (App Router)**, in **Persian (`fa`)** with
|
||
**RTL** layout.
|
||
|
||
Scope for this phase — **3 pages only**:
|
||
|
||
| Page | Route | Source |
|
||
| --- | --- | --- |
|
||
| Homepage | `/` | https://dejband.com |
|
||
| About Us | `/about` | https://www.dejband.com/aboutus |
|
||
| Contact Us | `/contact` | https://www.dejband.com/contactus |
|
||
|
||
Blog / articles are **out of scope** — they will be wired to a backend later.
|
||
`/#articles` and "مقالات" nav link are placeholders.
|
||
|
||
## 2. Prompt iteration log
|
||
|
||
| # | Date | Summary |
|
||
| --- | --- | --- |
|
||
| 1 | 2026-09-04 | Initial build: scaffolded Next.js project, downloaded assets, built shared Header/Footer + Home/About/Contact pages, RTL + Persian, palette from source, footer bottom-bar modeled on safeteb.com. |
|
||
| 2 | 2026-09-04 | **Faithful homepage rebuild to match the original exactly.** Re-inspected every dejband.com homepage section. New/rewritten sections: Hero (2-col — blurred cover bg + framed foreground photo + centred heading + circled arrow, 6 slides), Services (black bg, 150px metallic PNG line icons, 3-col, no cards), Consulting (6 rows, fixed parallax strip), Stats (#0F0F0F, vertical counters 70/531/217/25), AboutBlock (blue lead + h5 + 2 ruled sub-columns), Timeline (vertical #083578 numbered nodes + centre line, alternating labels), Portfolio (4-col image grid, `rgba(8,53,120,.9)` hover overlay + fa/en captions), Articles (3-col blog grid). Downloaded: 6 service icon PNGs (`icons/svc-*.png`), 8 portfolio images (`portfolio/p-*.jpg`), 3 article thumbs (`articles/a-*.jpg`), hero foreground photos (`hero/fg-*.jpg`), `consult-parallax.jpg`. Added Montserrat (next/font/google) for Latin kickers. `next.config.mjs`: `images.unoptimized = true` (assets are pre-sized local copies). Removed `AboutPreview`, `ServiceIcon`. |
|
||
|
||
### Homepage section order (matches source DOM)
|
||
`Hero → Services → Consulting(×6) → Stats → AboutBlock → Timeline → Portfolio → CtaBand → Articles`
|
||
|
||
| 3 | 2026-09-04 | **All header pages created + routes aligned to source URLs.** Renamed `/about`→`/aboutus`, `/contact`→`/contactus` (matching dejband.com). New pages: `/portfolios` (blue `#083578` `PageTitle` bar + breadcrumb + light-gray 3-col project card grid — 4 real projects with images from `meshkee-storage`: چسب و رنگ، نیروموتور، هتل استقلال، مجتمع زمزم → `public/images/projects/proj-*.jpg`) and `/articles` (blue title bar + 4-col blog grid, same 3 `ARTICLES`). Rebuilt `/aboutus` and `/contactus` using shared `PageTitle`. Nav items آموزش / مشاوره رایگان / مجوزها point to `/` (source does the same). New component `PageTitle.js`. Consulting section: removed bg/parallax images — now a subtle `#0e0e0e` half-panel (`.consult-row::before`), alternating with `.flip`. AboutBlock two columns moved to 50/50. |
|
||
| 4 | 2026-09-04 | **`/aboutus` faithful rebuild (8 sections, dark theme)** mirroring source `/aboutus`: intro badge, هیئت مدیره (3 members `BOARD_MEMBERS` + `about/team/m-*.jpg`), ماموریت/چشمانداز interactive tabs (`MissionTabs.js`), طراحی صنعتی تخصص ماست, سازه صنعتی, رزومه و کاتالوگ (icons `about/ic-*.png`), blue CTA bar. 10 assets → `public/images/about/`. |
|
||
| 5 | 2026-09-04 | Hero heading: smaller (`clamp(20px,2.2vw,30px)`) + tighter `line-height:1.45`. "مشاهده بیشتر" button switched to Persian font (`--font-fa`). |
|
||
| 8 | 2026-09-04 | **Contact form wired to an API.** New route `app/api/contact/route.js` (POST) — validates `{name,phone,email,message}` (Persian-digit aware, `0?\d{10,11}` phone), returns `200 {ok,message,delivered}` or `422 {ok:false,errors:{...}}`. When `MESHKEE_SMS_API_KEY` + `MESHKEE_CONTACT_NOTIFY_TO` env vars are set it notifies the business via `POST /api/v1/public/sms/send` (`X-Api-Key`, `{domain,to,message}`); without them it still accepts (`delivered:false`). No public contact endpoint exists in the Meshkee docs — this route is the integration point. `ContactForm.js` rewritten: `fetch('/api/contact')`, loading state ("در حال ارسال…", disabled inputs), **success → toast (auto-dismiss 5s) + inline `.form-success-text` + `form.reset()`**, error → red toast + inline `.field-err` per field. New CSS: `.toast*`, `.field-err`, `.form-success-text`. |
|
||
| 7 | 2026-09-04 | **SEO & sitemap phase.** Sitemap/robots are **proxied** through the Meshkee API, no static files: route handlers `app/{robots.txt,sitemap.xml,sitemap-main.xml,sitemap-products.xml,sitemap-blogs.xml}/route.js` → `GET https://api.meshkee.com/api/v1/tenants/dejband.com/<same>` via `proxyText()` in `lib/api.js` (each has an inline fallback; static routes exclude auth/checkout/cart/admin). **Canonical blog URL is `/blog/{id}/{titleSlug}`** (`app/blog/[id]/[slug]/page.js`, SSG from `getBlogById`, `slugify()` keeps Farsi & converts spaces→`-`); `app/articles/[slug]` is now a 307 redirect to the canonical path (`encodeURI` — Location must be ByteString); `/articles` listing links via `blogPath()`. **One H1 per page:** homepage has a single `.sr-only` `<h1>` + hero titles demoted to `<h2 class="hero-title">`; `PageTitle` gained `as` prop — detail pages pass `as="div"` so the post/project `<h1>` is the only one. **Per-page metadata:** unique `title`+`description`+`alternates.canonical` on `/`, `/aboutus`, `/contactus`, `/portfolios`, `/articles`, and both detail routes. **Alt text:** hero fg imgs → slide title, service icons → `آیکون {title}`, portfolio imgs → `{cat} — {en}`. `SITE_URL` const added. Build: 20 routes. |
|
||
| 6 | 2026-09-04 | **Backend integration (Meshkee public API).** New `src/lib/api.js` — `API_BASE=https://api.meshkee.com/api/v1`, `TENANT_BASE=/tenants/dejband.com`, `CUSTOMER_URL=https://customer.dejband.com`. Endpoints used: `GET /tenants/dejband.com/website/favicon` (favicon w/ fallback to bundled `public/favicon.png`), `GET /tenants/dejband.com/blogs` + `/blogs/{slug}` (live blog content), `GET /tenants/dejband.com/portfolios` (returns empty → portfolio uses local `PROJECTS`). **Auth/nav:** `UserMenu.js` — icon → `customer.dejband.com` when signed out; when signed in (reads `localStorage.meshkee_auth` / JWT `meshkee_token`) shows "{name} عزیز" dropdown → پروفایل من / مدیریت وبسایت (admin only) / خروج. **Favicon:** `layout.js` now `generateMetadata()` → `icons` from backend. **Blog module:** `/articles` async-fetches list; `/articles/[slug]` renders `mainTextHtml`, author, cover, Persian date (`formatFaDate` via `Intl` persian calendar) + "مقالات مرتبط" row. **Portfolio module:** `/portfolios/[slug]` — hero w/ CSS hover-zoom (`.pf-zoom-frame`), meta, `Lightbox.js` gallery (keyboard nav, counter, hover-zoom thumbs), "پروژههای مرتبط" row. `PROJECTS` in `site.js` extended with `slug`/`category`/`location`/`year`/`description`/`gallery`. New CSS: user-menu, `.pf-detail*`, `.pf-gallery*`, `.lb-*` lightbox, `.post*` blog, `.related-section`. Build: 15 routes (3 blog + 4 portfolio SSG, `revalidate: 300`). |
|
||
|
||
## 3. Tech stack
|
||
|
||
- **Next.js 15** (App Router, JS — no TypeScript), React 19.
|
||
- No CSS framework. One global stylesheet: `src/app/globals.css` (CSS custom properties
|
||
for the palette; component styles co-located by section).
|
||
- Fonts self-hosted via `next/font/local` — **Yekan Bakh** (primary, matches source
|
||
`--wb-default-font: yekan-bakh`) + **IranYekan** (numerals / fallback). Files in
|
||
`public/fonts/`, originals from `cdn.meshkee.com/web-builder/fonts/...`.
|
||
- Icons: inline stroke SVGs in `src/components/Icons.js` (no icon-font dependency).
|
||
- Images: local under `public/images/`, rendered with `next/image`.
|
||
|
||
## 4. Brand / design tokens (from source web-builder theme vars)
|
||
|
||
| Token | Value | Origin |
|
||
| --- | --- | --- |
|
||
| `--brand-primary` | `#2991d6` | `--wb-primary-color` |
|
||
| `--brand-primary-dark` | `#1875bb` | `--color-blue` |
|
||
| `--brand-navy` | `#04314b` | `--color-dark-blue` |
|
||
| `--brand-cyan` | `#32c5d2` | `--color-invert` |
|
||
| body background | `#101010` | source `body` bg |
|
||
| body text (on dark) | `~#9aa6b2` | derived from source `#5c6873` |
|
||
| default font | Yekan Bakh | `--wb-default-font` |
|
||
|
||
Overall look: **dark theme** (near-black sections), blue accent, generous vertical
|
||
rhythm, uppercase Latin kicker above each Persian section title (mirrors source's
|
||
"خدمات ما / OUR SERVICES" pattern).
|
||
|
||
## 5. Asset inventory (`public/`)
|
||
|
||
```
|
||
images/logo.png # white wordmark, source: assets/files/A3IeR4aVLO.png
|
||
images/meshkee-white.png # footer credit logo, source: safeteb.com/images/footer/MeshkeeLogo-White.png
|
||
images/hero/slide-1..7.jpg # homepage slider backgrounds
|
||
images/services/service-1..6.jpg # "مشاوره تخصصی" alternating rows
|
||
images/about/about-1..3.jpg # about-preview + about page splits
|
||
fonts/YekanBakh-Regular.ttf, YekanBakh-Light.ttf
|
||
fonts/IranYekan-Regular/Medium/Light/Bold.ttf
|
||
```
|
||
|
||
All content + media taken from the current live site — treated as valid for use per
|
||
the project brief.
|
||
|
||
## 6. Component map
|
||
|
||
| File | Role |
|
||
| --- | --- |
|
||
| `src/app/layout.js` | `<html lang="fa" dir="rtl">`, font vars, metadata, Header + Footer shell |
|
||
| `src/app/globals.css` | all styling |
|
||
| `src/lib/site.js` | **single source of content data** — nav, contact info, hero slides, services, consulting rows, stats, timeline, socials |
|
||
| `components/Header.js` | sticky dark header, logo, nav, mobile drawer, social + login (`client`) |
|
||
| `components/Footer.js` | 4-column footer **+ bottom bar modeled on safeteb.com** (`.footer-bottom` → `.footer-bottom-bar` → `.footer-bottom-site` + `.meshkee-credit` animated frame) |
|
||
| `components/Hero.js` | auto-rotating 7-slide hero, dots, "مشاهده بیشتر" round arrow button (`client`) |
|
||
| `components/Services.js` | "خدمات ما / Our Services" icon grid |
|
||
| `components/Consulting.js` | alternating image/text rows (6 home consulting blurbs) |
|
||
| `components/Stats.js` | 4 animated counters, IntersectionObserver (`client`) |
|
||
| `components/AboutPreview.js` | home "درباره ما" split section |
|
||
| `components/Timeline.js` | 5-step company history |
|
||
| `components/CtaBand.js` | reusable blue CTA strip |
|
||
| `components/ContactForm.js` | contact form, client-side only (no backend yet) (`client`) |
|
||
| `components/Icons.js`, `components/ServiceIcon.js` | inline SVG icon set + name→icon map |
|
||
|
||
## 7. Footer bottom-row spec (safeteb.com model)
|
||
|
||
Exact structure reproduced (class names + animated corner-draw frame on hover):
|
||
|
||
```
|
||
.footer-bottom (bg #1d1d1d, padding 20px 0 19px)
|
||
.container
|
||
.footer-bottom-content
|
||
.footer-bottom-bar (flex, space-between, wrap, gap 12px)
|
||
.footer-bottom-site -> "مهندسین مشاور دژبند قم"
|
||
a.meshkee-credit[href=meshkee.com, dir=ltr]
|
||
.meshkee-credit__frame > 4x .meshkee-credit__line--(l|t|r|b)
|
||
img.meshkee-credit__logo (meshkee-white.png, 42x42)
|
||
.meshkee-credit__text
|
||
.meshkee-credit__label -> "Designed And Developed By"
|
||
.meshkee-credit__name -> "Meshkee E-Commerce Team"
|
||
```
|
||
|
||
CSS for `.meshkee-credit*` copied verbatim from safeteb.com computed rules.
|
||
|
||
## 8. Known gaps / TODO (next iterations)
|
||
|
||
- Blog / articles listing + detail — pending backend.
|
||
- "پروژه ها" (portfolios) page — not in current scope, nav points to `/#services`.
|
||
- Contact form has **no submit endpoint** — shows a success state only.
|
||
- Map is an OpenStreetMap embed with approximate Qom coordinates; swap for exact
|
||
location / Google Maps when available.
|
||
- Board-of-directors ("هیئت مدیره") photos not provided on source in a usable form —
|
||
section summarized as text on `/about`.
|
||
- Real favicon / OG image not yet added.
|
||
|
||
## 9. Run
|
||
|
||
```
|
||
npm install
|
||
npm run dev # http://localhost:3000
|
||
npm run build && npm start
|
||
```
|