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)
|
||||
Reference in New Issue
Block a user