commit 5b69bc818ae7f0a8c4078511897af629d8c61c07 Author: philipcheung Date: Fri Sep 11 15:49:41 2026 +0800 first commit diff --git a/.astro/content.d.ts b/.astro/content.d.ts new file mode 100644 index 0000000..2bf13df --- /dev/null +++ b/.astro/content.d.ts @@ -0,0 +1,159 @@ +declare module 'astro:content' { + export interface RenderResult { + Content: import('astro/runtime/server/index.js').AstroComponentFactory; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + } + interface Render { + '.md': Promise; + } + + export interface RenderedContent { + html: string; + metadata?: { + imagePaths: Array; + [key: string]: unknown; + }; + } + + type Flatten = T extends { [K: string]: infer U } ? U : never; + + export type CollectionKey = keyof DataEntryMap; + export type CollectionEntry = Flatten; + + type AllValuesOf = T extends any ? T[keyof T] : never; + + export type ReferenceDataEntry< + C extends CollectionKey, + E extends keyof DataEntryMap[C] = string, + > = { + collection: C; + id: E; + }; + + export type ReferenceLiveEntry = { + collection: C; + id: string; + }; + + export function getCollection>( + collection: C, + filter?: (entry: CollectionEntry) => entry is E, + ): Promise; + export function getCollection( + collection: C, + filter?: (entry: CollectionEntry) => unknown, + ): Promise[]>; + + export function getLiveCollection( + collection: C, + filter?: LiveLoaderCollectionFilterType, + ): Promise< + import('astro').LiveDataCollectionResult, LiveLoaderErrorType> + >; + + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + entry: ReferenceDataEntry, + ): E extends keyof DataEntryMap[C] + ? Promise + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + collection: C, + id: E, + ): E extends keyof DataEntryMap[C] + ? string extends keyof DataEntryMap[C] + ? Promise | undefined + : Promise + : Promise | undefined>; + export function getLiveEntry( + collection: C, + filter: string | LiveLoaderEntryFilterType, + ): Promise, LiveLoaderErrorType>>; + + /** Resolve an array of entry references from the same collection */ + export function getEntries( + entries: ReferenceDataEntry[], + ): Promise[]>; + + export function render( + entry: DataEntryMap[C][string], + ): Promise; + + export function render( + entry: import('astro').LiveDataEntry>, + ): Promise; + + export function reference< + C extends + | keyof DataEntryMap + // Allow generic `string` to avoid excessive type errors in the config + // if `dev` is not running to update as you edit. + // Invalid collection names will be caught at build time. + | (string & {}), + >( + collection: C, + ): import('astro/zod').ZodPipe< + import('astro/zod').ZodString, + import('astro/zod').ZodTransform< + C extends keyof DataEntryMap + ? { + collection: C; + id: string; + } + : never, + string + > + >; + + type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; + type InferEntrySchema = import('astro/zod').infer< + ReturnTypeOrOriginal['schema']> + >; + type ExtractLoaderConfig = T extends { loader: infer L } ? L : never; + type InferLoaderSchema< + C extends keyof DataEntryMap, + L = ExtractLoaderConfig, + > = L extends { schema: import('astro/zod').ZodSchema } + ? import('astro/zod').infer + : any; + + type DataEntryMap = { + + }; + + type ExtractLoaderTypes = T extends import('astro/loaders').LiveLoader< + infer TData, + infer TEntryFilter, + infer TCollectionFilter, + infer TError + > + ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError } + : { data: never; entryFilter: never; collectionFilter: never; error: never }; + type ExtractEntryFilterType = ExtractLoaderTypes['entryFilter']; + type ExtractCollectionFilterType = ExtractLoaderTypes['collectionFilter']; + type ExtractErrorType = ExtractLoaderTypes['error']; + type ExtractDataType = ExtractLoaderTypes['data']; + + type LiveLoaderDataType = + LiveContentConfig['collections'][C]['schema'] extends undefined + ? ExtractDataType + : import('astro/zod').infer< + Exclude + >; + type LiveLoaderEntryFilterType = + ExtractEntryFilterType; + type LiveLoaderCollectionFilterType = + ExtractCollectionFilterType; + type LiveLoaderErrorType = ExtractErrorType< + LiveContentConfig['collections'][C]['loader'] + >; + + export type ContentConfig = never; + export type LiveContentConfig = never; +} diff --git a/.astro/dev.json b/.astro/dev.json new file mode 100644 index 0000000..a148f3d --- /dev/null +++ b/.astro/dev.json @@ -0,0 +1,14 @@ +{ + "pid": 27812, + "port": 4321, + "url": "http://localhost:4321", + "urls": { + "local": [ + "http://localhost:4321/" + ], + "network": [], + "networkInterfaceNames": [] + }, + "background": true, + "startedAt": "2026-09-11T07:43:31.316Z" +} \ No newline at end of file diff --git a/.astro/integrations/_astrojs_cloudflare/cloudflare.d.ts b/.astro/integrations/_astrojs_cloudflare/cloudflare.d.ts new file mode 100644 index 0000000..de11b8b --- /dev/null +++ b/.astro/integrations/_astrojs_cloudflare/cloudflare.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/.astro/settings.json b/.astro/settings.json new file mode 100644 index 0000000..885b981 --- /dev/null +++ b/.astro/settings.json @@ -0,0 +1,5 @@ +{ + "_variables": { + "lastUpdateCheck": 1789106959098 + } +} \ No newline at end of file diff --git a/.astro/types.d.ts b/.astro/types.d.ts new file mode 100644 index 0000000..d95e66d --- /dev/null +++ b/.astro/types.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// \ No newline at end of file diff --git a/.dev.vars.example b/.dev.vars.example new file mode 100644 index 0000000..71b3175 --- /dev/null +++ b/.dev.vars.example @@ -0,0 +1 @@ +ADMIN_PASSWORD=改成你自己嘅密碼 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf05629 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +.wrangler/ +.dev.vars +*.log +.DS_Store diff --git a/.playwright-mcp/blog.png b/.playwright-mcp/blog.png new file mode 100644 index 0000000..0136cae Binary files /dev/null and b/.playwright-mcp/blog.png differ diff --git a/.playwright-mcp/cases.png b/.playwright-mcp/cases.png new file mode 100644 index 0000000..db23d6e Binary files /dev/null and b/.playwright-mcp/cases.png differ diff --git a/.playwright-mcp/cta.png b/.playwright-mcp/cta.png new file mode 100644 index 0000000..56fa752 Binary files /dev/null and b/.playwright-mcp/cta.png differ diff --git a/.playwright-mcp/faq.png b/.playwright-mcp/faq.png new file mode 100644 index 0000000..d0fbc77 Binary files /dev/null and b/.playwright-mcp/faq.png differ diff --git a/.playwright-mcp/features.png b/.playwright-mcp/features.png new file mode 100644 index 0000000..7873109 Binary files /dev/null and b/.playwright-mcp/features.png differ diff --git a/.playwright-mcp/footer-fixed.png b/.playwright-mcp/footer-fixed.png new file mode 100644 index 0000000..0eb74b0 Binary files /dev/null and b/.playwright-mcp/footer-fixed.png differ diff --git a/.playwright-mcp/footer.png b/.playwright-mcp/footer.png new file mode 100644 index 0000000..5c3f4ab Binary files /dev/null and b/.playwright-mcp/footer.png differ diff --git a/.playwright-mcp/hero.png b/.playwright-mcp/hero.png new file mode 100644 index 0000000..0ec6042 Binary files /dev/null and b/.playwright-mcp/hero.png differ diff --git a/.playwright-mcp/mobile-drawer.png b/.playwright-mcp/mobile-drawer.png new file mode 100644 index 0000000..1174233 Binary files /dev/null and b/.playwright-mcp/mobile-drawer.png differ diff --git a/.playwright-mcp/mobile-hero.png b/.playwright-mcp/mobile-hero.png new file mode 100644 index 0000000..4ea1661 Binary files /dev/null and b/.playwright-mcp/mobile-hero.png differ diff --git a/.playwright-mcp/page-2026-09-11T07-29-18-715Z.yml b/.playwright-mcp/page-2026-09-11T07-29-18-715Z.yml new file mode 100644 index 0000000..4c46fbc --- /dev/null +++ b/.playwright-mcp/page-2026-09-11T07-29-18-715Z.yml @@ -0,0 +1,238 @@ +- generic [active] [ref=f22e1]: + - generic [ref=f22e2]: + - banner [ref=f22e3]: + - generic [ref=f22e5]: + - link [ref=f22e6] [cursor=pointer]: + - /url: / + - paragraph [ref=f22e7]: 盈豐太陽能 + - button "開啟選單" [ref=f22e9] [cursor=pointer] + - main [ref=f22e11]: + - generic [ref=f22e14]: + - generic [ref=f22e15]: + - paragraph [ref=f22e18]: 香港村屋太陽能專家 + - heading "善用村屋天台 發電慳電賺回報" [level=1] [ref=f22e19] + - paragraph [ref=f22e20]: 由現場評估、方案建議、安裝施工,到申請同跟進,我哋用清晰易明嘅方式,陪你完成整個村屋太陽能項目。 + - generic [ref=f22e21]: + - link "免費預約評估" [ref=f22e22] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "睇完成案例" [ref=f22e25] [cursor=pointer]: + - /url: "#cases" + - generic [ref=f22e28]: + - paragraph [ref=f22e33]: 註冊電業承辦商 + - paragraph [ref=f22e38]: 舊客口碑介紹 + - paragraph [ref=f22e43]: 一對一專人跟進 + - generic [ref=f22e44]: + - img "村屋天台太陽能系統" [ref=f22e45] + - generic [ref=f22e46]: + - generic [ref=f22e47]: + - paragraph [ref=f22e48]: 一般回本期 + - paragraph [ref=f22e49]: 約 6–9 年 + - generic [ref=f22e50]: + - paragraph [ref=f22e51]: 系統可用年期 + - paragraph [ref=f22e52]: 20–25 年 + - generic [ref=f22e53]: + - paragraph [ref=f22e54]: 牌照 + - paragraph [ref=f22e55]: 電業承辦商編號:待填 + - generic [ref=f22e58]: + - generic [ref=f22e64]: + - paragraph [ref=f22e65]: 註冊電業承辦商 + - paragraph [ref=f22e66]: 合資格承辦,安全合法 + - generic [ref=f22e73]: + - paragraph [ref=f22e74]: 上網電價 FiT 代辦 + - paragraph [ref=f22e75]: 中電/港燈申請全程跟進 + - generic [ref=f22e81]: + - paragraph [ref=f22e82]: 認可人士 AP 簽發 + - paragraph [ref=f22e83]: C/PVS、WR1、GF1 文件 + - generic [ref=f22e89]: + - paragraph [ref=f22e90]: 20–25 年系統壽命 + - paragraph [ref=f22e91]: 優質器材,長遠穩定 + - generic [ref=f22e93]: + - generic [ref=f22e94]: + - paragraph [ref=f22e97]: 服務範圍 + - heading "專為村屋而設嘅太陽能方案" [level=2] [ref=f22e98] + - paragraph [ref=f22e99]: 由天台評估到掛表發電,我哋提供真正一站式嘅村屋太陽能服務。 + - generic [ref=f22e100]: + - group [ref=f22e101]: + - paragraph [ref=f22e102]: "01" + - heading "村屋天台太陽能系統" [level=3] [ref=f22e103] + - paragraph [ref=f22e104]: 善用村屋天台空間,安裝高效太陽能板,將閒置天台變成穩定收入來源。 + - group [ref=f22e105]: + - paragraph [ref=f22e106]: "02" + - heading "合法合規支架工程" [level=3] [ref=f22e107] + - paragraph [ref=f22e108]: 按村屋結構同法規設計鋁合金支架,穩固耐用,確保合乎相關要求。 + - group [ref=f22e109]: + - paragraph [ref=f22e110]: "03" + - heading "代辦申請及文件" [level=3] [ref=f22e111] + - paragraph [ref=f22e112]: 由中電/港燈申請、上網電價計劃(FiT)到相關政府文件,全程代辦。 + - group [ref=f22e113]: + - paragraph [ref=f22e114]: "04" + - heading "專業安裝及驗收" [level=3] [ref=f22e115] + - paragraph [ref=f22e116]: 由認可人士(AP)及註冊電工施工,簽發所需認證文件,安全合法。 + - group [ref=f22e117]: + - paragraph [ref=f22e118]: "05" + - heading "降低頂樓室溫" [level=3] [ref=f22e119] + - paragraph [ref=f22e120]: 太陽能板為天台遮蔭,有效降低頂樓單位溫度,同時慳冷氣電費。 + - group [ref=f22e121]: + - paragraph [ref=f22e122]: "06" + - heading "收益及回本分析" [level=3] [ref=f22e123] + - paragraph [ref=f22e124]: 按日照、面積同電價,提供清晰嘅發電量同回本估算,一目了然。 + - generic [ref=f22e126]: + - generic [ref=f22e127]: + - paragraph [ref=f22e130]: 點解揀我哋 + - heading "結合專業工程同貼心溝通" [level=2] [ref=f22e131] + - paragraph [ref=f22e132]: 我哋唔止做工程,仲重視你由頭到尾嘅體驗同安心。 + - generic [ref=f22e133]: + - generic [ref=f22e134]: + - paragraph [ref=f22e135]: "01" + - heading "熟悉香港村屋環境" [level=3] [ref=f22e136] + - paragraph [ref=f22e137]: 深耕本地市場,充分掌握村屋結構、法規同地理限制。 + - generic [ref=f22e138]: + - paragraph [ref=f22e139]: "02" + - heading "流程清晰易明" [level=3] [ref=f22e140] + - paragraph [ref=f22e141]: 用最簡單直白嘅方式解說回本期同技術細節,絕無花巧術語。 + - generic [ref=f22e142]: + - paragraph [ref=f22e143]: "03" + - heading "專人快速跟進" [level=3] [ref=f22e144] + - paragraph [ref=f22e145]: 一對一顧問服務,由評估到完工全程透明,隨時解答疑問。 + - generic [ref=f22e146]: + - paragraph [ref=f22e147]: "04" + - heading "美觀與效率兼備" [level=3] [ref=f22e148] + - paragraph [ref=f22e149]: 追求發電效率之餘,極致重視施工整齊度同建築美感。 + - generic [ref=f22e150]: + - paragraph [ref=f22e151]: "05" + - heading "重視施工安全" [level=3] [ref=f22e152] + - paragraph [ref=f22e153]: 嚴選耐用器材、嚴格執行安全程序,確保系統長久穩定。 + - generic [ref=f22e154]: + - paragraph [ref=f22e155]: "06" + - heading "不硬銷真誠建議" [level=3] [ref=f22e156] + - paragraph [ref=f22e157]: 先幫你了解安裝可行性,未必即刻做,最緊要係問清楚。 + - generic [ref=f22e159]: + - generic [ref=f22e160]: + - paragraph [ref=f22e163]: 服務流程 + - heading "專業安裝流程 5 步到位" [level=2] [ref=f22e164] + - paragraph [ref=f22e165]: 清晰透明嘅流程,每一步都有專人跟進,你唔需要自己四圍撲。 + - generic [ref=f22e167]: + - generic [ref=f22e168]: + - generic [ref=f22e169]: "01" + - paragraph [ref=f22e170]: 初步諮詢 / 現場評估 + - paragraph [ref=f22e171]: 專人上門視察環境,提供專業技術建議。 + - generic [ref=f22e172]: + - generic [ref=f22e173]: "02" + - paragraph [ref=f22e174]: 申請文件處理 + - paragraph [ref=f22e175]: 代辦電力公司同政府部門所需嘅申請文件。 + - generic [ref=f22e176]: + - generic [ref=f22e177]: "03" + - paragraph [ref=f22e178]: 安裝施工 + - paragraph [ref=f22e179]: 專業團隊進場施工,確保工期同施工品質安全。 + - generic [ref=f22e180]: + - generic [ref=f22e181]: "04" + - paragraph [ref=f22e182]: 驗收認證 + - paragraph [ref=f22e183]: 由認可人士及合資格電工簽發 C/PVS、WR1、GF1 等文件。 + - generic [ref=f22e184]: + - generic [ref=f22e185]: "05" + - paragraph [ref=f22e186]: 掛表正式發電 + - paragraph [ref=f22e187]: 電力公司掛上電表後,正式開始享受太陽能發電收益。 + - generic [ref=f22e189]: + - generic [ref=f22e190]: + - paragraph [ref=f22e193]: 完成案例 + - heading "真實村屋工程案例" [level=2] [ref=f22e194] + - paragraph [ref=f22e195]: 我哋為香港各區村屋提供專業太陽能方案,累積豐富施工經驗。 + - generic [ref=f22e196]: + - group [ref=f22e197]: + - img "大埔上碗窯 — 雙玻光伏板 航空鋁支架" [ref=f22e199] + - generic [ref=f22e200]: + - generic [ref=f22e201]: + - paragraph [ref=f22e202]: 2026年2月 + - paragraph [ref=f22e207]: 大埔半山 + - heading "大埔上碗窯 — 雙玻光伏板 航空鋁支架" [level=3] [ref=f22e208] + - paragraph [ref=f22e209]: 採用雙玻光伏板配航空級鋁合金支架,兼顧發電效率同天台景觀。 + - generic [ref=f22e210]: + - group [ref=f22e211]: + - img "元朗山下村 — 香檳色鋁合金支架" [ref=f22e213] + - generic [ref=f22e214]: + - paragraph [ref=f22e215]: 2025年7月 + - paragraph [ref=f22e220]: 元朗屏山 + - heading "元朗山下村 — 香檳色鋁合金支架" [level=3] [ref=f22e221] + - paragraph [ref=f22e222]: 香檳色支架配合村屋外牆色調,施工整齊,發電穩定。 + - group [ref=f22e223]: + - img "西貢西澳村 — 焗白色鋁合金支架" [ref=f22e225] + - generic [ref=f22e226]: + - paragraph [ref=f22e227]: 2025年5月 + - paragraph [ref=f22e232]: 新界西貢 + - heading "西貢西澳村 — 焗白色鋁合金支架" [level=3] [ref=f22e233] + - paragraph [ref=f22e234]: 焗白色支架低調美觀,善用天台每一寸可用空間。 + - generic [ref=f22e236]: + - generic [ref=f22e237]: + - paragraph [ref=f22e240]: 常見問題 + - heading "安裝前,你可能想知嘅事" [level=2] [ref=f22e241] + - paragraph [ref=f22e242]: 仲有其他疑問?歡迎隨時 WhatsApp 問我哋。 + - generic [ref=f22e244]: + - generic [ref=f22e245]: + - button [expanded] [ref=f22e246]: + - paragraph [ref=f22e247]: 村屋天台可以安裝太陽能嗎? + - region "村屋天台可以安裝太陽能嗎?" [ref=f22e250]: + - generic [ref=f22e251]: 大部分村屋天台都可以。我哋會先上門評估結構、日照同遮擋情況,再判斷可行性同建議方案。 + - button [ref=f22e253]: + - paragraph [ref=f22e254]: 安裝太陽能大概幾錢?幾時回本? + - button [ref=f22e258]: + - paragraph [ref=f22e259]: 需要幾大天台面積? + - button [ref=f22e263]: + - paragraph [ref=f22e264]: 安裝太陽能合唔合法?會唔會影響樓宇結構? + - button [ref=f22e268]: + - paragraph [ref=f22e269]: 系統需要保養嗎? + - button [ref=f22e273]: + - paragraph [ref=f22e274]: 申請上網電價(FiT)麻煩嗎? + - generic [ref=f22e279]: + - generic [ref=f22e280]: + - paragraph [ref=f22e283]: 免費評估 + - heading "立即預約免費評估" [level=2] [ref=f22e284] + - paragraph [ref=f22e285]: 想知你嘅村屋天台啱唔啱裝太陽能?歡迎 WhatsApp 或致電,我哋會用清晰易明嘅方式為你詳答。 + - generic [ref=f22e286]: + - link "WhatsApp 查詢" [ref=f22e287] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "致電我哋" [ref=f22e290] [cursor=pointer]: + - /url: tel:+85200000000 + - generic [ref=f22e293]: + - paragraph [ref=f22e298]: +852 0000 0000 + - paragraph [ref=f22e304]: info@yingfungsolar.hk + - paragraph [ref=f22e310]: 香港新界(地址待填) + - contentinfo [ref=f22e311]: + - generic [ref=f22e312]: + - generic [ref=f22e313]: + - generic [ref=f22e314]: + - paragraph [ref=f22e315]: 盈豐太陽能 + - paragraph [ref=f22e316]: 專營香港村屋太陽能系統,由評估、設計、申請到安裝驗收,一站式為你善用天台,賺取發電回報。 + - paragraph [ref=f22e317]: 電業承辦商編號:待填 + - generic [ref=f22e318]: + - generic [ref=f22e319]: + - paragraph [ref=f22e320]: 快速連結 + - link "服務範圍" [ref=f22e321] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f22e322] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f22e323] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f22e324] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f22e325] [cursor=pointer]: + - /url: /blog + - generic [ref=f22e326]: + - paragraph [ref=f22e327]: 聯絡我哋 + - link "+852 0000 0000" [ref=f22e331] [cursor=pointer]: + - /url: tel:+85200000000 + - link "WhatsApp" [ref=f22e335] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "info@yingfungsolar.hk" [ref=f22e340] [cursor=pointer]: + - /url: mailto:info@yingfungsolar.hk?subject=%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D + - paragraph [ref=f22e345]: 香港新界(地址待填) + - generic [ref=f22e347]: + - paragraph [ref=f22e348]: © 2026 盈豐太陽能工程有限公司 All rights reserved. + - link "管理後台" [ref=f22e349] [cursor=pointer]: + - /url: /admin + - link "WhatsApp 查詢" [ref=f22e350] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - generic [ref=f22e355]: + - button [ref=f22e356] + - button [ref=f22e362] + - button [ref=f22e366] + - button [ref=f22e371] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-09-11T07-41-09-330Z.yml b/.playwright-mcp/page-2026-09-11T07-41-09-330Z.yml new file mode 100644 index 0000000..574e383 --- /dev/null +++ b/.playwright-mcp/page-2026-09-11T07-41-09-330Z.yml @@ -0,0 +1,77 @@ +- generic [active] [ref=f23e1]: + - generic [ref=f23e2]: + - banner [ref=f23e3]: + - generic [ref=f23e5]: + - link [ref=f23e6] [cursor=pointer]: + - /url: / + - paragraph [ref=f23e7]: 盈豐太陽能 + - paragraph [ref=f23e8]: 電業承辦商編號:待填 + - generic [ref=f23e9]: + - link "服務" [ref=f23e10] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f23e11] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f23e12] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f23e13] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f23e14] [cursor=pointer]: + - /url: /blog + - generic [ref=f23e15]: + - link "+852 0000 0000" [ref=f23e16] [cursor=pointer]: + - /url: tel:+85200000000 + - link "免費諮詢" [ref=f23e19] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - main [ref=f23e22]: + - generic [ref=f23e23]: + - generic [ref=f23e24]: + - paragraph [ref=f23e27]: BLOG + - heading "太陽能知識庫" [level=1] [ref=f23e28] + - paragraph [ref=f23e29]: 村屋太陽能嘅實用資訊、安裝心得同回本分析,幫你更了解點樣善用天台。 + - group [ref=f23e31] [cursor=pointer]: + - img "村屋安裝太陽能前,你要知嘅 5 件事" [ref=f23e33] + - generic [ref=f23e34]: + - generic [ref=f23e35]: 2026年9月11日 + - heading "村屋安裝太陽能前,你要知嘅 5 件事" [level=2] [ref=f23e38] + - paragraph [ref=f23e39]: 想喺村屋天台裝太陽能?由天台面積、日照、支架法規到回本期,呢篇幫你一次過搞清楚。 + - paragraph [ref=f23e40]: 閱讀更多 + - contentinfo [ref=f23e43]: + - generic [ref=f23e44]: + - generic [ref=f23e45]: + - generic [ref=f23e46]: + - paragraph [ref=f23e47]: 盈豐太陽能 + - paragraph [ref=f23e48]: 專營香港村屋太陽能系統,由評估、設計、申請到安裝驗收,一站式為你善用天台,賺取發電回報。 + - paragraph [ref=f23e49]: 電業承辦商編號:待填 + - generic [ref=f23e50]: + - generic [ref=f23e51]: + - paragraph [ref=f23e52]: 快速連結 + - link "服務範圍" [ref=f23e53] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f23e54] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f23e55] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f23e56] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f23e57] [cursor=pointer]: + - /url: /blog + - generic [ref=f23e58]: + - paragraph [ref=f23e59]: 聯絡我哋 + - link "+852 0000 0000" [ref=f23e63] [cursor=pointer]: + - /url: tel:+85200000000 + - link "WhatsApp" [ref=f23e67] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "info@yingfungsolar.hk" [ref=f23e72] [cursor=pointer]: + - /url: mailto:info@yingfungsolar.hk?subject=%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D + - paragraph [ref=f23e77]: 香港新界(地址待填) + - generic [ref=f23e79]: + - paragraph [ref=f23e80]: © 2026 盈豐太陽能工程有限公司 All rights reserved. + - link "管理後台" [ref=f23e81] [cursor=pointer]: + - /url: /admin + - link "WhatsApp 查詢" [ref=f23e82] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - generic [ref=f23e87]: + - button [ref=f23e88] + - button [ref=f23e94] + - button [ref=f23e98] + - button [ref=f23e103] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-09-11T07-42-44-448Z.yml b/.playwright-mcp/page-2026-09-11T07-42-44-448Z.yml new file mode 100644 index 0000000..c353fa7 --- /dev/null +++ b/.playwright-mcp/page-2026-09-11T07-42-44-448Z.yml @@ -0,0 +1,14 @@ +- generic [ref=f25e3]: + - generic [ref=f25e4]: + - checkbox "Use dark theme" [ref=f25e5] + - generic [ref=f25e6] [cursor=pointer]: Use dark theme + - banner [ref=f25e16]: + - generic [ref=f25e17]: + - heading [level=2] + - heading "An error occurred." [level=1] [ref=f25e18] + - generic [ref=f25e24]: "The file does not exist at \"/Users/philipcheung/Documents/projects/yingfungsolar/node_modules/.vite/deps_ssr/marked.js?v=c35ab5a8\" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`." + - generic [ref=f25e30]: + - generic [ref=f25e31]: + - heading "Stack Trace" [level=2] [ref=f25e32] + - generic [ref=f25e33] [cursor=pointer] + - generic [ref=f25e38]: at runInRunnerObject (workers/runner-worker/index.js:107:3) at Object.getComponentByRoute (/Users/philipcheung/Documents/projects/yingfungsolar/node_modules/astro/dist/core/environment/dev-nonrunnable.js:48:10) at matchRoute (/Users/philipcheung/Documents/projects/yingfungsolar/node_modules/astro/dist/core/routing/dev.js:31:14) at DevFacadeApp.devMatch (/Users/philipcheung/Documents/projects/yingfungsolar/node_modules/astro/dist/core/app/dev-facade.js:24:26) at Object.handle [as fetch] (/Users/philipcheung/Documents/projects/yingfungsolar/node_modules/@astrojs/cloudflare/dist/utils/handler.js:66:20) at maybeCaptureError (workers/runner-worker/index.js:51:10) \ No newline at end of file diff --git a/.playwright-mcp/page-2026-09-11T07-43-42-407Z.yml b/.playwright-mcp/page-2026-09-11T07-43-42-407Z.yml new file mode 100644 index 0000000..b85c7d9 --- /dev/null +++ b/.playwright-mcp/page-2026-09-11T07-43-42-407Z.yml @@ -0,0 +1,81 @@ +- generic [ref=f27e2]: + - banner [ref=f27e3]: + - generic [ref=f27e5]: + - link [ref=f27e6] [cursor=pointer]: + - /url: / + - paragraph [ref=f27e7]: 盈豐太陽能 + - paragraph [ref=f27e8]: 電業承辦商編號:待填 + - generic [ref=f27e9]: + - link "服務" [ref=f27e10] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f27e11] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f27e12] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f27e13] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f27e14] [cursor=pointer]: + - /url: /blog + - generic [ref=f27e15]: + - link "+852 0000 0000" [ref=f27e16] [cursor=pointer]: + - /url: tel:+85200000000 + - link "免費諮詢" [ref=f27e19] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - main [ref=f27e22]: + - generic [ref=f27e23]: + - link "返去 Blog" [ref=f27e24] [cursor=pointer]: + - /url: /blog + - generic [ref=f27e27]: + - heading "村屋安裝太陽能前,你要知嘅 5 件事" [level=1] [ref=f27e28] + - paragraph [ref=f27e29]: 2026年9月11日 + - img "村屋安裝太陽能前,你要知嘅 5 件事" [ref=f27e32] + - generic [ref=f27e33]: + - paragraph [ref=f27e34]: 村屋天台係香港少數可以合法大規模安裝太陽能嘅地方。不過落決定之前,以下 5 點你一定要知。 + - heading "1. 天台面積有幾大?" [level=2] [ref=f27e35] + - paragraph [ref=f27e36]: 一般每 1 kW 系統約需 60–80 平方呎可用面積。天台有無水箱、樓梯屋或其他遮擋,都會影響實際可安裝容量。 + - heading "2. 日照同遮擋" [level=2] [ref=f27e37] + - paragraph [ref=f27e38]: 向南、無遮擋嘅天台發電表現最好。我哋會用現場評估同工具分析你屋企嘅日照情況。 + - heading "3. 支架要合法合規" [level=2] [ref=f27e39] + - paragraph [ref=f27e40]: 村屋太陽能支架須符合相關法規。專業設計嘅鋁合金支架唔單止穩固,亦確保合乎要求。 + - heading "4. 回本期有幾長?" [level=2] [ref=f27e41] + - paragraph [ref=f27e42]: 一般村屋系統回本期約 6–9 年,之後嘅發電收益基本上係淨賺。實際數字視乎系統容量同電價。 + - heading "5. 邊個幫你申請?" [level=2] [ref=f27e43] + - paragraph [ref=f27e44]: 由中電/港燈嘅上網電價計劃(FiT)到政府文件,我哋會全程代辦,你唔需要自己四圍撲。 + - paragraph [ref=f27e45]: 想知你屋企啱唔啱裝?歡迎 WhatsApp 我哋預約免費評估。 + - link "睇更多文章" [ref=f27e46] [cursor=pointer]: + - /url: /blog + - contentinfo [ref=f27e49]: + - generic [ref=f27e50]: + - generic [ref=f27e51]: + - generic [ref=f27e52]: + - paragraph [ref=f27e53]: 盈豐太陽能 + - paragraph [ref=f27e54]: 專營香港村屋太陽能系統,由評估、設計、申請到安裝驗收,一站式為你善用天台,賺取發電回報。 + - paragraph [ref=f27e55]: 電業承辦商編號:待填 + - generic [ref=f27e56]: + - generic [ref=f27e57]: + - paragraph [ref=f27e58]: 快速連結 + - link "服務範圍" [ref=f27e59] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f27e60] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f27e61] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f27e62] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f27e63] [cursor=pointer]: + - /url: /blog + - generic [ref=f27e64]: + - paragraph [ref=f27e65]: 聯絡我哋 + - link "+852 0000 0000" [ref=f27e69] [cursor=pointer]: + - /url: tel:+85200000000 + - link "WhatsApp" [ref=f27e73] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "info@yingfungsolar.hk" [ref=f27e78] [cursor=pointer]: + - /url: mailto:info@yingfungsolar.hk?subject=%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D + - paragraph [ref=f27e83]: 香港新界(地址待填) + - generic [ref=f27e85]: + - paragraph [ref=f27e86]: © 2026 盈豐太陽能工程有限公司 All rights reserved. + - link "管理後台" [ref=f27e87] [cursor=pointer]: + - /url: /admin + - link "WhatsApp 查詢" [ref=f27e88] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 \ No newline at end of file diff --git a/.playwright-mcp/page-2026-09-11T07-44-13-628Z.yml b/.playwright-mcp/page-2026-09-11T07-44-13-628Z.yml new file mode 100644 index 0000000..cd54c58 --- /dev/null +++ b/.playwright-mcp/page-2026-09-11T07-44-13-628Z.yml @@ -0,0 +1,254 @@ +- generic [active] [ref=f28e1]: + - generic [ref=f28e2]: + - banner [ref=f28e3]: + - generic [ref=f28e5]: + - link [ref=f28e6] [cursor=pointer]: + - /url: / + - paragraph [ref=f28e7]: 盈豐太陽能 + - paragraph [ref=f28e8]: 電業承辦商編號:待填 + - generic [ref=f28e9]: + - link "服務" [ref=f28e10] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f28e11] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f28e12] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f28e13] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f28e14] [cursor=pointer]: + - /url: /blog + - generic [ref=f28e15]: + - link "+852 0000 0000" [ref=f28e16] [cursor=pointer]: + - /url: tel:+85200000000 + - link "免費諮詢" [ref=f28e19] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - main [ref=f28e22]: + - generic [ref=f28e25]: + - generic [ref=f28e26]: + - paragraph [ref=f28e29]: 香港村屋太陽能專家 + - heading "善用村屋天台 發電慳電賺回報" [level=1] [ref=f28e30] + - paragraph [ref=f28e31]: 由現場評估、方案建議、安裝施工,到申請同跟進,我哋用清晰易明嘅方式,陪你完成整個村屋太陽能項目。 + - generic [ref=f28e32]: + - link "免費預約評估" [ref=f28e33] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "睇完成案例" [ref=f28e36] [cursor=pointer]: + - /url: "#cases" + - generic [ref=f28e39]: + - paragraph [ref=f28e44]: 註冊電業承辦商 + - paragraph [ref=f28e49]: 舊客口碑介紹 + - paragraph [ref=f28e54]: 一對一專人跟進 + - generic [ref=f28e55]: + - img "村屋天台太陽能系統" [ref=f28e56] + - generic [ref=f28e57]: + - generic [ref=f28e58]: + - paragraph [ref=f28e59]: 一般回本期 + - paragraph [ref=f28e60]: 約 6–9 年 + - generic [ref=f28e61]: + - paragraph [ref=f28e62]: 系統可用年期 + - paragraph [ref=f28e63]: 20–25 年 + - generic [ref=f28e64]: + - paragraph [ref=f28e65]: 牌照 + - paragraph [ref=f28e66]: 電業承辦商編號:待填 + - generic [ref=f28e69]: + - generic [ref=f28e75]: + - paragraph [ref=f28e76]: 註冊電業承辦商 + - paragraph [ref=f28e77]: 合資格承辦,安全合法 + - generic [ref=f28e84]: + - paragraph [ref=f28e85]: 上網電價 FiT 代辦 + - paragraph [ref=f28e86]: 中電/港燈申請全程跟進 + - generic [ref=f28e92]: + - paragraph [ref=f28e93]: 認可人士 AP 簽發 + - paragraph [ref=f28e94]: C/PVS、WR1、GF1 文件 + - generic [ref=f28e100]: + - paragraph [ref=f28e101]: 20–25 年系統壽命 + - paragraph [ref=f28e102]: 優質器材,長遠穩定 + - generic [ref=f28e104]: + - generic [ref=f28e105]: + - paragraph [ref=f28e108]: 服務範圍 + - heading "專為村屋而設嘅太陽能方案" [level=2] [ref=f28e109] + - paragraph [ref=f28e110]: 由天台評估到掛表發電,我哋提供真正一站式嘅村屋太陽能服務。 + - generic [ref=f28e111]: + - group [ref=f28e112]: + - paragraph [ref=f28e113]: "01" + - heading "村屋天台太陽能系統" [level=3] [ref=f28e114] + - paragraph [ref=f28e115]: 善用村屋天台空間,安裝高效太陽能板,將閒置天台變成穩定收入來源。 + - group [ref=f28e119]: + - paragraph [ref=f28e120]: "02" + - heading "合法合規支架工程" [level=3] [ref=f28e121] + - paragraph [ref=f28e122]: 按村屋結構同法規設計鋁合金支架,穩固耐用,確保合乎相關要求。 + - group [ref=f28e126]: + - paragraph [ref=f28e127]: "03" + - heading "代辦申請及文件" [level=3] [ref=f28e128] + - paragraph [ref=f28e129]: 由中電/港燈申請、上網電價計劃(FiT)到相關政府文件,全程代辦。 + - group [ref=f28e133]: + - paragraph [ref=f28e134]: "04" + - heading "專業安裝及驗收" [level=3] [ref=f28e135] + - paragraph [ref=f28e136]: 由認可人士(AP)及註冊電工施工,簽發所需認證文件,安全合法。 + - group [ref=f28e140]: + - paragraph [ref=f28e141]: "05" + - heading "降低頂樓室溫" [level=3] [ref=f28e142] + - paragraph [ref=f28e143]: 太陽能板為天台遮蔭,有效降低頂樓單位溫度,同時慳冷氣電費。 + - group [ref=f28e147]: + - paragraph [ref=f28e148]: "06" + - heading "收益及回本分析" [level=3] [ref=f28e149] + - paragraph [ref=f28e150]: 按日照、面積同電價,提供清晰嘅發電量同回本估算,一目了然。 + - generic [ref=f28e155]: + - generic [ref=f28e156]: + - paragraph [ref=f28e159]: 點解揀我哋 + - heading "結合專業工程同貼心溝通" [level=2] [ref=f28e160] + - paragraph [ref=f28e161]: 我哋唔止做工程,仲重視你由頭到尾嘅體驗同安心。 + - generic [ref=f28e162]: + - generic [ref=f28e163]: + - paragraph [ref=f28e164]: "01" + - heading "熟悉香港村屋環境" [level=3] [ref=f28e165] + - paragraph [ref=f28e166]: 深耕本地市場,充分掌握村屋結構、法規同地理限制。 + - generic [ref=f28e167]: + - paragraph [ref=f28e168]: "02" + - heading "流程清晰易明" [level=3] [ref=f28e169] + - paragraph [ref=f28e170]: 用最簡單直白嘅方式解說回本期同技術細節,絕無花巧術語。 + - generic [ref=f28e171]: + - paragraph [ref=f28e172]: "03" + - heading "專人快速跟進" [level=3] [ref=f28e173] + - paragraph [ref=f28e174]: 一對一顧問服務,由評估到完工全程透明,隨時解答疑問。 + - generic [ref=f28e175]: + - paragraph [ref=f28e176]: "04" + - heading "美觀與效率兼備" [level=3] [ref=f28e177] + - paragraph [ref=f28e178]: 追求發電效率之餘,極致重視施工整齊度同建築美感。 + - generic [ref=f28e179]: + - paragraph [ref=f28e180]: "05" + - heading "重視施工安全" [level=3] [ref=f28e181] + - paragraph [ref=f28e182]: 嚴選耐用器材、嚴格執行安全程序,確保系統長久穩定。 + - generic [ref=f28e183]: + - paragraph [ref=f28e184]: "06" + - heading "不硬銷真誠建議" [level=3] [ref=f28e185] + - paragraph [ref=f28e186]: 先幫你了解安裝可行性,未必即刻做,最緊要係問清楚。 + - generic [ref=f28e188]: + - generic [ref=f28e189]: + - paragraph [ref=f28e192]: 服務流程 + - heading "專業安裝流程 5 步到位" [level=2] [ref=f28e193] + - paragraph [ref=f28e194]: 清晰透明嘅流程,每一步都有專人跟進,你唔需要自己四圍撲。 + - generic [ref=f28e196]: + - generic [ref=f28e197]: + - generic [ref=f28e198]: "01" + - paragraph [ref=f28e199]: 初步諮詢 / 現場評估 + - paragraph [ref=f28e200]: 專人上門視察環境,提供專業技術建議。 + - generic [ref=f28e201]: + - generic [ref=f28e202]: "02" + - paragraph [ref=f28e203]: 申請文件處理 + - paragraph [ref=f28e204]: 代辦電力公司同政府部門所需嘅申請文件。 + - generic [ref=f28e205]: + - generic [ref=f28e206]: "03" + - paragraph [ref=f28e207]: 安裝施工 + - paragraph [ref=f28e208]: 專業團隊進場施工,確保工期同施工品質安全。 + - generic [ref=f28e209]: + - generic [ref=f28e210]: "04" + - paragraph [ref=f28e211]: 驗收認證 + - paragraph [ref=f28e212]: 由認可人士及合資格電工簽發 C/PVS、WR1、GF1 等文件。 + - generic [ref=f28e213]: + - generic [ref=f28e214]: "05" + - paragraph [ref=f28e215]: 掛表正式發電 + - paragraph [ref=f28e216]: 電力公司掛上電表後,正式開始享受太陽能發電收益。 + - generic [ref=f28e218]: + - generic [ref=f28e219]: + - paragraph [ref=f28e222]: 完成案例 + - heading "真實村屋工程案例" [level=2] [ref=f28e223] + - paragraph [ref=f28e224]: 我哋為香港各區村屋提供專業太陽能方案,累積豐富施工經驗。 + - generic [ref=f28e225]: + - group [ref=f28e226]: + - img "大埔上碗窯 — 雙玻光伏板 航空鋁支架" [ref=f28e228] + - generic [ref=f28e229]: + - generic [ref=f28e230]: + - paragraph [ref=f28e231]: 2026年2月 + - paragraph [ref=f28e236]: 大埔半山 + - heading "大埔上碗窯 — 雙玻光伏板 航空鋁支架" [level=3] [ref=f28e237] + - paragraph [ref=f28e238]: 採用雙玻光伏板配航空級鋁合金支架,兼顧發電效率同天台景觀。 + - generic [ref=f28e239]: + - group [ref=f28e240]: + - img "元朗山下村 — 香檳色鋁合金支架" [ref=f28e242] + - generic [ref=f28e243]: + - paragraph [ref=f28e244]: 2025年7月 + - paragraph [ref=f28e249]: 元朗屏山 + - heading "元朗山下村 — 香檳色鋁合金支架" [level=3] [ref=f28e250] + - paragraph [ref=f28e251]: 香檳色支架配合村屋外牆色調,施工整齊,發電穩定。 + - group [ref=f28e252]: + - img "西貢西澳村 — 焗白色鋁合金支架" [ref=f28e254] + - generic [ref=f28e255]: + - paragraph [ref=f28e256]: 2025年5月 + - paragraph [ref=f28e261]: 新界西貢 + - heading "西貢西澳村 — 焗白色鋁合金支架" [level=3] [ref=f28e262] + - paragraph [ref=f28e263]: 焗白色支架低調美觀,善用天台每一寸可用空間。 + - generic [ref=f28e265]: + - generic [ref=f28e266]: + - paragraph [ref=f28e269]: 常見問題 + - heading "安裝前,你可能想知嘅事" [level=2] [ref=f28e270] + - paragraph [ref=f28e271]: 仲有其他疑問?歡迎隨時 WhatsApp 問我哋。 + - generic [ref=f28e273]: + - generic [ref=f28e274]: + - button [expanded] [ref=f28e275]: + - paragraph [ref=f28e276]: 村屋天台可以安裝太陽能嗎? + - region "村屋天台可以安裝太陽能嗎?" [ref=f28e281]: + - generic [ref=f28e282]: 大部分村屋天台都可以。我哋會先上門評估結構、日照同遮擋情況,再判斷可行性同建議方案。 + - button [ref=f28e284]: + - paragraph [ref=f28e285]: 安裝太陽能大概幾錢?幾時回本? + - button [ref=f28e289]: + - paragraph [ref=f28e290]: 需要幾大天台面積? + - button [ref=f28e294]: + - paragraph [ref=f28e295]: 安裝太陽能合唔合法?會唔會影響樓宇結構? + - button [ref=f28e299]: + - paragraph [ref=f28e300]: 系統需要保養嗎? + - button [ref=f28e304]: + - paragraph [ref=f28e305]: 申請上網電價(FiT)麻煩嗎? + - generic [ref=f28e310]: + - generic [ref=f28e311]: + - paragraph [ref=f28e314]: 免費評估 + - heading "立即預約免費評估" [level=2] [ref=f28e315] + - paragraph [ref=f28e316]: 想知你嘅村屋天台啱唔啱裝太陽能?歡迎 WhatsApp 或致電,我哋會用清晰易明嘅方式為你詳答。 + - generic [ref=f28e317]: + - link "WhatsApp 查詢" [ref=f28e318] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "致電我哋" [ref=f28e321] [cursor=pointer]: + - /url: tel:+85200000000 + - generic [ref=f28e324]: + - paragraph [ref=f28e329]: +852 0000 0000 + - paragraph [ref=f28e335]: info@yingfungsolar.hk + - paragraph [ref=f28e341]: 香港新界(地址待填) + - contentinfo [ref=f28e342]: + - generic [ref=f28e343]: + - generic [ref=f28e344]: + - generic [ref=f28e345]: + - paragraph [ref=f28e346]: 盈豐太陽能 + - paragraph [ref=f28e347]: 專營香港村屋太陽能系統,由評估、設計、申請到安裝驗收,一站式為你善用天台,賺取發電回報。 + - paragraph [ref=f28e348]: 電業承辦商編號:待填 + - generic [ref=f28e349]: + - generic [ref=f28e350]: + - paragraph [ref=f28e351]: 快速連結 + - link "服務範圍" [ref=f28e352] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f28e353] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f28e354] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f28e355] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f28e356] [cursor=pointer]: + - /url: /blog + - generic [ref=f28e357]: + - paragraph [ref=f28e358]: 聯絡我哋 + - link "+852 0000 0000" [ref=f28e362] [cursor=pointer]: + - /url: tel:+85200000000 + - link "WhatsApp" [ref=f28e366] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - link "info@yingfungsolar.hk" [ref=f28e371] [cursor=pointer]: + - /url: mailto:info@yingfungsolar.hk?subject=%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D + - paragraph [ref=f28e376]: 香港新界(地址待填) + - generic [ref=f28e378]: + - paragraph [ref=f28e379]: © 2026 盈豐太陽能工程有限公司 All rights reserved. + - link "管理後台" [ref=f28e380] [cursor=pointer]: + - /url: /admin + - link "WhatsApp 查詢" [ref=f28e381] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - generic [ref=f28e386]: + - button [ref=f28e387] + - button [ref=f28e393] + - button [ref=f28e397] + - button [ref=f28e402] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-09-11T07-44-57-324Z.yml b/.playwright-mcp/page-2026-09-11T07-44-57-324Z.yml new file mode 100644 index 0000000..449643f --- /dev/null +++ b/.playwright-mcp/page-2026-09-11T07-44-57-324Z.yml @@ -0,0 +1,312 @@ +- generic: + - generic [aria-hidden]: + - banner: + - generic: + - generic: + - link: + - /url: / + - paragraph: 盈豐太陽能 + - generic: + - button [expanded] + - main: + - generic: + - generic: + - generic: + - generic: + - generic: + - paragraph: 香港村屋太陽能專家 + - heading [level=1]: 善用村屋天台 發電慳電賺回報 + - paragraph: 由現場評估、方案建議、安裝施工,到申請同跟進,我哋用清晰易明嘅方式,陪你完成整個村屋太陽能項目。 + - generic: + - link: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - text: 免費預約評估 + - link: + - /url: "#cases" + - text: 睇完成案例 + - generic: + - generic: + - paragraph: 註冊電業承辦商 + - generic: + - paragraph: 舊客口碑介紹 + - generic: + - paragraph: 一對一專人跟進 + - generic: + - generic: + - generic: + - paragraph: 一般回本期 + - paragraph: 約 6–9 年 + - generic: + - paragraph: 系統可用年期 + - paragraph: 20–25 年 + - generic: + - paragraph: 牌照 + - paragraph: 電業承辦商編號:待填 + - generic: + - generic: + - generic: + - generic: + - generic: + - paragraph: 註冊電業承辦商 + - paragraph: 合資格承辦,安全合法 + - generic: + - generic: + - paragraph: 上網電價 FiT 代辦 + - paragraph: 中電/港燈申請全程跟進 + - generic: + - generic: + - paragraph: 認可人士 AP 簽發 + - paragraph: C/PVS、WR1、GF1 文件 + - generic: + - generic: + - paragraph: 20–25 年系統壽命 + - paragraph: 優質器材,長遠穩定 + - generic: + - generic: + - generic: + - generic: + - paragraph: 服務範圍 + - heading [level=2]: 專為村屋而設嘅太陽能方案 + - paragraph: 由天台評估到掛表發電,我哋提供真正一站式嘅村屋太陽能服務。 + - generic: + - group: + - paragraph: "01" + - heading [level=3]: 村屋天台太陽能系統 + - paragraph: 善用村屋天台空間,安裝高效太陽能板,將閒置天台變成穩定收入來源。 + - group: + - paragraph: "02" + - heading [level=3]: 合法合規支架工程 + - paragraph: 按村屋結構同法規設計鋁合金支架,穩固耐用,確保合乎相關要求。 + - group: + - paragraph: "03" + - heading [level=3]: 代辦申請及文件 + - paragraph: 由中電/港燈申請、上網電價計劃(FiT)到相關政府文件,全程代辦。 + - group: + - paragraph: "04" + - heading [level=3]: 專業安裝及驗收 + - paragraph: 由認可人士(AP)及註冊電工施工,簽發所需認證文件,安全合法。 + - group: + - paragraph: "05" + - heading [level=3]: 降低頂樓室溫 + - paragraph: 太陽能板為天台遮蔭,有效降低頂樓單位溫度,同時慳冷氣電費。 + - group: + - paragraph: "06" + - heading [level=3]: 收益及回本分析 + - paragraph: 按日照、面積同電價,提供清晰嘅發電量同回本估算,一目了然。 + - generic: + - generic: + - generic: + - generic: + - paragraph: 點解揀我哋 + - heading [level=2]: 結合專業工程同貼心溝通 + - paragraph: 我哋唔止做工程,仲重視你由頭到尾嘅體驗同安心。 + - generic: + - generic: + - paragraph: "01" + - heading [level=3]: 熟悉香港村屋環境 + - paragraph: 深耕本地市場,充分掌握村屋結構、法規同地理限制。 + - generic: + - paragraph: "02" + - heading [level=3]: 流程清晰易明 + - paragraph: 用最簡單直白嘅方式解說回本期同技術細節,絕無花巧術語。 + - generic: + - paragraph: "03" + - heading [level=3]: 專人快速跟進 + - paragraph: 一對一顧問服務,由評估到完工全程透明,隨時解答疑問。 + - generic: + - paragraph: "04" + - heading [level=3]: 美觀與效率兼備 + - paragraph: 追求發電效率之餘,極致重視施工整齊度同建築美感。 + - generic: + - paragraph: "05" + - heading [level=3]: 重視施工安全 + - paragraph: 嚴選耐用器材、嚴格執行安全程序,確保系統長久穩定。 + - generic: + - paragraph: "06" + - heading [level=3]: 不硬銷真誠建議 + - paragraph: 先幫你了解安裝可行性,未必即刻做,最緊要係問清楚。 + - generic: + - generic: + - generic: + - generic: + - paragraph: 服務流程 + - heading [level=2]: 專業安裝流程 5 步到位 + - paragraph: 清晰透明嘅流程,每一步都有專人跟進,你唔需要自己四圍撲。 + - generic: + - generic: + - generic: + - generic: "01" + - paragraph: 初步諮詢 / 現場評估 + - paragraph: 專人上門視察環境,提供專業技術建議。 + - generic: + - generic: "02" + - paragraph: 申請文件處理 + - paragraph: 代辦電力公司同政府部門所需嘅申請文件。 + - generic: + - generic: "03" + - paragraph: 安裝施工 + - paragraph: 專業團隊進場施工,確保工期同施工品質安全。 + - generic: + - generic: "04" + - paragraph: 驗收認證 + - paragraph: 由認可人士及合資格電工簽發 C/PVS、WR1、GF1 等文件。 + - generic: + - generic: "05" + - paragraph: 掛表正式發電 + - paragraph: 電力公司掛上電表後,正式開始享受太陽能發電收益。 + - generic: + - generic: + - generic: + - generic: + - paragraph: 完成案例 + - heading [level=2]: 真實村屋工程案例 + - paragraph: 我哋為香港各區村屋提供專業太陽能方案,累積豐富施工經驗。 + - generic: + - group: + - generic: + - generic: + - paragraph: 2026年2月 + - generic: + - paragraph: 大埔半山 + - heading [level=3]: 大埔上碗窯 — 雙玻光伏板 航空鋁支架 + - paragraph: 採用雙玻光伏板配航空級鋁合金支架,兼顧發電效率同天台景觀。 + - generic: + - group: + - generic: + - paragraph: 2025年7月 + - generic: + - paragraph: 元朗屏山 + - heading [level=3]: 元朗山下村 — 香檳色鋁合金支架 + - paragraph: 香檳色支架配合村屋外牆色調,施工整齊,發電穩定。 + - group: + - generic: + - paragraph: 2025年5月 + - generic: + - paragraph: 新界西貢 + - heading [level=3]: 西貢西澳村 — 焗白色鋁合金支架 + - paragraph: 焗白色支架低調美觀,善用天台每一寸可用空間。 + - generic: + - generic: + - generic: + - generic: + - paragraph: 常見問題 + - heading [level=2]: 安裝前,你可能想知嘅事 + - paragraph: 仲有其他疑問?歡迎隨時 WhatsApp 問我哋。 + - generic: + - generic: + - generic: + - button [expanded]: + - paragraph: 村屋天台可以安裝太陽能嗎? + - region: + - generic: 大部分村屋天台都可以。我哋會先上門評估結構、日照同遮擋情況,再判斷可行性同建議方案。 + - generic: + - button: + - paragraph: 安裝太陽能大概幾錢?幾時回本? + - generic: + - button: + - paragraph: 需要幾大天台面積? + - generic: + - button: + - paragraph: 安裝太陽能合唔合法?會唔會影響樓宇結構? + - generic: + - button: + - paragraph: 系統需要保養嗎? + - generic: + - button: + - paragraph: 申請上網電價(FiT)麻煩嗎? + - generic: + - generic: + - generic: + - generic: + - generic: + - paragraph: 免費評估 + - heading [level=2]: 立即預約免費評估 + - paragraph: 想知你嘅村屋天台啱唔啱裝太陽能?歡迎 WhatsApp 或致電,我哋會用清晰易明嘅方式為你詳答。 + - generic: + - link: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - text: WhatsApp 查詢 + - link: + - /url: tel:+85200000000 + - text: 致電我哋 + - generic: + - generic: + - paragraph: +852 0000 0000 + - generic: + - paragraph: info@yingfungsolar.hk + - generic: + - paragraph: 香港新界(地址待填) + - contentinfo: + - generic: + - generic: + - generic: + - paragraph: 盈豐太陽能 + - paragraph: 專營香港村屋太陽能系統,由評估、設計、申請到安裝驗收,一站式為你善用天台,賺取發電回報。 + - paragraph: 電業承辦商編號:待填 + - generic: + - generic: + - paragraph: 快速連結 + - link: + - /url: "#services" + - text: 服務範圍 + - link: + - /url: "#cases" + - text: 完成案例 + - link: + - /url: "#process" + - text: 服務流程 + - link: + - /url: "#faq" + - text: 常見問題 + - link: + - /url: /blog + - text: Blog + - generic: + - paragraph: 聯絡我哋 + - generic: + - link: + - /url: tel:+85200000000 + - text: +852 0000 0000 + - generic: + - link: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - text: WhatsApp + - generic: + - link: + - /url: mailto:info@yingfungsolar.hk?subject=%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D + - text: info@yingfungsolar.hk + - generic: + - paragraph: 香港新界(地址待填) + - generic: + - generic: + - paragraph: © 2026 盈豐太陽能工程有限公司 All rights reserved. + - link: + - /url: /admin + - text: 管理後台 + - link: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - generic [ref=f28e386]: + - button [ref=f28e407]: + - generic: Menu + - button [ref=f28e408]: + - generic: Inspect + - button [ref=f28e409]: + - generic: Audit + - button [ref=f28e413]: + - generic: Settings + - dialog [ref=f28e414]: + - heading "盈豐太陽能" [level=2] [ref=f28e416] + - generic [ref=f28e418]: + - link "服務" [active] [ref=f28e419] [cursor=pointer]: + - /url: "#services" + - link "完成案例" [ref=f28e420] [cursor=pointer]: + - /url: "#cases" + - link "服務流程" [ref=f28e421] [cursor=pointer]: + - /url: "#process" + - link "常見問題" [ref=f28e422] [cursor=pointer]: + - /url: "#faq" + - link "Blog" [ref=f28e423] [cursor=pointer]: + - /url: /blog + - link "WhatsApp 免費諮詢" [ref=f28e425] [cursor=pointer]: + - /url: https://api.whatsapp.com/send?phone=85200000000&text=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91%E6%83%B3%E6%9F%A5%E8%A9%A2%E6%9D%91%E5%B1%8B%E5%A4%AA%E9%99%BD%E8%83%BD%E5%AE%89%E8%A3%9D%EF%BC%8C%E6%83%B3%E9%A0%90%E7%B4%84%E5%85%8D%E8%B2%BB%E8%A9%95%E4%BC%B0%E3%80%82 + - button "Close" [ref=f28e428] [cursor=pointer] \ No newline at end of file diff --git a/.playwright-mcp/post.png b/.playwright-mcp/post.png new file mode 100644 index 0000000..e1186af Binary files /dev/null and b/.playwright-mcp/post.png differ diff --git a/.playwright-mcp/process.png b/.playwright-mcp/process.png new file mode 100644 index 0000000..a1a1dd9 Binary files /dev/null and b/.playwright-mcp/process.png differ diff --git a/.playwright-mcp/redesign-full.png b/.playwright-mcp/redesign-full.png new file mode 100644 index 0000000..7c05918 Binary files /dev/null and b/.playwright-mcp/redesign-full.png differ diff --git a/.playwright-mcp/services.png b/.playwright-mcp/services.png new file mode 100644 index 0000000..a92bee4 Binary files /dev/null and b/.playwright-mcp/services.png differ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..b70a456 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,121 @@ +# AGENTS.md + +Astro 7 + React 19 + Chakra UI v3,部署在 Cloudflare Workers(單一 Worker)+ D1 + Drizzle。一頁式官網 + Blog + `/admin` 後台。 + +## 指令 + +- `npm run dev` — Astro dev(:4321,經 wrangler platformProxy 讀 `wrangler.jsonc` bindings) +- `npm run build` — `astro build`(唯一的驗證步驟) +- `npm run preview` / `npm run deploy` — build 後用 wrangler dev / deploy +- DB(本機用 `:local`,雲端省略):`npm run db:generate` → `db:migrate:local` / `db:migrate` → `db:seed:local` / `db:seed` +- `npm run types` — 重新產生 `worker-configuration.d.ts`;`npm run secret` — 設定 `ADMIN_PASSWORD` +- 沒有 test / lint / typecheck script(未安裝 @astrojs/check)。`npm run build` 是唯一可跑的驗證。 + +## 關鍵慣例與陷阱 + +- **SSR 頁面必須自己聲明**:`astro.config.mjs` 是 `output: "static"`,所有要讀 D1 的動態頁面都靠檔案內 `export const prerender = false`(首頁、blog、admin、sitemap/robots)。新增需要 request-time 資料的頁面時一定要加。 +- **環境變數只用 `getEnv()`**(`src/lib/env.ts`,底層 `cloudflare:workers` 的 `env`)。Astro v6 起已移除 `Astro.locals.runtime.env`。`getEnv()` 只能在 `prerender = false` 的頁面/endpoint 用。 +- **資料層**:`getDb(getEnv().DB)` → Drizzle;查詢集中在 `src/data/content.ts`,schema 在 `src/db/schema.ts`。改 schema 後跑 `npm run db:generate` 產生 migration。 +- **Seed 與 migration 是分開的**(README 講法有誤):`db:migrate:local` 只套 migrations,`migrations/seed.sql` 要用 `db:seed:local` 另外執行;seed 可重複跑。 +- **`wrangler.jsonc` 有佔位 id**:`database_id` / KV `id` 要先用 `db:create` / `kv:create` 產生再貼上,未貼前無法部署。 +- **上線前要改 `astro.config.mjs` 的 `site`**:sitemap / canonical / OG 全部靠它(現為 `https://example.com`)。 +- **後台認證**:`src/middleware.ts` 保護所有 `/admin`,用 HMAC-signed cookie(`src/lib/auth.ts`);未設 `ADMIN_PASSWORD`(本機在 `.dev.vars`,已 gitignore)會回 503。 +- **Chakra v3 + Emotion**:前台 React 元件要用 `Provider` / `SiteChrome`(內含 ``),theme 在 `src/theme/system.ts`。Astro 以 `client:load` 掛 island。 +- **語言**:UI 文案、註解、後台全部都係繁體中文(廣東話)——新增內容請保持一致;網站只做中文,不做雙語。 +- `dist/`、`.astro/`、`.wrangler/`、`worker-configuration.d.ts` 都係產生檔,唔好手改。 +- `docs/superpowers/` 有設計規格與實作計劃,係設計決策的權威來源。 + +# DOX framework + +- DOX is highly performant AGENTS.md hierarchy installed here +- Agent must follow DOX instructions across any edits + +## Core Contract + +- AGENTS.md files are binding work contracts for their subtrees +- Work products, source materials, instructions, records, assets, and durable docs must stay understandable from the nearest applicable AGENTS.md plus every parent AGENTS.md above it + +## Read Before Editing + +1. Read the root AGENTS.md +2. Identify every file or folder you expect to touch +3. Walk from the repository root to each target path +4. Read every AGENTS.md found along each route +5. If a parent AGENTS.md lists a child AGENTS.md whose scope contains the path, read that child and continue from there +6. Use the nearest AGENTS.md as the local contract and parent docs for repo-wide rules +7. If docs conflict, the closer doc controls local work details, but no child doc may weaken DOX + +Do not rely on memory. Re-read the applicable DOX chain in the current session before editing. + +## Update After Editing + +Every meaningful change requires a DOX pass before the task is done. + +Update the closest owning AGENTS.md when a change affects: + +- purpose, scope, ownership, or responsibilities +- durable structure, contracts, workflows, or operating rules +- required inputs, outputs, permissions, constraints, side effects, or artifacts +- user preferences about behavior, communication, process, organization, or quality +- AGENTS.md creation, deletion, move, rename, or index contents + +Update parent docs when parent-level structure, ownership, workflow, or child index changes. Update child docs when parent changes alter local rules. Remove stale or contradictory text immediately. Small edits that do not change behavior or contracts may leave docs unchanged, but the DOX pass still must happen. + +## Hierarchy + +- Root AGENTS.md is the DOX rail: project-wide instructions, global preferences, durable workflow rules, and the top-level Child DOX Index +- Child AGENTS.md files own domain-specific instructions and their own Child DOX Index +- Each parent explains what its direct children cover and what stays owned by the parent +- The closer a doc is to the work, the more specific and practical it must be + +## Child Doc Shape + +- Create a child AGENTS.md when a folder becomes a durable boundary with its own purpose, rules, responsibilities, workflow, materials, or quality standards +- Work Guidance must reflect the current standards of the project or user instructions; if there are no specific standards or instructions yet, leave it empty +- Verification must reflect an existing check; if no verification framework exists yet, leave it empty and update it when one exists + +Default section order: + +- Purpose +- Ownership +- Local Contracts +- Work Guidance +- Verification +- Child DOX Index + +## Style + +- Keep docs concise, current, and operational +- Document stable contracts, not diary entries +- Put broad rules in parent docs and concrete details in child docs +- Prefer direct bullets with explicit names +- Do not duplicate rules across many files unless each scope needs a local version +- Delete stale notes instead of explaining history +- Trim obvious statements, repeated rules, misplaced detail, and warnings for risks that no longer exist + +## Closeout + +1. Re-check changed paths against the DOX chain +2. Update nearest owning docs and any affected parents or children +3. Refresh every affected Child DOX Index +4. Remove stale or contradictory text +5. Run existing verification when relevant +6. Report any docs intentionally left unchanged and why + +## User Preferences + +When the user requests a durable behavior change, record it here or in the relevant child AGENTS.md + +## Child DOX Index + +| Path | Scope | +|---|---| +| `src/AGENTS.md` | 原始碼全層:架構、跨層慣例;擁有 `theme/`、`layouts/`、`config.ts`、`middleware.ts`、`env.d.ts`,以及 `pages/` 路由與 `/admin` 後台合約 | +| `src/components/site/AGENTS.md` | 前台 React island 與 Chakra UI 元件 | +| `src/data/AGENTS.md` | D1 讀取查詢層與後台設定欄位定義 | +| `src/db/AGENTS.md` | Drizzle schema(migration 的唯一來源) | +| `src/lib/AGENTS.md` | auth / env / db / markdown 基礎工具 | +| `migrations/AGENTS.md` | D1 migration 與 seed SQL | +| `docs/AGENTS.md` | 設計規格與實作計劃(`superpowers/` 為設計權威) | + +Project-level files with no child doc are owned by this root: `astro.config.mjs`、`wrangler.jsonc`、`drizzle.config.ts`、`tsconfig.json`、`package.json`、`README.md`、`.dev.vars.example`。 diff --git a/README.md b/README.md new file mode 100644 index 0000000..cd30947 --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +# 盈豐太陽能工程有限公司 — 官網(村屋太陽能) + +**Astro 7 + React 19 + Chakra UI v3 + Cloudflare Workers + D1 + Drizzle。全部部署喺 Cloudflare,零維運。** + +一頁式官網(村屋太陽能)+ Blog + 內容管理後台。 + +## 功能 + +- **一頁式官網** `/`(SSR,讀 D1):Hero、服務、特色、流程、完成案例、FAQ、聯絡 CTA +- **Blog** `/blog`、`/blog/[slug]`:封面卡片列表 + Markdown 文章頁 +- **後台** `/admin`(密碼登入):管理文章、首頁內容(服務/特色/流程/FAQ)、完成案例、網站設定(公司資料/聯絡/Hero/SEO) +- **SEO**:canonical、OG/Twitter card、`/sitemap.xml`、`/robots.txt`、結構化語意 HTML +- 首頁/Blog 用邊緣快取(`s-maxage`),後台改完約 1 分鐘內生效 + +## 技術棧 + +| 層 | 選用 | +|---|---| +| 前端框架 | Astro 7(`output: "static"` + per-page SSR) | +| UI | React 19 + `@chakra-ui/react` v3 + `@emotion/react`(清新天藍/綠色系 theme) | +| Adapter | `@astrojs/cloudflare`(一個 Worker) | +| DB | Cloudflare D1(SQLite) | +| ORM | Drizzle | +| Auth | HMAC-signed cookie(`src/lib/auth.ts`) | +| Markdown | `marked` | +| Icons | `lucide-react` | + +> Chakra v3 用 Emotion,SSR 會輸出 inline critical CSS(首屏即有樣式、零 FOUC),client hydrate 後整合到 ``;已實測 Astro 7 + React 19 無 hydration error。 + +## 本機開發 + +```bash +npm install + +# 建本機 D1 + 套 migration(migration 會連 seed.sql 一齊套) +npm run db:migrate:local + +# 重新匯入種子資料(可重複執行) +npm run db:seed:local + +# 開發 server(:4321) +npx astro dev +``` + +本機後台密碼喺 `.dev.vars`(`ADMIN_PASSWORD=changeme-local`,已 gitignore)。 + +想模擬 production(wrangler):`npx wrangler dev`。 + +## 部署到 Cloudflare + +```bash +npm run login # 瀏覽器授權 + +npm run db:create # 印 database_id → 填入 wrangler.jsonc +npm run kv:create # 印 namespace id → 填入 wrangler.jsonc + +npm run db:migrate # 雲端套 migration +npm run db:seed # 雲端匯入種子(公司資料 + 樣本內容) + +npx wrangler secret put ADMIN_PASSWORD # 設定後台密碼 + +# 改 astro.config.mjs 嘅 site = 真網域 +npm run deploy +``` + +之後更新:`npm run deploy`。 + +## 後台點用 + +1. 去 `/admin`,輸入密碼登入 +2. **內容總覽** → 服務 / 特色 / 流程 / 常見問題 / 完成案例 / 網站設定 +3. 每個項目可新增、修改、刪除、用 ↑↓ 排序、「已發布 / 草稿」控制前台顯示 +4. 圖片:直接貼圖片 URL(暫時;之後可換成上傳) + +## 結構 + +``` +src/ +├─ theme/system.ts Chakra theme(tokens / 顏色 / 字體) +├─ components/site/*.tsx 前台 React 元件(Header/Hero/Services/Faq…) +├─ data/ +│ ├─ content.ts D1 讀取 + WhatsApp/電話 link helper +│ └─ settings-fields.ts 後台設定欄位定義 +├─ db/schema.ts Drizzle schema(posts / site_settings / content_items / cases) +├─ layouts/Base.astro SEO head + fonts +├─ layouts/AdminLayout.astro 後台外框 +├─ pages/ +│ ├─ index.astro SSR 首頁 +│ ├─ blog/… Blog +│ ├─ admin/… 後台 +│ └─ sitemap.xml.ts / robots.txt.ts +└─ lib/{auth,db,env,markdown}.ts +migrations/ +├─ 0000_init.sql … Drizzle migrations +└─ seed.sql 種子資料(與 migration 一齊執行) +``` + +## 待客戶提供(可喺 `/admin/settings` 自行更新) + +- 真實電話 / WhatsApp / Email / 地址 +- 電業承辦商牌照號碼 +- 真域名(`astro.config.mjs` 嘅 `site`) +- 真實工程相片(現時用佔位圖) diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 0000000..ff81de0 --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,20 @@ +import { defineConfig } from "astro/config"; +import cloudflare from "@astrojs/cloudflare"; +import react from "@astrojs/react"; + +export default defineConfig({ + + integrations: [react()], + // ⚠️ 上線前改咗呢個做你嘅真域名(sitemap、canonical、OG 全部靠佢) + site: "https://example.com", + + output: "static", + + adapter: cloudflare({ + platformProxy: { + enabled: true, + // 本機 astro dev 時讀 wrangler.jsonc 嘅 bindings + configPath: "./wrangler.jsonc", + }, + }), +}); diff --git a/docs/AGENTS.md b/docs/AGENTS.md new file mode 100644 index 0000000..04a042b --- /dev/null +++ b/docs/AGENTS.md @@ -0,0 +1,29 @@ +# docs/AGENTS.md + +## Purpose + +專案的設計規格與實作計劃文件。 + +## Ownership + +- 擁有 `docs/` 全樹,包括 `docs/superpowers/specs/` 同 `docs/superpowers/plans/`。 + +## Local Contracts + +- **設計權威**:`superpowers/specs/` 係已確認的設計規格,係設計決策的權威來源。實作與 spec 有出入時,以 spec 為準,或先更新 spec。 +- **實作計劃**:`superpowers/plans/` 用 checkbox 追蹤進度;計劃與實際實作有偏差時同步更新。 +- **檔名**:`YYYY-MM-DD-.md`。 +- 內容繁體中文(廣東話)。 + +## Work Guidance + +- 做大改動前先讀對應 spec / plan;完成後如設計有變,更新文件而唔係留低過時描述。 +- 呢啲係設計記錄,唔係日常 diary;只記穩定決策同計劃。 + +## Verification + +無自動化檢查;靠人工對照 spec 同實作。 + +## Child DOX Index + +無(`superpowers/` 由本文件覆蓋)。 diff --git a/docs/superpowers/plans/2026-09-11-ying-fung-solar.md b/docs/superpowers/plans/2026-09-11-ying-fung-solar.md new file mode 100644 index 0000000..ec7aa82 --- /dev/null +++ b/docs/superpowers/plans/2026-09-11-ying-fung-solar.md @@ -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 # +│ ├─ 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 → +├─ pages/blog/index.astro # SSR → +├─ pages/blog/[slug].astro # SSR → +├─ 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` = `{children}` +- [ ] `SiteChrome` = `
{children}