Integrate CMS with Marketing Solutions page
Links the marketing solutions frontend page to the Payload CMS Pages collection via the new API library. Removes legacy static portfolio routes and components to consolidate marketing content. Enhances the Header and Footer Astro components with improved responsive styling.
This commit is contained in:
@@ -2,10 +2,22 @@
|
||||
/**
|
||||
* Marketing Solutions Page - 行銷方案頁面
|
||||
* Pixel-perfect implementation based on Webflow design
|
||||
* Data fetched from Payload CMS Pages Collection API
|
||||
*/
|
||||
import Layout from '../layouts/Layout.astro'
|
||||
import SolutionsHero from '../sections/SolutionsHero.astro'
|
||||
import ServicesList from '../sections/ServicesList.astro'
|
||||
import { getMarketingSolutionsPage } from '../lib/api/marketing-solution'
|
||||
import SectionHeader from '../components/SectionHeader.astro'
|
||||
|
||||
// Fetch page data from CMS
|
||||
const pageData = await getMarketingSolutionsPage()
|
||||
|
||||
// Use CMS data or fallback to defaults
|
||||
const heroTitle = pageData?.heroTitle || '行銷解決方案'
|
||||
const heroSubtitle = pageData?.heroSubtitle || '提供全方位的數位行銷服務,協助您的品牌在數位時代脫穎而出'
|
||||
const heroImage = pageData?.heroImage
|
||||
const services = pageData?.services || []
|
||||
|
||||
// Metadata for SEO
|
||||
const title = '行銷解決方案 | 恩群數位行銷'
|
||||
@@ -15,10 +27,16 @@ const description = '恩群數位行銷提供全方位的數位行銷服務,
|
||||
<Layout title={title} description={description}>
|
||||
<!-- Hero Section -->
|
||||
<SolutionsHero
|
||||
title="行銷解決方案"
|
||||
subtitle="提供全方位的數位行銷服務,協助您的品牌在數位時代脫穎而出"
|
||||
title={heroTitle}
|
||||
subtitle={heroSubtitle}
|
||||
backgroundImage={heroImage}
|
||||
/>
|
||||
<!-- Section Header -->
|
||||
<SectionHeader
|
||||
title="行銷方案"
|
||||
subtitle="Marketing solutions"
|
||||
sectionBg="bg-white"
|
||||
/>
|
||||
|
||||
<!-- Services List -->
|
||||
<ServicesList />
|
||||
<ServicesList services={services} />
|
||||
</Layout>
|
||||
|
||||
@@ -1,345 +0,0 @@
|
||||
---
|
||||
/**
|
||||
* Portfolio Detail Page - 作品詳情頁
|
||||
* Displays full project information with live website link
|
||||
* Pixel-perfect implementation based on Webflow design
|
||||
*/
|
||||
import Layout from '../../layouts/Layout.astro'
|
||||
import { fetchPortfolioBySlug, getWebsiteTypeLabel } from '../../lib/api/portfolio'
|
||||
|
||||
// Get slug from params
|
||||
const { slug } = Astro.params
|
||||
|
||||
// Validate slug
|
||||
if (!slug) {
|
||||
return Astro.redirect('/404')
|
||||
}
|
||||
|
||||
// Fetch portfolio item
|
||||
const portfolio = await fetchPortfolioBySlug(slug)
|
||||
|
||||
// Handle 404 for non-existent portfolio
|
||||
if (!portfolio) {
|
||||
return Astro.redirect('/404')
|
||||
}
|
||||
|
||||
// Get website type label
|
||||
const typeLabel = getWebsiteTypeLabel(portfolio.websiteType)
|
||||
|
||||
// Get tags
|
||||
const tags = portfolio.tags?.map(t => t.tag) || []
|
||||
|
||||
// SEO metadata
|
||||
const title = `${portfolio.title} | 恩群數位案例分享`
|
||||
const description = portfolio.description || `瀏覽 ${portfolio.title} 專案詳情`
|
||||
---
|
||||
|
||||
<Layout title={title} description={description}>
|
||||
<article class="portfolio-detail">
|
||||
<div class="container">
|
||||
<!-- Back Link -->
|
||||
<a href="/portfolio" class="back-link">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
|
||||
<path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/>
|
||||
</svg>
|
||||
返回作品列表
|
||||
</a>
|
||||
|
||||
<!-- Project Header -->
|
||||
<header class="project-header">
|
||||
<div class="project-meta">
|
||||
<span class="project-type-badge">{typeLabel}</span>
|
||||
</div>
|
||||
<h1 class="project-title">{portfolio.title}</h1>
|
||||
|
||||
{
|
||||
portfolio.description && (
|
||||
<p class="project-description">{portfolio.description}</p>
|
||||
)
|
||||
}
|
||||
|
||||
<!-- Tags -->
|
||||
{
|
||||
tags.length > 0 && (
|
||||
<div class="project-tags">
|
||||
{tags.map((tag) => (
|
||||
<span class="tag">{tag}</span>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</header>
|
||||
|
||||
<!-- Hero Image -->
|
||||
{
|
||||
portfolio.image?.url && (
|
||||
<div class="project-hero-image">
|
||||
<img
|
||||
src={portfolio.image.url}
|
||||
alt={portfolio.image.alt || portfolio.title}
|
||||
loading="eager"
|
||||
width="1200"
|
||||
height="675"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<!-- Project Content -->
|
||||
<div class="project-content">
|
||||
<div class="content-section">
|
||||
<h2>專案介紹</h2>
|
||||
<p>
|
||||
此專案展示了我們在{typeLabel}領域的專業能力。
|
||||
我們致力於為客戶打造符合品牌定位、使用體驗優良的數位產品。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="content-section">
|
||||
<h2>專案連結</h2>
|
||||
{
|
||||
portfolio.url ? (
|
||||
<a
|
||||
href={portfolio.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="btn-primary"
|
||||
>
|
||||
前往網站
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor">
|
||||
<path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/>
|
||||
</svg>
|
||||
</a>
|
||||
) : (
|
||||
<p class="text-muted">此專案暫無公開連結</p>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<div class="detail-cta">
|
||||
<h3>喜歡這個作品嗎?</h3>
|
||||
<p>讓我們一起為您的品牌打造獨特的數位體驗</p>
|
||||
<a href="/contact-us" class="cta-button">
|
||||
聯絡我們
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
/* Portfolio Detail */
|
||||
.portfolio-detail {
|
||||
padding: 60px 20px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Back Link */
|
||||
.back-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 2rem;
|
||||
color: var(--color-enchunblue, #23608c);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: color 0.25s ease;
|
||||
}
|
||||
|
||||
.back-link:hover {
|
||||
color: var(--color-enchunblue-hover, #1a4d6e);
|
||||
}
|
||||
|
||||
/* Project Header */
|
||||
.project-header {
|
||||
text-align: center;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.project-meta {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.project-type-badge {
|
||||
display: inline-block;
|
||||
background: var(--color-enchunblue, #23608c);
|
||||
color: white;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 20px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.project-title {
|
||||
font-family: "Noto Sans TC", sans-serif;
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-dark-blue, #1a1a1a);
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.project-description {
|
||||
font-family: "Noto Sans TC", sans-serif;
|
||||
font-size: 1.125rem;
|
||||
color: var(--color-gray-600, #666);
|
||||
max-width: 700px;
|
||||
margin: 0 auto 1.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.project-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.tag {
|
||||
background: var(--color-gray-100, #f5f5f5);
|
||||
color: var(--color-gray-700, #4a5568);
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 20px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Hero Image */
|
||||
.project-hero-image {
|
||||
margin-bottom: 3rem;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.project-hero-image img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Project Content */
|
||||
.project-content {
|
||||
display: grid;
|
||||
gap: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.content-section h2 {
|
||||
font-family: "Noto Sans TC", sans-serif;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-dark-blue, #1a1a1a);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.content-section p {
|
||||
color: var(--color-gray-600, #666);
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: var(--color-enchunblue, #23608c);
|
||||
color: white;
|
||||
padding: 0.875rem 1.75rem;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--color-enchunblue-hover, #1a4d6e);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(35, 96, 140, 0.3);
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: var(--color-gray-500, #999);
|
||||
}
|
||||
|
||||
/* Detail CTA */
|
||||
.detail-cta {
|
||||
text-align: center;
|
||||
padding: 3rem 2rem;
|
||||
background: var(--color-gray-50, #f9fafb);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.detail-cta h3 {
|
||||
font-family: "Noto Sans TC", sans-serif;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-enchunblue, #23608c);
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.detail-cta p {
|
||||
color: var(--color-gray-600, #666);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
background: var(--color-enchunblue, #23608c);
|
||||
color: white;
|
||||
padding: 14px 28px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
background: var(--color-enchunblue-hover, #1a4d6e);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(35, 96, 140, 0.3);
|
||||
}
|
||||
|
||||
/* Responsive Adjustments */
|
||||
@media (max-width: 991px) {
|
||||
.portfolio-detail {
|
||||
padding: 50px 20px;
|
||||
}
|
||||
|
||||
.project-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.portfolio-detail {
|
||||
padding: 40px 16px;
|
||||
}
|
||||
|
||||
.project-title {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.project-description {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.content-section h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.detail-cta {
|
||||
padding: 2rem 1.5rem;
|
||||
}
|
||||
|
||||
.detail-cta h3 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,244 +0,0 @@
|
||||
---
|
||||
/**
|
||||
* Portfolio Listing Page - 案例分享列表頁
|
||||
* Displays all portfolio items in a 2-column grid
|
||||
* Pixel-perfect implementation based on Webflow design
|
||||
*/
|
||||
import Layout from '../../layouts/Layout.astro'
|
||||
import PortfolioCard from '../../components/PortfolioCard.astro'
|
||||
import { fetchPortfolios } from '../../lib/api/portfolio'
|
||||
|
||||
// Metadata for SEO
|
||||
const title = '案例分享 | 恩群數位行銷'
|
||||
const description = '瀏覽恩群數位的成功案例,包括企業官網、電商網站、品牌網站等設計作品。'
|
||||
|
||||
// Fetch portfolios from Payload CMS
|
||||
const portfoliosData = await fetchPortfolios(1, 100)
|
||||
const portfolios = portfoliosData.docs
|
||||
---
|
||||
|
||||
<Layout title={title} description={description}>
|
||||
<!-- Portfolio Header -->
|
||||
<section class="portfolio-header" aria-labelledby="portfolio-heading">
|
||||
<div class="container">
|
||||
<div class="section_header_w_line">
|
||||
<div class="divider_line"></div>
|
||||
<div class="header_subtitle">
|
||||
<h2 id="portfolio-heading" class="header_subtitle_head">案例分享</h2>
|
||||
<p class="header_subtitle_paragraph">Our Works</p>
|
||||
</div>
|
||||
<div class="divider_line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Portfolio Grid -->
|
||||
<section class="portfolio-grid-section" aria-label="作品列表">
|
||||
<div class="container">
|
||||
{
|
||||
portfolios.length > 0 ? (
|
||||
<ul class="portfolio-grid">
|
||||
{
|
||||
portfolios.map((item) => (
|
||||
<PortfolioCard
|
||||
item={{
|
||||
slug: item.slug,
|
||||
title: item.title,
|
||||
description: item.description || '',
|
||||
image: item.image?.url,
|
||||
tags: item.tags?.map(t => t.tag) || [],
|
||||
externalUrl: item.url || undefined,
|
||||
}}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
) : (
|
||||
<div class="empty-state">
|
||||
<p class="empty-text">暫無作品資料</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="portfolio-cta" aria-labelledby="cta-heading">
|
||||
<div class="container">
|
||||
<h2 id="cta-heading" class="cta-title">
|
||||
有興趣與我們合作嗎?
|
||||
</h2>
|
||||
<p class="cta-description">
|
||||
讓我們一起為您的品牌打造獨特的數位體驗
|
||||
</p>
|
||||
<a href="/contact-us" class="cta-button">
|
||||
聯絡我們
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
/* Portfolio Header */
|
||||
.portfolio-header {
|
||||
padding: 60px 20px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.section_header_w_line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.header_subtitle {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header_subtitle_head {
|
||||
color: var(--color-enchunblue, #23608c);
|
||||
font-family: "Noto Sans TC", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header_subtitle_paragraph {
|
||||
color: var(--color-gray-600, #666);
|
||||
font-family: "Quicksand", "Noto Sans TC", sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.divider_line {
|
||||
width: 40px;
|
||||
height: 2px;
|
||||
background-color: var(--color-enchunblue, #23608c);
|
||||
}
|
||||
|
||||
/* Grid Section */
|
||||
.portfolio-grid-section {
|
||||
padding: 0 20px 60px;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.portfolio-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Empty State */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 80px 20px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 1.125rem;
|
||||
color: var(--color-gray-500, #999);
|
||||
}
|
||||
|
||||
/* CTA Section */
|
||||
.portfolio-cta {
|
||||
text-align: center;
|
||||
padding: 80px 20px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-family: "Noto Sans TC", sans-serif;
|
||||
font-size: 1.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-enchunblue, #23608c);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.cta-description {
|
||||
font-size: 1rem;
|
||||
color: var(--color-gray-600, #666);
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
background-color: var(--color-enchunblue, #23608c);
|
||||
color: white;
|
||||
padding: 16px 32px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(35, 96, 140, 0.3);
|
||||
background-color: var(--color-enchunblue-hover, #1a4d6e);
|
||||
}
|
||||
|
||||
/* Responsive Adjustments */
|
||||
@media (max-width: 991px) {
|
||||
.portfolio-header {
|
||||
padding: 50px 20px;
|
||||
}
|
||||
|
||||
.header_subtitle_head {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.portfolio-grid {
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.portfolio-header {
|
||||
padding: 40px 16px;
|
||||
}
|
||||
|
||||
.header_subtitle_head {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.header_subtitle_paragraph {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
|
||||
.portfolio-grid-section {
|
||||
padding: 0 16px 40px;
|
||||
}
|
||||
|
||||
.portfolio-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.portfolio-cta {
|
||||
padding: 60px 16px;
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.cta-description {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 24px;
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,442 +0,0 @@
|
||||
---
|
||||
/**
|
||||
* Portfolio Detail Page - 案例詳情頁
|
||||
* Pixel-perfect implementation based on Webflow design
|
||||
*/
|
||||
import Layout from '../../layouts/Layout.astro'
|
||||
|
||||
// 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>
|
||||
|
||||
<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'],
|
||||
},
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const slugs = Object.keys(portfolioItems)
|
||||
|
||||
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 title={title} description={description}>
|
||||
<!-- Breadcrumb -->
|
||||
<nav class="breadcrumb" aria-label="麵包屑導航">
|
||||
<div class="container">
|
||||
<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>
|
||||
</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>
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.portfolio-detail-header {
|
||||
margin-bottom: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.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>
|
||||
Reference in New Issue
Block a user