first commit
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
# 盈豐太陽能官網 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 將現有 Astro + Cloudflare + D1 骨幹改造成盈豐太陽能工程有限公司的村屋太陽能一頁式官網(Chakra UI)+ Blog + 內容管理後台。
|
||||
|
||||
**Architecture:** Astro 7(`output: "static"` + per-page `prerender=false`)作全疊框架,`@astrojs/react` 提供 React island,Chakra UI v3(Emotion)負責前台 UI。首頁 SSR 讀 D1,經 `Cache-Control: s-maxage` 邊緣快取。後台沿用 Astro SSR 表單 + HMAC cookie。資料層用 Drizzle + D1。
|
||||
|
||||
**Tech Stack:** Astro 7.3 / @astrojs/react 6 / React 19 / @chakra-ui/react 3.37 / @emotion/react / Drizzle ORM / Cloudflare D1 + KV / marked。
|
||||
|
||||
**已驗證(spike):** Chakra v3 + Astro SSR 可正常運作,inline critical CSS、零 FOUC、無 hydration error。
|
||||
|
||||
---
|
||||
|
||||
## 檔案結構
|
||||
|
||||
```
|
||||
src/
|
||||
├─ theme/system.ts # Chakra system(tokens/semanticTokens/recipes/fonts)
|
||||
├─ components/site/
|
||||
│ ├─ Provider.tsx # <ChakraProvider value={system}>
|
||||
│ ├─ SiteChrome.tsx # Header + main + Footer 外框
|
||||
│ ├─ Header.tsx Hero.tsx TrustBar.tsx Services.tsx Features.tsx
|
||||
│ ├─ Process.tsx Cases.tsx Faq.tsx ContactCta.tsx Footer.tsx
|
||||
│ ├─ WhatsAppFab.tsx Section.tsx SectionHeading.tsx
|
||||
│ ├─ HomePage.tsx # 組合首頁所有 section
|
||||
│ ├─ BlogIndex.tsx BlogPost.tsx
|
||||
├─ data/content.ts # D1 讀取:settings/items/cases,型別化
|
||||
├─ db/schema.ts # posts + site_settings + content_items + cases
|
||||
├─ db/seed.ts # 種子公司資料 + 樣本內容
|
||||
├─ layouts/Base.astro # SEO head / fonts / global reset
|
||||
├─ layouts/AdminLayout.astro # 後台外框(沿用 + 換色)
|
||||
├─ pages/index.astro # SSR 讀 D1 → <HomePage client:load>
|
||||
├─ pages/blog/index.astro # SSR → <BlogIndex client:load>
|
||||
├─ pages/blog/[slug].astro # SSR → <BlogPost client:load :html>
|
||||
├─ pages/admin/** # login/logout/index/post/settings/content/cases
|
||||
├─ pages/sitemap.xml.ts robots.txt.ts
|
||||
└─ lib/{auth,db,env,markdown}.ts(沿用)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Foundation
|
||||
|
||||
### Task 1: Chakra theme system
|
||||
|
||||
**Files:** Create `src/theme/system.ts`
|
||||
|
||||
- [ ] 定義 tokens:`colors.brand`(#0B8A5E 色階)、`colors.sky`(#0BA5EC 色階)、`fonts.heading/body = Noto Sans HK`
|
||||
- [ ] 定義 semanticTokens:`bg`, `bg.subtle`, `fg`, `fg.muted`, `border`, `brand.solid`, `brand.contrast`, `brand.muted`
|
||||
- [ ] `createSystem(defaultConfig, config)` 匯出 `system`
|
||||
- [ ] 驗證:`npm run build` 無 TypeScript/Chakra token 錯誤
|
||||
|
||||
### Task 2: Provider + SiteChrome
|
||||
|
||||
**Files:** Create `src/components/site/Provider.tsx`, `src/components/site/SiteChrome.tsx`, `Section.tsx`, `SectionHeading.tsx`
|
||||
|
||||
- [ ] `Provider` = `<ChakraProvider value={system}>{children}</ChakraProvider>`
|
||||
- [ ] `SiteChrome` = `<Provider><Header/><Box as="main">{children}</Box><Footer/><WhatsAppFab/></Provider>`
|
||||
- [ ] 驗證:build 過
|
||||
|
||||
### Task 3: Base.astro SEO layout
|
||||
|
||||
**Files:** Modify `src/layouts/Base.astro`
|
||||
|
||||
- [ ] 保留 canonical / OG / Twitter / robots 邏輯;加 `og:image`(cover prop)
|
||||
- [ ] 加 Google Fonts(Noto Sans HK)`<link>`,加中文字體 fallback
|
||||
- [ ] 移除舊的純 CSS 樣式(改由 Chakra 負責),只保留最小 global reset(可在 Chakra `globalCss`)
|
||||
- [ ] 驗證:build 過
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Data layer
|
||||
|
||||
### Task 4: Drizzle schema
|
||||
|
||||
**Files:** Modify `src/db/schema.ts`
|
||||
|
||||
- [ ] `posts` 加 `cover_image` (text), `tags` (text)
|
||||
- [ ] 新增 `site_settings`(key PK, value, updated_at)
|
||||
- [ ] 新增 `content_items`(id, kind, title, description, extra, sort_order, status, updated_at)+ index(kind,status,sort_order)
|
||||
- [ ] 新增 `cases`(id, title, location, completed_at, description, image_url, sort_order, status, updated_at)+ index(status,sort_order)
|
||||
- [ ] 匯出型別
|
||||
- [ ] 驗證:`npm run db:generate` 產生 migration
|
||||
|
||||
### Task 5: Seed
|
||||
|
||||
**Files:** Create `src/db/seed.ts`(以 drizzle 插入種子,可 idempotent)
|
||||
|
||||
- [ ] 公司資料:盈豐太陽能工程有限公司(電話/WhatsApp/email/地址/牌照號用佔位)
|
||||
- [ ] Hero 文案、SEO 預設
|
||||
- [ ] services(村屋太陽能、天台空間、合法支架、代辦申請、降室溫、回報計算)
|
||||
- [ ] features(熟悉香港環境、流程清晰、專人跟進、美觀效率、施工安全、真誠建議)
|
||||
- [ ] steps(初步諮詢/現場評估 → 申請文件 → 安裝施工 → 驗收認證 → 掛表發電)
|
||||
- [ ] faqs(村屋天台可否安裝、回本期、需要幾大面積、是否合法、保養、申請邊個)
|
||||
- [ ] cases(大埔上碗窯、元朗山下村、西貢西澳村 — 佔位圖)
|
||||
- [ ] 驗證:`npm run db:migrate:local` 後 SQL 查得到
|
||||
|
||||
### Task 6: Content access helpers
|
||||
|
||||
**Files:** Create `src/data/content.ts`
|
||||
|
||||
- [ ] `getSettings(db)` → Record<string,string>
|
||||
- [ ] `getItems(db, kind)` → published, order by sort_order
|
||||
- [ ] `getCases(db)` → published, order by sort_order
|
||||
- [ ] `getPublishedPosts(db)` / `getPostBySlug(db, slug)`
|
||||
- [ ] 型別 `Settings`, `ContentItem`, `CaseItem`
|
||||
- [ ] 驗證:TS build 過
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Homepage UI
|
||||
|
||||
### Task 7–16: Sections
|
||||
|
||||
**Files:** Create 各 section 元件(見檔案結構)
|
||||
|
||||
每個 section 一個 task,包含:完整 Chakra markup、響應式、內容 props、設計(清新天藍/綠)。
|
||||
- [ ] Header(sticky、玻璃感、手機 drawer、錨點導覽、WhatsApp CTA)
|
||||
- [ ] Hero(眉題/標題/副標/雙 CTA/主視覺圖/信任子彈)
|
||||
- [ ] TrustBar(牌照號、案例數、口碑)
|
||||
- [ ] Services(卡片 grid)
|
||||
- [ ] Features(6 卡)
|
||||
- [ ] Process(5 步 timeline)
|
||||
- [ ] Cases(案例卡 + 圖)
|
||||
- [ ] Faq(Accordion)
|
||||
- [ ] ContactCta(WhatsApp/電話/email/地址)
|
||||
- [ ] Footer + WhatsAppFab
|
||||
|
||||
### Task 17: HomePage 組裝 + index.astro
|
||||
|
||||
- [ ] `HomePage.tsx` 接收 `{ settings, services, features, steps, faqs, cases }` props,用 `<SiteChrome>` 包住所有 section
|
||||
- [ ] `src/pages/index.astro`:`prerender=false`,讀 D1,`<HomePage ... client:load />`,設 `Cache-Control`
|
||||
- [ ] 驗證:`astro dev` 開 / 無 console error,RWD 檢查
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Blog
|
||||
|
||||
### Task 18: Blog UI
|
||||
|
||||
- [ ] `BlogIndex.tsx`(卡片:封面/標題/摘要/日期,空狀態)
|
||||
- [ ] `BlogPost.tsx`(封面/標題/日期/prose/返回)
|
||||
- [ ] 改 `blog/index.astro`、`blog/[slug].astro` 用新元件(改 SSR propless → props)
|
||||
- [ ] 驗證:build + 瀏覽器
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Admin
|
||||
|
||||
### Task 19–22
|
||||
|
||||
- [ ] `/admin/settings`:分組表單(公司/聯絡/Hero/SEO),POST upsert
|
||||
- [ ] `/admin/content/[kind]`:通用 list + 編輯 + 上下排序(service/feature/step/faq)
|
||||
- [ ] `/admin/cases`、`/admin/cases/[id]`:CRUD
|
||||
- [ ] `/admin/post/[id]`:加封面圖欄位
|
||||
- [ ] 驗證:登入後可改,前台即刻反映(SSR)
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — SEO / Deploy
|
||||
|
||||
### Task 23–24
|
||||
|
||||
- [ ] 更新 `sitemap.xml.ts`(含 /blog 文章 cover)、`robots.txt.ts`
|
||||
- [ ] `wrangler.jsonc`:name=`yingfung-solar`、`SITE_NAME`=盈豐太陽能、佔位 d1/kv id
|
||||
- [ ] `astro.config.mjs`:`site`、`react()`(已加)
|
||||
- [ ] `src/config.ts`:公司名/tagline
|
||||
- [ ] README 更新部署步驟
|
||||
- [ ] 驗證:`npm run build`、`npm run preview`、Lighthouse
|
||||
|
||||
---
|
||||
|
||||
## 驗證指令
|
||||
|
||||
- `npm run build` 必須成功
|
||||
- `npm run db:migrate:local` 建本機 DB
|
||||
- `NODE_OPTIONS= npx astro dev` 開 :4321
|
||||
- 瀏覽器:無 console error、RWD、錨點、FAQ accordion、WhatsApp link 正確
|
||||
- 每個 phase 完成後 commit(如已初始化 git)
|
||||
@@ -0,0 +1,80 @@
|
||||
# 盈豐太陽能 — 前台 Editorial 極簡重新設計 (Redesign Spec)
|
||||
|
||||
- **日期**:2026-09-11
|
||||
- **狀態**:已與客戶確認方向
|
||||
- **背景**:初版 UI(見 `2026-09-11-ying-fung-solar-design.md`)被客戶評為「AI 模板感太重」。本規格取代該 spec 的 §5 設計系統部分;其餘架構/資料庫/路由/SEO 決策不變。
|
||||
|
||||
---
|
||||
|
||||
## 1. 設計方向
|
||||
|
||||
**暖米白 × 琥珀金 × 明體標題** 的 editorial 極簡風,似高端工程公司官網。
|
||||
|
||||
要消滅嘅「AI 模板痕跡」:
|
||||
|
||||
- 綠→天藍漸層(logo 磚、hero 光暈、流程圓圈、CTA 橫額)→ 全站零漸層、零光斑
|
||||
- 膠囊形按鈕(`rounded-full`)→ 直角或微圓角(≤4px)
|
||||
- Pill badge 眉題 →「琥珀短線+細字 letterspaced 眉題」
|
||||
- Hero 圖上浮卡 → 圖下髮絲線統計列
|
||||
- Icon 放淺色圓角磚嘅卡片網格 → 編號式清單/髮絲線格網,無卡片陰影
|
||||
- 柔和陰影卡片 → 髮絲邊框(hairline)分隔
|
||||
|
||||
## 2. 範圍
|
||||
|
||||
- **只改前台**:`src/theme/system.ts`、`src/layouts/Base.astro`、`src/components/site/*.tsx`
|
||||
- **唔郁**:資料層、D1 schema、路由、admin(`/admin` 後台維持現有純 CSS 色系)
|
||||
|
||||
## 3. 新 Design Tokens(`src/theme/system.ts`)
|
||||
|
||||
### 色彩
|
||||
|
||||
| Token | 值方向 | 用途 |
|
||||
|---|---|---|
|
||||
| `bg` 頁面 | 暖米白 `#FAF8F4` | 主背景 |
|
||||
| `bg.subtle` | 略深米白 `#F3EFE7` | 分段背景 |
|
||||
| `ink`(深色 surface) | 墨黑 `#1A1917` | CTA / Footer / 深色 section |
|
||||
| `fg` | 墨 `#1A1917` | 正文 |
|
||||
| `fg.muted` | 暖灰 `#6E6862` | 次要文字 |
|
||||
| `border.subtle` | 髮絲 `#E7E2D9` | 分隔線、邊框 |
|
||||
| `brand`(唯一彩色) | 琥珀金階梯,主色 `#C2410C`–`#D97706` 一帶 | CTA、編號、重點數字 |
|
||||
|
||||
- 語意 token 名保留(`brand.*`、`fg.muted`、`border.subtle`、`bg.subtle`)以減少改動;舊 `sky` 色階移除。
|
||||
- `bg.hero` token 移除(Hero 用主背景)。
|
||||
|
||||
### 字體
|
||||
|
||||
- 標題:`Noto Serif HK`(700/900),serif fallback
|
||||
- 內文:維持 `Noto Sans HK`
|
||||
- `Base.astro` 的 Google Fonts link 加入 Noto Serif HK 字重;global body 背景轉米白
|
||||
|
||||
### 形狀與動效
|
||||
|
||||
- 按鈕:實心墨黑或琥珀金,直角/微圓角(`rounded="sm"` 或 `none`),唔再係膠囊
|
||||
- 卡片:去大圓角去陰影,以髮絲線分隔
|
||||
- 動效:保留簡單 hover(透明度/位移),唔加新動畫庫
|
||||
|
||||
## 4. 各 Section 重構
|
||||
|
||||
1. **Header**:去玻璃模糊 → 米白實底+髮絲底線;logo 改純文字 wordmark(serif 公司名,唔再係漸層 icon 磚);CTA 改墨黑直角實心掣;手機 drawer 保留但跟新色
|
||||
2. **Hero**:serif 超大標題;眉題改琥珀短線+細字;剷走圖上浮卡 → 圖下方髮絲線統計列(回本期/系統年期/牌照);次 CTA 改文字連結「睇完成案例 →」;去背景光斑
|
||||
3. **TrustBar**:四欄髮絲分隔列,幼線 icon+細字,無底色無框
|
||||
4. **Services**:icon 卡片 → 編號式清單(01/02/03),serif 標題+列頂髮絲線,hover 出現箭嘴
|
||||
5. **Features**:白卡 → 髮絲線格網(報紙分欄感),編號+serif 標題
|
||||
6. **Process**:漸層圓圈 → 超大 serif 琥珀數字+髮絲連線
|
||||
7. **Cases**:去圓角去陰影;首案例 featured 放大(非對稱);地點 pill badge 改細字標籤
|
||||
8. **FAQ**:白卡 accordion → 髮絲線裸列,serif 問題
|
||||
9. **ContactCta**:漸層橫額 → 墨黑實底 section,serif 白標題+琥珀實心掣
|
||||
10. **Footer**:深綠底 → 墨黑底;logo 磚改文字 wordmark;髮絲分隔線
|
||||
11. **WhatsAppFab**:綠色圓掣 → 墨黑圓掣(icon 保持白色)
|
||||
12. **Blog 列表/文章頁**:serif 標題、髮絲線、琥珀 accent,跟新 tokens
|
||||
13. **SectionHeading**:pill eyebrow → 琥珀短線+細字眉題;預設左對齊
|
||||
|
||||
## 5. 驗證
|
||||
|
||||
- `npm run build` 通過
|
||||
- `npm run dev` 目測:RWD、錨點、FAQ accordion、WhatsApp link、無 hydration error
|
||||
|
||||
## 6. 文件同步
|
||||
|
||||
- `src/AGENTS.md`:token 名單更新(移除 `sky`、`bg.hero`;加入 `ink`)
|
||||
- `src/components/site/AGENTS.md`:樣式慣例更新(editorial 風、禁用漸層/膠囊/陰影卡)
|
||||
@@ -0,0 +1,302 @@
|
||||
# 盈豐太陽能工程有限公司 — 官網設計規格 (Design Spec)
|
||||
|
||||
- **日期**:2026-09-11
|
||||
- **專案代號**:yingfungsolar
|
||||
- **狀態**:已與客戶確認方向,待寫實作計劃
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景與目標
|
||||
|
||||
為香港**村屋太陽能**興建公司「盈豐太陽能工程有限公司」建立一個可以**完全部署在 Cloudflare** 的網站,包含:
|
||||
|
||||
- 面向公眾的一頁式官網
|
||||
- 一個 Blog 分頁(列表 + 文章頁)
|
||||
- 一個後台 `/admin`,讓非技術人員管理 Blog 及首頁內容
|
||||
|
||||
設計要求:美觀、現代化、清爽。內容參考 BrightSun Solar(村屋及工廈太陽能),但**本網站只做村屋**,而且版面設計不參考該站。
|
||||
|
||||
### 非目標 (Out of scope)
|
||||
|
||||
- 不做工廈 / 農地太陽能內容
|
||||
- 不做雙語(只做繁體中文)
|
||||
- 不做聯絡表單(只做 WhatsApp / 電話 / Email 連結)
|
||||
- 不做圖片上傳(先用佔位圖,後台以 URL 貼圖)
|
||||
- 不做多頁公司介紹(關於我們等內容併入一頁式)
|
||||
|
||||
---
|
||||
|
||||
## 2. 技術架構
|
||||
|
||||
沿用現有 `cf-dash` 骨幹,路線 A:**Astro + React islands + Chakra UI**。
|
||||
|
||||
```
|
||||
┌──────────────── Cloudflare Worker (一個 deploy) ────────────────┐
|
||||
瀏覽器 → │ Astro 7 │
|
||||
│ ├─ / SSR,讀 D1 → React island (Chakra UI) │
|
||||
│ ├─ /blog SSR,讀 D1 │
|
||||
│ ├─ /blog/[slug] SSR,讀 D1 + Markdown 渲染 │
|
||||
│ ├─ /admin/* SSR,Astro 表單 + HMAC cookie auth │
|
||||
│ ├─ /sitemap.xml SSR,讀 D1 │
|
||||
│ └─ /robots.txt 靜態 │
|
||||
│ │ │
|
||||
│ D1 (SQLite) ← Drizzle ORM │
|
||||
│ KV (CACHE) ← 內容版本快取 (可選) │
|
||||
└────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 技術選型
|
||||
|
||||
| 層 | 選用 | 說明 |
|
||||
|---|---|---|
|
||||
| 框架 | Astro 7 (`output: "static"` + per-page `prerender = false`) | 沿用現有 |
|
||||
| Adapter | `@astrojs/cloudflare` | 沿用現有 |
|
||||
| UI | `@chakra-ui/react` v3 + `@emotion/react`(只淺色模式,不引入 color mode 套件) | 新增 |
|
||||
| React | React 19(由 `npx astro add react` 加入) | 新增 |
|
||||
| DB | Cloudflare D1 (SQLite) | 沿用 |
|
||||
| ORM | Drizzle | 沿用 |
|
||||
| Auth | HMAC-signed cookie(`src/lib/auth.ts`) | 沿用 |
|
||||
| Markdown | `marked`(`src/lib/markdown.ts`) | 沿用 |
|
||||
|
||||
### 關鍵渲染決策
|
||||
|
||||
1. **首頁改為 SSR**(`prerender = false`),因為首頁內容由 D1 提供、後台改完要即時生效。
|
||||
- 用 `Cache-Control: public, s-maxage=60, stale-while-revalidate=300` 保持效能。
|
||||
2. **每個頁面用單一 React root island**(`client:load`),入面包一個 `<Provider>`。
|
||||
- 原因:Chakra 的 Provider 只需一個;避免多個 island 各自建立 Provider 造成樣式重複。
|
||||
- Astro 會 SSR render 呢個 island(SEO 無損),再喺 client hydrate。
|
||||
3. **Chakra v3 SSR 樣式注入**:**已用 spike 實測驗證可行**。
|
||||
- Versions: Astro 7.3.2 + `@astrojs/react` 6.0.5 + React 19.3 + `@chakra-ui/react` 3.37 + `@emotion/react` 11.14。
|
||||
- 實測結果:SSR 會將 critical CSS 以 inline `<style data-emotion>` 輸出(首屏即有樣式、零 FOUC);client hydrate 後 emotion 會自動把樣式整合到 `<head>`;**無 hydration error**,樣式正確。
|
||||
- 因此採預設 `react()`(streaming),每個 island 由 `<ChakraProvider value={system}>` 包裹。
|
||||
- 禁止使用 `client:only`(會失去 SEO)。
|
||||
4. **Admin 沿用 Astro SSR 表單**(POST `formData`),不引入 React/Chakra,降低複雜度。
|
||||
|
||||
---
|
||||
|
||||
## 3. 資料庫設計 (Drizzle / D1)
|
||||
|
||||
### 3.1 `posts`(現有,擴充)
|
||||
|
||||
| 欄位 | 型別 | 說明 |
|
||||
|---|---|---|
|
||||
| `id` | text PK | UUID |
|
||||
| `slug` | text unique | |
|
||||
| `title` | text | |
|
||||
| `excerpt` | text | |
|
||||
| `content` | text | Markdown |
|
||||
| `meta_description` | text | |
|
||||
| `cover_image` | text | **新增**,封面圖 URL |
|
||||
| `tags` | text | **新增**,逗號分隔(可選) |
|
||||
| `status` | text | `draft` \| `published` |
|
||||
| `published_at` | integer (timestamp_ms) | |
|
||||
| `updated_at` | integer (timestamp_ms) | |
|
||||
|
||||
### 3.2 `site_settings`(新增,單例 key-value)
|
||||
|
||||
| 欄位 | 型別 | 說明 |
|
||||
|---|---|---|
|
||||
| `key` | text PK | 設定名稱 |
|
||||
| `value` | text | 值(複雜值以 JSON 字串存放) |
|
||||
| `updated_at` | integer (timestamp_ms) | |
|
||||
|
||||
種子 keys:
|
||||
- 公司:`company_name`, `company_short_name`, `license_no`, `phone`, `whatsapp`, `email`, `address`, `facebook_url`
|
||||
- Hero:`hero_eyebrow`, `hero_title`, `hero_subtitle`, `hero_primary_cta`, `hero_secondary_cta`, `hero_image`
|
||||
- SEO:`seo_default_title`, `seo_default_description`, `og_image`
|
||||
- 信任列:`trust_stats`(JSON 陣列)
|
||||
|
||||
### 3.3 `content_items`(新增,重複內容)
|
||||
|
||||
| 欄位 | 型別 | 說明 |
|
||||
|---|---|---|
|
||||
| `id` | text PK | UUID |
|
||||
| `kind` | text | `service` \| `feature` \| `step` \| `faq` |
|
||||
| `title` | text | 服務名 / 特色名 / 步驟名 / 問題 |
|
||||
| `description` | text | 描述 / 答案 |
|
||||
| `extra` | text | 可選(icon 名、步驟編號等) |
|
||||
| `sort_order` | integer | 排序 |
|
||||
| `status` | text | `draft` \| `published` |
|
||||
| `updated_at` | integer (timestamp_ms) | |
|
||||
|
||||
- `service`:首頁服務卡(村屋太陽能相關)
|
||||
- `feature`:為何揀我哋
|
||||
- `step`:專業安裝流程(extra 放 `01`–`05`)
|
||||
- `faq`:常見問題
|
||||
|
||||
### 3.4 `cases`(新增,完成案例)
|
||||
|
||||
| 欄位 | 型別 | 說明 |
|
||||
|---|---|---|
|
||||
| `id` | text PK | UUID |
|
||||
| `title` | text | 例:大埔上碗窯 - 雙玻光伏板 航空鋁支架 |
|
||||
| `location` | text | 例:大埔半山 |
|
||||
| `completed_at` | text | 例:2026年2月 |
|
||||
| `description` | text | |
|
||||
| `image_url` | text | 佔位圖 URL |
|
||||
| `sort_order` | integer | |
|
||||
| `status` | text | `draft` \| `published` |
|
||||
| `updated_at` | integer (timestamp_ms) | |
|
||||
|
||||
索引:`content_items(kind, status, sort_order)`、`cases(status, sort_order)`、`posts(status, published_at)`。
|
||||
|
||||
---
|
||||
|
||||
## 4. 路由與頁面
|
||||
|
||||
| 路徑 | 渲染 | 內容 |
|
||||
|---|---|---|
|
||||
| `/` | SSR | 一頁式官網 |
|
||||
| `/blog` | SSR | 文章卡片列表 |
|
||||
| `/blog/[slug]` | SSR | 文章頁(Markdown) |
|
||||
| `/admin` | SSR | 儀表板:文章列表 + 內容管理入口 |
|
||||
| `/admin/login` | SSR | 登入 |
|
||||
| `/admin/logout` | SSR | 登出 |
|
||||
| `/admin/post/[id]` | SSR | 新增/編輯文章 |
|
||||
| `/admin/settings` | SSR | 公司 / 聯絡 / Hero / SEO 設定 |
|
||||
| `/admin/content/[kind]` | SSR | 通用編輯器(service/feature/step/faq) |
|
||||
| `/admin/cases` | SSR | 案例列表 |
|
||||
| `/admin/cases/[id]` | SSR | 新增/編輯案例 |
|
||||
| `/sitemap.xml` | SSR | 動態 |
|
||||
| `/robots.txt` | 靜態 | |
|
||||
|
||||
### 4.1 首頁 section 順序
|
||||
|
||||
1. **Header**(sticky,玻璃感):Logo/公司名、錨點導覽(服務、案例、流程、常見問題、Blog)、WhatsApp CTA;手機版 hamburger drawer
|
||||
2. **Hero**:眉題、主標題、副標、雙 CTA、主視覺圖、信任子彈點
|
||||
3. **信任列**:電業承辦商牌照號、服務年資/案例數、客戶口碑
|
||||
4. **服務**(村屋為主,3–4 卡)
|
||||
5. **為何揀我哋**(feature,6 卡)
|
||||
6. **專業安裝流程**(5 步 timeline)
|
||||
7. **完成案例**(案例卡 + 圖)
|
||||
8. **FAQ**(accordion)
|
||||
9. **聯絡 CTA**:電話 / WhatsApp / Email / 地址
|
||||
10. **Footer**
|
||||
11. **浮動 WhatsApp 掣**
|
||||
|
||||
### 4.2 Blog
|
||||
|
||||
- 列表:卡片(封面圖、標題、摘要、日期),空狀態
|
||||
- 文章頁:封面、標題、日期、Markdown prose、返回連結、SEO/OG
|
||||
|
||||
---
|
||||
|
||||
## 5. 設計系統(Chakra theme)
|
||||
|
||||
> **已過時**:2026-09-11 前台改為 editorial 極簡風(暖米白+琥珀金+明體標題),以 `2026-09-11-editorial-redesign-design.md` 為準。以下保留作歷史記錄。
|
||||
|
||||
檔案:`src/theme/system.ts`,用 `createSystem(defaultConfig, defineConfig(...))`。
|
||||
|
||||
### 色彩(清新天藍/綠色系)
|
||||
|
||||
| Token | 值 | 用途 |
|
||||
|---|---|---|
|
||||
| `brand`(主,綠) | `#0B8A5E` 為主,配 50–900 色階 | 主 CTA、標題點綴、標籤 |
|
||||
| `sky`(副,天藍) | `#0BA5EC` / `#38BDF8` | 圖示、裝飾、漸層 |
|
||||
| `bg` 頁面 | `#FFFFFF` | 主背景 |
|
||||
| `bg.subtle` | `#F2F8F6` | 分段背景 |
|
||||
| `fg` | `#0F1E1A` | 正文 |
|
||||
| `fg.muted` | `#5B6B66` | 次要文字 |
|
||||
| `border` | `#E2EDE9` | 卡片描邊 |
|
||||
|
||||
- 漸層:天藍 → 青綠(Hero 裝飾光暈)
|
||||
- 語意 tokens:`bg`, `fg`, `border`, `brand.solid`, `brand.contrast`, `brand.muted`
|
||||
|
||||
### 字體
|
||||
|
||||
- `Noto Sans HK`(fallback:`PingFang HK`, system sans)
|
||||
- 標題:700/800,負字距;內文:400/500,行高 1.75
|
||||
|
||||
### 形狀與動效
|
||||
|
||||
- 卡片:白底、圓角 `2xl`(16–24px)、柔和陰影、細描邊
|
||||
- 按鈕:`brand.solid` 圓角、hover 微加深
|
||||
- 動效:捲動淡入/上移,用 CSS + IntersectionObserver,不引入 framer-motion
|
||||
|
||||
### 圖像
|
||||
|
||||
- 全部先用高質佔位/AI 生成圖,經 `img` URL 提供
|
||||
- 之後可經後台換成真實工程相
|
||||
|
||||
---
|
||||
|
||||
## 6. Admin 功能
|
||||
|
||||
- 沿用 Astro SSR 表單 + HMAC cookie;共用設計 token 的 CSS,令後台風格與前台一致
|
||||
- **文章**:列表 / 新增 / 編輯 / 發布 / 刪除(現有,加封面圖欄)
|
||||
- **設定** `/admin/settings`:公司資料、聯絡、Hero 文案、SEO 預設(分組表單)
|
||||
- **內容** `/admin/content/[kind]`:通用編輯器,支援新增/編輯/刪除/上下排序;以 `kind` 切換 service/feature/step/faq
|
||||
- **案例** `/admin/cases`:列表 + 編輯(含圖片 URL、地點、日期)
|
||||
|
||||
### 內容更新即時生效
|
||||
|
||||
- Admin 儲存 → 首頁 SSR 讀 D1(最長 60 秒邊緣快取後更新)
|
||||
- (可選)儲存時 bump `CACHE` 內的 `content_version`,於 SSR 檢查以提早失效
|
||||
|
||||
---
|
||||
|
||||
## 7. SEO / 效能
|
||||
|
||||
- 沿用 `Base.astro` 的 canonical / OG / Twitter card;補上 `cover_image` 作 `og:image`
|
||||
- `sitemap.xml` 加入 `/`、`/blog`、各文章
|
||||
- `robots.txt` disallow `/admin`
|
||||
- 首頁 SSR + s-maxage 邊緣快取
|
||||
- 圖片 lazy load、`loading="lazy"`、尺寸標註
|
||||
- 目標:Lighthouse SEO/Performance/Accessibility 良好
|
||||
|
||||
---
|
||||
|
||||
## 8. 部署(Cloudflare)
|
||||
|
||||
```bash
|
||||
npx astro add react
|
||||
npm i @chakra-ui/react @emotion/react
|
||||
|
||||
npx wrangler d1 create yingfung-solar-db # 將 database_id 填入 wrangler.jsonc
|
||||
npx wrangler kv namespace create CACHE # 將 id 填入 wrangler.jsonc
|
||||
npm run db:generate
|
||||
npm run db:migrate # 雲端
|
||||
npm run db:migrate:local # 本機
|
||||
npx wrangler secret put ADMIN_PASSWORD
|
||||
|
||||
# 更新 astro.config.mjs site、src/config.ts、wrangler.jsonc vars
|
||||
npm run deploy
|
||||
```
|
||||
|
||||
- 需更新 `wrangler.jsonc` 的 `name`、`vars.SITE_NAME` 為盈豐太陽能
|
||||
- `astro.config.mjs` 的 `site` 待客戶提供真域名
|
||||
|
||||
---
|
||||
|
||||
## 9. 分階段實作
|
||||
|
||||
1. **基建**:加 React + Chakra + Provider、theme、換 Base layout、驗證 SSR 樣式
|
||||
2. **首頁 UI**:全部 section 組件(先佔位內容)
|
||||
3. **資料層**:schema 擴充 + migration + seed(公司資料 + 樣本內容)
|
||||
4. **Blog UI**:列表 + 文章頁翻新
|
||||
5. **Admin**:settings / content items / cases 編輯器
|
||||
6. **SEO / 效能**:sitemap、快取、Lighthouse
|
||||
7. **部署**:D1/KV/secret、上線
|
||||
|
||||
---
|
||||
|
||||
## 10. 風險與對策
|
||||
|
||||
| 風險 | 對策 |
|
||||
|---|---|
|
||||
| Chakra v3 + Astro SSR 樣式注入 | **已實測通過**(見 §2.3);Astro 7 + React 19 + Chakra 3.37 無 hydration error |
|
||||
| Astro 7 與 `@astrojs/react` / React 19 版本相容 | 用 `npx astro add react` 自動配對版本 |
|
||||
| 多個 island 造成 Provider 重複 | 每頁只一個 React root island |
|
||||
| 佔位圖版權 | 使用可商用來源或 AI 生成 |
|
||||
| 接觸點資訊未齊 | 全部放 `site_settings`,客戶可於後台自行更新 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 待客戶提供
|
||||
|
||||
- 真實電話 / WhatsApp 號碼
|
||||
- 聯絡 Email
|
||||
- 辦公地址
|
||||
- 電業承辦商牌照號碼
|
||||
- 真域名
|
||||
- 真實工程相片(可後補)
|
||||
Reference in New Issue
Block a user