Phase 1: Homepage seamless design - add gradient transitions
- Added gradient transitions between sections in global.css - Portfolio section now has gradient-top (dark to white fade) - Blog section now has gradient-bottom (white fade from dark) - Reduced portfolio overlay opacity from 0.85 to 0.65 - Added border to blog cards for white-on-white visibility - Blog cards now have primary color accent on hover
This commit is contained in:
248
src/pages/services/[slug].astro
Normal file
248
src/pages/services/[slug].astro
Normal file
@@ -0,0 +1,248 @@
|
||||
---
|
||||
import Base from '../../layouts/Base.astro';
|
||||
import Navigation from '../../components/Navigation.astro';
|
||||
import Footer from '../../components/Footer.astro';
|
||||
import PageHero from '../../components/PageHero.astro';
|
||||
import { getCollection, render } from 'astro:content';
|
||||
|
||||
// For SSR mode, use Astro.params directly
|
||||
const { slug } = Astro.params;
|
||||
|
||||
const services = await getCollection('services');
|
||||
// Use id for matching since slug might be undefined
|
||||
const service = services.find(s => s.id === slug);
|
||||
|
||||
if (!service) {
|
||||
return Astro.redirect('/404');
|
||||
}
|
||||
|
||||
const { Content } = await render(service);
|
||||
|
||||
const features = [
|
||||
{ icon: service.data.feature1_icon, title: service.data.feature1_title, desc: service.data.feature1_desc },
|
||||
{ icon: service.data.feature2_icon, title: service.data.feature2_title, desc: service.data.feature2_desc },
|
||||
{ icon: service.data.feature3_icon, title: service.data.feature3_title, desc: service.data.feature3_desc },
|
||||
{ icon: service.data.feature4_icon, title: service.data.feature4_title, desc: service.data.feature4_desc },
|
||||
{ icon: service.data.feature5_icon, title: service.data.feature5_title, desc: service.data.feature5_desc },
|
||||
{ icon: service.data.feature6_icon, title: service.data.feature6_title, desc: service.data.feature6_desc },
|
||||
].filter(f => f.title);
|
||||
|
||||
const processSteps = [
|
||||
{ num: "01", title: "วิเคราะห์", desc: service.data.category === 'tech-consult' ? "วิเคราะห์กระบวนการทำงานปัจจุบันและหาโอกาส" : "วิเคราะห์การตลาดปัจจุบันและหาโอกาส" },
|
||||
{ num: "02", title: "ออกแบบ", desc: "ออกแบบระบบที่เหมาะกับความต้องการและ budget" },
|
||||
{ num: "03", title: "พัฒนา", desc: "พัฒนาและ deploy ระบบพร้อมทดสอบก่อนใช้งานจริง" },
|
||||
{ num: "04", title: service.data.category === 'tech-consult' ? "Support" : "วัดผล", desc: service.data.category === 'tech-consult' ? "ดูแลและปรับปรุงระบบให้ทำงานได้อย่างต่อเนื่อง" : "ติดตามผลและปรับปรุงอย่างต่อเนื่องเพื่อเพิ่ม ROI" },
|
||||
];
|
||||
|
||||
const uspText = service.data.category === 'tech-consult'
|
||||
? "ลูกค้าที่ใช้บริการ Consult จะได้รับ Server สำหรับ App และ AI ฟรี (สำหรับการใช้งานปกติ) หากต้องการใช้งานหนักหรือ Resource-intensive จะมีค่าใช้จ่ายเพิ่มเติม"
|
||||
: "ลูกค้าที่ใช้ Server ของเราจะได้รับบริการแก้ไขและเพิ่มเนื้อหาเว็บไซต์ฟรี! จ่ายเฉพาะเมื่อต้องการ Redesign ทั้งหมด หรือ Upgrade ฟีเจอร์ใหญ่ เช่น เพิ่มระบบ E-commerce";
|
||||
|
||||
const uspTitle = service.data.category === 'tech-consult'
|
||||
? "Server ฟรีสำหรับลูกค้า Consult"
|
||||
: "แก้ไขเนื้อหาฟรี!";
|
||||
---
|
||||
|
||||
<Base title={`${service.data.title} | MoreminiMore`}>
|
||||
<Navigation />
|
||||
|
||||
<PageHero
|
||||
badge={service.data.badge}
|
||||
title={service.data.title}
|
||||
subtitle={service.data.subtitle}
|
||||
/>
|
||||
|
||||
<!-- Objective Badge -->
|
||||
<section class="section section-dark" style="padding: 40px 0;">
|
||||
<div class="container">
|
||||
<div class="hero-objective">
|
||||
<span class="objective-label">เป้าหมายหลัก:</span>
|
||||
<span class="objective-value">{service.data.objective}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- USP Section -->
|
||||
<section class="section section-light usp-section">
|
||||
<div class="container">
|
||||
<div class="usp-card">
|
||||
<div class="usp-icon">🎁</div>
|
||||
<div class="usp-content">
|
||||
<h3 class="usp-title">{uspTitle}</h3>
|
||||
<p class="usp-desc">{uspText}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Features Section -->
|
||||
<section class="section features-section">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">บริการของเรา</span>
|
||||
<h2 class="section-title">{service.data.title} ที่เราช่วยได้</h2>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
{features.map((feature, i) => (
|
||||
<div class="feature-card" style={`--delay: ${i * 0.1}s`}>
|
||||
<div class="feature-icon">{feature.icon || "⭐"}</div>
|
||||
<h3 class="feature-title">{feature.title}</h3>
|
||||
<p class="feature-desc">{feature.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Process Section -->
|
||||
<section class="section section-dark process-section">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">กระบวนการ</span>
|
||||
<h2 class="section-title-light">วิธีการทำงานของเรา</h2>
|
||||
</div>
|
||||
<div class="process-steps">
|
||||
{processSteps.map((step, i) => (
|
||||
<div class="step" style={`--delay: ${i * 0.1}s`}>
|
||||
<span class="step-num">{step.num}</span>
|
||||
<h3 class="step-title">{step.title}</h3>
|
||||
<p class="step-desc">{step.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="section section-primary cta-section">
|
||||
<div class="container">
|
||||
<div class="cta-content">
|
||||
<h2 class="cta-title">ต้องการ{service.data.objective}?</h2>
|
||||
<p class="cta-desc">ปรึกษาฟรี! เราพร้อมช่วยวิเคราะห์และออกแบบโซลูชันที่เหมาะกับคุณ</p>
|
||||
<div class="cta-actions">
|
||||
<a href="/contact" class="btn btn-dark btn-lg">ติดต่อเรา</a>
|
||||
<a href="tel:0809955945" class="btn btn-outline-dark btn-lg">080-995-5945</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
</Base>
|
||||
|
||||
<style>
|
||||
.section-dark {
|
||||
background: var(--color-dark);
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.section-light {
|
||||
background: var(--color-gray-100);
|
||||
}
|
||||
|
||||
.section-primary {
|
||||
background: var(--color-primary);
|
||||
}
|
||||
|
||||
.hero-objective {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
background: rgba(254, 212, 0, 0.15);
|
||||
padding: 12px 24px;
|
||||
border-radius: 40px;
|
||||
border: 1px solid rgba(254, 212, 0, 0.3);
|
||||
}
|
||||
.objective-label { color: rgba(255,255,255,0.6); font-size: 14px; }
|
||||
.objective-value { color: var(--color-primary); font-weight: 700; font-size: 16px; }
|
||||
|
||||
.usp-card {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 24px;
|
||||
padding: 32px;
|
||||
background: linear-gradient(135deg, var(--color-primary) 0%, #ffe066 100%);
|
||||
border-radius: 20px;
|
||||
}
|
||||
.usp-icon { font-size: 48px; flex-shrink: 0; }
|
||||
.usp-title { font-size: 24px; font-weight: 700; color: var(--color-black); margin-bottom: 12px; }
|
||||
.usp-desc { font-size: 16px; color: rgba(0,0,0,0.8); line-height: 1.6; }
|
||||
|
||||
.section-header { text-align: center; margin-bottom: 60px; }
|
||||
.section-badge {
|
||||
display: inline-block;
|
||||
background: var(--color-primary);
|
||||
color: var(--color-black);
|
||||
padding: 6px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.section-title { font-size: clamp(28px, 4vw, 42px); font-weight: 700; color: var(--color-black); }
|
||||
.section-title-light { font-size: clamp(28px, 4vw, 42px); font-weight: 700; color: var(--color-white); }
|
||||
|
||||
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
|
||||
.feature-card {
|
||||
background: var(--color-white);
|
||||
border-radius: 16px;
|
||||
padding: 40px 28px;
|
||||
text-align: center;
|
||||
border: 1px solid rgba(0,0,0,0.05);
|
||||
transition: all 0.3s ease;
|
||||
animation: fadeUp 0.6s ease backwards;
|
||||
animation-delay: var(--delay);
|
||||
}
|
||||
.feature-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
.feature-icon { font-size: 48px; margin-bottom: 20px; }
|
||||
.feature-title { font-size: 20px; font-weight: 700; margin-bottom: 12px; color: var(--color-black); }
|
||||
.feature-desc { font-size: 14px; color: var(--color-gray-600); line-height: 1.6; }
|
||||
|
||||
.process-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 32px; }
|
||||
.step {
|
||||
text-align: center;
|
||||
padding: 32px 24px;
|
||||
background: rgba(255,255,255,0.03);
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
transition: all 0.3s ease;
|
||||
animation: fadeUp 0.6s ease backwards;
|
||||
animation-delay: var(--delay);
|
||||
}
|
||||
.step:hover { transform: translateY(-4px); border-color: var(--color-primary); }
|
||||
.step-num { display: block; font-family: var(--font-display); font-size: 48px; font-weight: 800; color: var(--color-primary); margin-bottom: 16px; }
|
||||
.step-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; color: var(--color-white); }
|
||||
.step-desc { font-size: 14px; color: rgba(255,255,255,0.5); line-height: 1.6; }
|
||||
|
||||
.cta-content { text-align: center; }
|
||||
.cta-title { font-size: clamp(28px, 4vw, 42px); font-weight: 800; margin-bottom: 16px; color: var(--color-black); }
|
||||
.cta-desc { font-size: 18px; color: rgba(0,0,0,0.7); margin-bottom: 32px; max-width: 500px; margin-left: auto; margin-right: auto; }
|
||||
.cta-actions { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
|
||||
.btn-dark { background: var(--color-dark); color: var(--color-white); }
|
||||
.btn-dark:hover { background: var(--color-dark-light); }
|
||||
.btn-outline-dark { background: transparent; color: var(--color-black); border: 2px solid var(--color-black); }
|
||||
.btn-outline-dark:hover { background: var(--color-black); color: var(--color-white); }
|
||||
.btn-lg { padding: 16px 36px; font-size: 16px; font-weight: 600; text-transform: uppercase; letter-spacing: 2px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
|
||||
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.features-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
.process-steps { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.features-grid, .process-steps { grid-template-columns: 1fr; }
|
||||
.usp-card { flex-direction: column; }
|
||||
.cta-actions { flex-direction: column; }
|
||||
.btn-lg { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user