- 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>
12 KiB
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 inpublic/fonts/, originals fromcdn.meshkee.com/web-builder/fonts/.... - Icons: inline stroke SVGs in
src/components/Icons.js(no icon-font dependency). - Images: local under
public/images/, rendered withnext/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