first commit

This commit is contained in:
2026-09-11 15:49:41 +08:00
commit 5b69bc818a
98 changed files with 30551 additions and 0 deletions
@@ -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 islandChakra UI v3Emotion)負責前台 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 systemtokens/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 FontsNoto 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 716: Sections
**Files:** Create 各 section 元件(見檔案結構)
每個 section 一個 task,包含:完整 Chakra markup、響應式、內容 props、設計(清新天藍/綠)。
- [ ] Headersticky、玻璃感、手機 drawer、錨點導覽、WhatsApp CTA
- [ ] Hero(眉題/標題/副標/雙 CTA/主視覺圖/信任子彈)
- [ ] TrustBar(牌照號、案例數、口碑)
- [ ] Services(卡片 grid
- [ ] Features6 卡)
- [ ] Process5 步 timeline
- [ ] Cases(案例卡 + 圖)
- [ ] FaqAccordion
- [ ] ContactCtaWhatsApp/電話/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 errorRWD 檢查
---
## 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 1922
- [ ] `/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 2324
- [ ] 更新 `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)