feat(frontend): update pages, components and branding

Refresh Astro frontend implementation including new pages (Portfolio, Teams, Services), components, and styling updates.
This commit is contained in:
2026-02-11 11:50:42 +08:00
parent be7fc902fb
commit 9c2181f743
49 changed files with 9699 additions and 899 deletions

View File

@@ -1,52 +1,442 @@
---
import Layout from '../../layouts/Layout.astro';
/**
* Portfolio Detail Page - 案例詳情頁
* Pixel-perfect implementation based on Webflow design
*/
import Layout from '../../layouts/Layout.astro'
export async function getStaticPaths() {
// Portfolio slugs from sitemap
const slugs = [
'web-design-project-2',
'web-design-project-3',
'web-design-project-4',
'web-design-project-5'
];
// Get portfolio items
const portfolioItems: Record<string, {
title: string
client?: string
date?: string
category?: string
description: string
images?: string[]
externalUrl?: string
}> = {
'corporate-website-1': {
title: '企業官網設計案例',
client: '知名製造業公司',
date: '2024年1月',
category: '企業官網',
description: `
<p>這是一個為知名製造業公司打造的現代化企業官網專案。客戶希望建立一個能夠有效展示產品系列、公司形象以及最新消息的專業網站。</p>
return slugs.map(slug => ({
params: { slug },
props: { slug }
}));
<h3>專案背景</h3>
<p>客戶原有的網站設計過時,難以在手機設備上正常瀏覽,且內容管理不夠靈活。他們需要一個響應式設計的現代化網站,能夠自動適應各種設備,並方便內容團隊更新。</p>
<h3>解決方案</h3>
<p>我們採用了最新的網頁技術,打造了一個完全響應式的企業官網。網站架構清晰,導航直觀,產品展示頁面設計精美,同時整合了新聞發佈功能,讓客戶能夠快速分享公司動態。</p>
<h3>專案成果</h3>
<p>網站上線後,客戶反映使用者停留時間增加了 40%,詢問量也顯著提升。響應式設計讓行動用戶也能獲得良好的瀏覽體驗,整體滿意度非常高。</p>
`,
images: ['/placeholder-portfolio-1.jpg'],
},
'ecommerce-site-1': {
title: '電商平台建置',
client: '精品品牌',
date: '2024年2月',
category: '電商網站',
description: `
<p>這是一個為精品品牌打造的 B2C 電商網站專案。客戶需要一個功能完整、設計精緻的線上購物平台。</p>
<h3>專案背景</h3>
<p>客戶希望拓展線上銷售渠道,建立一個能夠完整呈現品牌調性的電商網站。需求包含會員系統、購物車、金流整合、庫存管理等完整功能。</p>
<h3>解決方案</h3>
<p>我們設計了一個簡潔優雅的電商平台,整合了完整的購物流程。從商品瀏覽、加入購物車、結帳到訂單追蹤,整個流程流暢無縫。同時整合了主流金流與物流服務。</p>
<h3>專案成果</h3>
<p>網站上線後首月即達到預期銷售目標,客戶反應購物體驗流暢,設計風格也獲得用戶高度評價。</p>
`,
images: ['/placeholder-portfolio-2.jpg'],
},
'brand-website-1': {
title: '品牌形象網站',
client: '新創品牌',
date: '2024年3月',
category: '品牌網站',
description: `
<p>這是一個為新創品牌打造的以視覺故事為核心的品牌網站專案。</p>
<h3>專案背景</h3>
<p>客戶是一個新創品牌,需要一個能夠有效傳達品牌故事、價值理念的網站。他們希望網站不只是資訊展示,更能成為品牌與用戶情感連結的橋樑。</p>
<h3>解決方案</h3>
<p>我們以視覺故事為設計核心,運用大型視覺元素、動畫效果和互動設計,打造了一個充滿故事性的品牌網站。每一個區塊都精心設計,引導用戶深入了解品牌。</p>
<h3>專案成果</h3>
<p>網站成功建立了強烈的品牌印象,訪客平均停留時間超過 3 分鐘,品牌認知度顯著提升。</p>
`,
images: ['/placeholder-portfolio-3.jpg'],
},
'landing-page-1': {
title: '活動行銷頁面',
client: '活動主辦單位',
date: '2024年4月',
category: '活動頁面',
description: `
<p>這是一個為大型活動設計的高轉換率行銷頁面專案。</p>
<h3>專案背景</h3>
<p>客戶需要一個能夠有效吸引報名、轉換率高的活動頁面。頁面需要能夠清楚傳達活動資訊、吸引目光,並引導用戶完成報名流程。</p>
<h3>解決方案</h3>
<p>我們設計了一個視覺衝擊力強的活動頁面CTA 按鈕配置經過精心規劃,報名流程簡化到最少步驟。同時加入倒數計時、名額顯示等促進轉換的元素。</p>
<h3>專案成果</h3>
<p>頁面上線後,報名轉換率達到 15%,遠超過預期目標,活動順利達到滿檔狀態。</p>
`,
images: ['/placeholder-portfolio-4.jpg'],
},
}
const { slug } = Astro.props;
export async function getStaticPaths() {
const slugs = Object.keys(portfolioItems)
// Placeholder content
const project = {
title: 'Web Design Project',
description: 'Project description...',
images: []
};
return slugs.map((slug) => ({
params: { slug },
props: { slug }
}))
}
const { slug } = Astro.props
const project = portfolioItems[slug] || {
title: '作品詳情',
description: '<p>暫無內容</p>',
images: ['/placeholder-portfolio.jpg'],
}
// Metadata for SEO
const title = `${project.title} | 恩群數位案例`
const description = project.description.replace(/<[^>]*>/g, '').slice(0, 160)
---
<Layout>
<section class="project-section">
<Layout title={title} description={description}>
<!-- Breadcrumb -->
<nav class="breadcrumb" aria-label="麵包屑導航">
<div class="container">
<h1>{project.title}</h1>
<p>{project.description}</p>
<!-- Images and details -->
<ol class="breadcrumb-list">
<li><a href="/">首頁</a></li>
<li><a href="/website-portfolio">案例分享</a></li>
<li aria-current="page">{project.title}</li>
</ol>
</div>
</section>
</nav>
<!-- Portfolio Detail -->
<article class="portfolio-detail">
<div class="container">
<!-- Header -->
<header class="portfolio-detail-header">
<h1 class="portfolio-detail-title">{project.title}</h1>
<div class="portfolio-detail-meta">
{
project.client && (
<span class="meta-item">
<strong>客戶:</strong>{project.client}
</span>
)
}
{
project.date && (
<span class="meta-item">
<strong>日期:</strong>{project.date}
</span>
)
}
{
project.category && (
<span class="meta-item">
<strong>類別:</strong>{project.category}
</span>
)
}
</div>
</header>
<!-- Featured Image -->
{
project.images && project.images.length > 0 && (
<div class="portfolio-detail-image-wrapper">
<img
src={project.images[0]}
alt={project.title}
class="portfolio-detail-image"
loading="eager"
width="1000"
height="562"
/>
</div>
)
}
<!-- Description -->
<div class="portfolio-detail-content">
<div class="description-wrapper" set:html={project.description} />
</div>
<!-- CTA -->
<div class="portfolio-detail-cta">
<h3 class="cta-heading">有專案想要討論嗎?</h3>
<p class="cta-subheading">我們很樂意聽聽您的需求</p>
<a href="/contact-us" class="cta-button">
聯絡我們
</a>
</div>
<!-- Related Projects -->
<div class="related-projects">
<h3 class="related-title">更多案例</h3>
<a href="/website-portfolio" class="view-all-link">
查看全部案例 →
</a>
</div>
</div>
</article>
</Layout>
<style>
.project-section {
padding: 40px 0;
/* Portfolio Detail Styles - Pixel-perfect from Webflow */
/* Breadcrumb */
.breadcrumb {
padding: 16px 20px;
background-color: #f8f9fa;
border-bottom: 1px solid #e5e7eb;
}
.breadcrumb-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
max-width: 1200px;
margin: 0 auto;
padding: 0;
list-style: none;
font-size: 0.875rem;
color: var(--color-gray-600);
}
.breadcrumb-list a {
color: var(--color-enchunblue);
text-decoration: none;
}
.breadcrumb-list a:hover {
text-decoration: underline;
}
.breadcrumb-list li:not(:last-child)::after {
content: '/';
margin-left: 8px;
color: var(--color-gray-400);
}
/* Detail Section */
.portfolio-detail {
padding: 60px 20px;
background-color: #ffffff;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
/* Header */
.portfolio-detail-header {
margin-bottom: 40px;
text-align: center;
margin-bottom: 30px;
}
</style>
.portfolio-detail-title {
font-family: "Noto Sans TC", sans-serif;
font-size: 2.5rem;
font-weight: 700;
color: var(--color-tarawera, #2d3748);
margin-bottom: 24px;
line-height: 1.2;
}
.portfolio-detail-meta {
display: flex;
justify-content: center;
gap: 24px;
font-size: 0.875rem;
color: var(--color-gray-600);
flex-wrap: wrap;
}
.meta-item strong {
color: var(--color-text-primary);
}
/* Featured Image */
.portfolio-detail-image-wrapper {
margin-bottom: 40px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}
.portfolio-detail-image {
width: 100%;
height: auto;
display: block;
}
/* Content */
.portfolio-detail-content {
margin-bottom: 60px;
}
.description-wrapper {
font-family: "Noto Sans TC", sans-serif;
font-size: 1.125rem;
line-height: 1.8;
color: var(--color-text-primary);
}
.description-wrapper :global(p) {
margin-bottom: 20px;
}
.description-wrapper :global(h3) {
font-size: 1.5rem;
font-weight: 600;
color: var(--color-enchunblue);
margin-top: 32px;
margin-bottom: 16px;
}
/* CTA Section */
.portfolio-detail-cta {
text-align: center;
padding: 60px;
background: linear-gradient(135deg, rgba(35, 96, 140, 0.05) 0%, rgba(35, 96, 140, 0.02) 100%);
border-radius: 12px;
margin-bottom: 60px;
}
.cta-heading {
font-family: "Noto Sans TC", sans-serif;
font-size: 1.75rem;
font-weight: 600;
color: var(--color-enchunblue);
margin-bottom: 8px;
}
.cta-subheading {
font-size: 1rem;
color: var(--color-gray-600);
margin-bottom: 24px;
}
.cta-button {
display: inline-block;
background-color: var(--color-enchunblue);
color: white;
padding: 16px 32px;
border-radius: var(--radius, 8px);
font-weight: 600;
text-decoration: none;
transition: all var(--transition-base, 0.3s ease);
}
.cta-button:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-md, 0 4px 6px rgba(0, 0, 0, 0.1));
background-color: var(--color-enchunblue-hover, #1a4d6e);
}
/* Related Projects */
.related-projects {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 32px;
border-top: 1px solid var(--color-border, #e5e7eb);
}
.related-title {
font-family: "Noto Sans TC", sans-serif;
font-size: 1.25rem;
font-weight: 600;
color: var(--color-text-primary);
}
.view-all-link {
color: var(--color-enchunblue);
text-decoration: none;
font-weight: 500;
transition: color var(--transition-fast, 0.2s ease);
}
.view-all-link:hover {
color: var(--color-enchunblue-hover, #1a4d6e);
}
/* Responsive Adjustments */
@media (max-width: 991px) {
.portfolio-detail {
padding: 50px 16px;
}
.portfolio-detail-title {
font-size: 2rem;
}
.portfolio-detail-cta {
padding: 40px;
}
.cta-heading {
font-size: 1.5rem;
}
}
@media (max-width: 767px) {
.breadcrumb {
padding: 12px 16px;
}
.breadcrumb-list {
font-size: 0.8125rem;
}
.portfolio-detail {
padding: 40px 16px;
}
.portfolio-detail-title {
font-size: 1.75rem;
}
.portfolio-detail-meta {
flex-direction: column;
gap: 8px;
}
.portfolio-detail-cta {
padding: 32px 20px;
}
.related-projects {
flex-direction: column;
gap: 16px;
align-items: flex-start;
}
.description-wrapper {
font-size: 1rem;
}
.description-wrapper :global(h3) {
font-size: 1.25rem;
}
}
</style>