80 lines
6.4 KiB
Markdown
80 lines
6.4 KiB
Markdown
# HOM arch studio — AI / Project Context
|
||
|
||
Persian (fa, RTL) brochure website for **استودیو معماری هوم** (architecture + interior design group).
|
||
Keep this file current whenever routes, slots, data sources or design rules change.
|
||
|
||
## Source of truth
|
||
- Live domain: `https://homgroup.com` (`NEXT_PUBLIC_WEBSITE_DOMAIN`, default `homgroup.com`)
|
||
- Backend docs: https://api.meshkee.com/docs/website (OpenAPI: `/docs/website/openapi.json`)
|
||
- API base: `https://api.meshkee.com/api/v1` (`NEXT_PUBLIC_MESHKEE_API_BASE`)
|
||
- Tenant: `GET /tenants/homgroup.com` — **not registered yet** (404 as of 2026-10-11). Every Meshkee read has a local fallback, so the site renders fully without the tenant.
|
||
- Prompt reference: `https://api.meshkee.com/api/v1/public/ai-prompts/studio-hom/basic-create/36caa331616c4b1cd382f8cb`
|
||
- Original brief: homepage + about + contact only; `lang=fa`, `dir=rtl`, flat design, palette from the logo.
|
||
|
||
## Stack
|
||
- Next.js 15 App Router + React 19 + TypeScript, no Tailwind — all styles in `src/app/globals.css`
|
||
- `output: "standalone"` in `next.config.ts` (**required** for the Meshkee websites VM; deploy drops `node_modules`)
|
||
- `npm run build` runs `prebuild` → `scripts/generate-sitemap-config.mjs` (scans `src/app` for static pages)
|
||
- `npm run lint` = `tsc --noEmit`
|
||
- Font: IranYekan (local, `public/fonts/`, weights 300/400/500/700) via `next/font/local` → `--font-yekan`
|
||
|
||
## Design language (flat)
|
||
- Palette: bg `#ffffff`, surface `#f4f3f1`, text `#111111`, muted `#6b6b6b`, hairline `#e2e0dc`, accent red `#e3002b` (the logo dot)
|
||
- Flat only: no shadows, no border-radius, 1px hairlines, solid fills. Red appears as a small square “dot” (eyebrows, hero title) and on hover.
|
||
- Latin labels use `.latin` (uppercase, letter-spaced, LTR). One dark section (`.section--dark`) for the process.
|
||
- Header is sticky, white, hairline bottom; mobile burger menu under 900px.
|
||
- Logo: `public/images/logo.png` (cropped from `assets/logo/logo.jpeg`); favicon `src/app/icon.png`
|
||
|
||
## Routes
|
||
| Route | Purpose |
|
||
| --- | --- |
|
||
| `/` | Hero (title + CMS hero image), intro, 4 services, 6 selected projects, studio block, 4-step process (dark), stats, CTA |
|
||
| `/about` | Page hero image, story (3 paragraphs from `business-info.about` or fallback), 3-image gallery, values, services list, stats, CTA |
|
||
| `/contact` | Facts (phones, email, Instagram, address), contact image, form → `POST /api/contact` |
|
||
| `/api/contact` | Proxies to `POST /tenants/{domain}/contact-submissions` (`title`, `name`, `text` required; `email`, `cellNumber` optional) |
|
||
| `/meshkee/static-image-slots` | Slot catalog (`STATIC_IMAGE_SLOTS`) for the dashboard “Refresh slots” |
|
||
| `/meshkee/sitemap-config.json` | Static pages for the Meshkee-generated sitemap |
|
||
|
||
No `/login`, `/register`, `/cart`, `/checkout`, no local `sitemap.xml` / `robots.txt` (nginx proxies those to the API).
|
||
|
||
## Meshkee integration (`src/lib/`)
|
||
- `config.ts` — domain / API base / portal URLs
|
||
- `meshkee.ts` — `meshkeeGet` (ISR 300s, returns fallback on any error), `getBusinessInfo`, `getFavicon`
|
||
- `static-images.ts` — slot catalog + `getPageSlots(pageKey)` (parses `{ items: [{ key, aspectRatio, images[] }] }`), `slotImages`, `slotRatio`
|
||
- `content.ts` — resolves name / logo / phones / emails / address / Instagram / about from `business-info` with fallbacks from `src/data/site.ts`; `parseHeadTag`, `stripScripts`, digit helpers
|
||
- Root layout: `metaTags` → `<CmsMeta>` in `<head>`; `schema.jsonLd` → `<JsonLd>` when `schema.enabled`; `trustBadges[].embedHtml` → footer (scripts stripped)
|
||
- Favicon: `GET /website/favicon` → `metadata.icons`; falls back to `src/app/icon.png`
|
||
|
||
### Static image slots
|
||
Fetch per page: `GET /tenants/{domain}/website/static-images?pageKey=…`. Empty/fail → local images from `gallery` in `src/data/site.ts`.
|
||
`url` → `<img>`, `linkUrl` → wrap in `<a>`, `titleFa`/`titleEn`/`subtext` → captions where the UI shows them.
|
||
Use the API `aspectRatio` first, catalog second. **If a frame’s size or ratio changes in development, update `STATIC_IMAGE_SLOTS` in the same change.**
|
||
|
||
| key | page | kind | itemCount | aspectRatio | width | UI |
|
||
| --- | --- | --- | --- | --- | --- | --- |
|
||
| `hero` | home | single | 1 | `16:9` | 1920 | Hero frame; `titleFa` shown in the caption row |
|
||
| `projects` | home | list | null | `4:5` | 1200 | Selected projects grid; `titleFa` = title, `titleEn` = Latin subtitle, `subtext` = meta (e.g. category · year). When empty → 6 local `projects` |
|
||
| `studio-image` | home | single | 1 | `4:3` | 1400 | “نگاه ما” block image |
|
||
| `about-hero` | about | single | 1 | `16:9` | 1920 | About page hero |
|
||
| `about-gallery` | about | list | 3 | `1:1` | 900 | 3-up square gallery |
|
||
| `contact-image` | contact | single | 1 | `4:5` | 1200 | Image under the contact facts |
|
||
|
||
## Local content / fallbacks (`src/data/site.ts`)
|
||
- `site` — names (`استودیو معماری هوم` / `HOM arch studio`), tagline, description, placeholder phone `۰۹۱۲ ۰۰۰ ۰۰۰۰`, email `info@homgroup.com`, Instagram `@hom.archstudio`, address `تهران`, 3 about paragraphs. **Replace placeholders once the business profile exists in Meshkee** (they are overridden automatically by `business-info` when present).
|
||
- `services` (4), `processSteps` (4), `stats` (4), `projects` (6), `gallery` (image paths), `NAV_LINKS`
|
||
- Images: `public/images/*.jpg` — resized (≤1800px, q82) from `assets/images/` (originals kept out of git). Mapping: `facade-sunset*` ← IMG_1455/1456/1458, `courtyard-brick*` ← IMG_0356/0357, `kitchen-cream*` ← IMG_0374/0375, `study-terracotta*` ← IMG_0376/0377, `kitchen-oak*` ← IMG_0394/0396, `facade-louver` ← IMG_0400, `garden-gate` ← IMG_1037
|
||
|
||
## SEO
|
||
- Unique `<title>` / description per page (`metadata` in each `page.tsx`; template `%s | {name}`)
|
||
- One `<h1>` per page; content images have `alt`
|
||
- Static pages published through `/meshkee/sitemap-config.json`; do not add `app/sitemap.ts` / `app/robots.ts`
|
||
|
||
## Components (`src/components/`)
|
||
`Header` (client; sticky, burger), `Footer`, `CmsMeta` (+ `JsonLd`), `SlotImage` (flat frame for slot/fallback images), `ContactForm` (client; posts to `/api/contact`, Persian status messages)
|
||
|
||
## Deploy
|
||
Standard Meshkee websites VM flow: push → Super Admin **Deploy**. Deploy log must say `standalone build detected`; PM2 script `.next/standalone/server.js`.
|
||
|
||
## Changelog
|
||
- 2026-10-11 — Initial build: home / about / contact, Meshkee business-info + static-image slots + contact form, standalone runtime, sitemap-config generator.
|