feat: Implement S3 presigned URL resolution for CMS images across pages and apply minor styling adjustments to the header and hero sections.

This commit is contained in:
pradeepkumar
2026-03-05 05:51:57 +05:30
parent 9152bb818b
commit 724ce6a735
6 changed files with 74 additions and 18 deletions

View File

@@ -5,7 +5,7 @@ import { HeroSection } from '@/components/home/HeroSection';
import { FeaturesSection } from '@/components/home/FeaturesSection';
import { TopProfessionals } from '@/components/home/TopProfessionals';
import { TestimonialsSection } from '@/components/home/TestimonialsSection';
import { cmsService } from '@/services/cms.service';
import { cmsService, resolveImageUrl } from '@/services/cms.service';
import type { HeroContent, FeaturesContent, TopProfessionalsContent, TestimonialsContent, CmsContentRecord } from '@/types/cms';
export default function UserDashboard() {
@@ -15,9 +15,21 @@ export default function UserDashboard() {
const fetchCms = async () => {
const sections = await cmsService.getPageContent('landing');
const data: Record<string, unknown> = {};
sections.forEach((s: CmsContentRecord) => {
data[s.sectionKey] = s.content;
});
for (const s of sections) {
const content = s.content as Record<string, unknown>;
// Resolve S3 keys in image fields
if (s.sectionKey === 'features' && Array.isArray(content.features)) {
for (const feat of content.features as { iconPath?: string }[]) {
if (feat.iconPath) feat.iconPath = await resolveImageUrl(feat.iconPath);
}
}
if (s.sectionKey === 'testimonials' && Array.isArray(content.stats)) {
for (const stat of content.stats as { iconPath?: string }[]) {
if (stat.iconPath) stat.iconPath = await resolveImageUrl(stat.iconPath);
}
}
data[s.sectionKey] = content;
}
setCmsData(data);
};
fetchCms();

View File

@@ -6,7 +6,7 @@ import Link from 'next/link';
import { useSession } from 'next-auth/react';
import { CommonHeader } from '@/components/layout/CommonHeader';
import { Footer } from '@/components/layout/Footer';
import { cmsService } from '@/services/cms.service';
import { cmsService, resolveImageUrl } from '@/services/cms.service';
import type {
AboutHeroContent,
AboutStatsContent,
@@ -93,28 +93,43 @@ export default function AboutPage() {
const [cta, setCta] = useState<AboutCtaContent>(defaultCta);
useEffect(() => {
cmsService.getPageContent('about').then((sections) => {
sections.forEach((s: CmsContentRecord) => {
cmsService.getPageContent('about').then(async (sections) => {
for (const s of sections) {
const c = s.content as Record<string, unknown>;
// Only apply CMS content if it has meaningful data; otherwise keep defaults
switch (s.sectionKey) {
case 'hero':
if (c.headline || c.description) setHero(c as unknown as AboutHeroContent);
if (c.headline || c.description) {
const heroData = c as unknown as AboutHeroContent;
heroData.bannerImageUrl = await resolveImageUrl(heroData.bannerImageUrl);
setHero(heroData);
}
break;
case 'stats':
if (Array.isArray(c.stats) && c.stats.length > 0) setStats(c as unknown as AboutStatsContent);
break;
case 'features':
if (c.badge || (Array.isArray(c.features) && c.features.length > 0)) setFeatures(c as unknown as AboutFeaturesContent);
if (c.badge || (Array.isArray(c.features) && c.features.length > 0)) {
const featData = c as unknown as AboutFeaturesContent;
for (const feat of featData.features) {
feat.iconPath = await resolveImageUrl(feat.iconPath);
}
setFeatures(featData);
}
break;
case 'team':
if (Array.isArray(c.members) && c.members.length > 0) setTeam(c as unknown as AboutTeamContent);
if (Array.isArray(c.members) && c.members.length > 0) {
const teamData = c as unknown as AboutTeamContent;
for (const member of teamData.members) {
member.imageUrl = await resolveImageUrl(member.imageUrl);
}
setTeam(teamData);
}
break;
case 'cta':
if (c.title || c.description) setCta(c as unknown as AboutCtaContent);
break;
}
});
}
});
}, []);

View File

@@ -4,7 +4,7 @@ import Image from 'next/image';
import { useState, useEffect } from 'react';
import { CommonHeader } from '@/components/layout/CommonHeader';
import { Footer } from '@/components/layout/Footer';
import { cmsService } from '@/services/cms.service';
import { cmsService, resolveImageUrl } from '@/services/cms.service';
import { FaqContent, FaqCategoryItem, FaqItem, CmsContentRecord } from '@/types/cms';
const defaultCategories: FaqCategoryItem[] = [
@@ -91,6 +91,12 @@ export default function FAQPage() {
setCategories(cmsCategories);
}
if (content.faqs && content.faqs.length > 0) {
// Resolve S3 keys for FAQ icons
for (const faq of content.faqs) {
if (faq.icon) {
faq.icon = await resolveImageUrl(faq.icon);
}
}
setFaqs(content.faqs);
setExpandedFaq(content.faqs[0]?.id ?? null);
}