179 lines
6.5 KiB
TypeScript
179 lines
6.5 KiB
TypeScript
"use client";
|
|
import { useState, useEffect, useMemo } from "react";
|
|
import Image from "next/legacy/image";
|
|
import Link from "next/link";
|
|
import { getValidImageUrl, FALLBACK_IMAGES } from "@/lib/imageUtils";
|
|
import { useCaseStudies } from "@/lib/hooks/useCaseStudy";
|
|
import { API_CONFIG } from "@/lib/config/api";
|
|
|
|
const Story = () => {
|
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
const [activeImageIndex, setActiveImageIndex] = useState(0);
|
|
|
|
// Fetch case studies from API with ordering and limit
|
|
const params = useMemo(() => ({
|
|
ordering: 'display_order',
|
|
page_size: 5
|
|
}), []);
|
|
|
|
const { caseStudies, loading, error } = useCaseStudies(params);
|
|
|
|
// Fallback to static data if API fails or is loading
|
|
const staticStoryData = [
|
|
{
|
|
id: 1,
|
|
category_name: "Financial Services",
|
|
title: "Banking System Modernization",
|
|
excerpt: "Complete digital transformation of legacy banking systems with enhanced security and real-time processing capabilities.",
|
|
thumbnail: "/images/case/one.png",
|
|
slug: "banking-system-modernization",
|
|
display_order: 1,
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString()
|
|
},
|
|
{
|
|
id: 2,
|
|
category_name: "Healthcare",
|
|
title: "Patient Management System",
|
|
excerpt: "Enterprise-grade patient management system with HIPAA compliance and seamless integration across multiple healthcare facilities.",
|
|
thumbnail: "/images/case/two.png",
|
|
slug: "patient-management-system",
|
|
display_order: 2,
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString()
|
|
},
|
|
{
|
|
id: 3,
|
|
category_name: "Manufacturing",
|
|
title: "Supply Chain Optimization",
|
|
excerpt: "Advanced supply chain management system with real-time tracking, predictive analytics, and automated inventory management.",
|
|
thumbnail: "/images/case/three.png",
|
|
slug: "supply-chain-optimization",
|
|
display_order: 3,
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString()
|
|
},
|
|
{
|
|
id: 4,
|
|
category_name: "E-commerce",
|
|
title: "Multi-Platform Integration",
|
|
excerpt: "Seamless integration of multiple e-commerce platforms with unified inventory management and real-time synchronization.",
|
|
thumbnail: "/images/case/four.png",
|
|
slug: "multi-platform-integration",
|
|
display_order: 4,
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString()
|
|
},
|
|
{
|
|
id: 5,
|
|
category_name: "Education",
|
|
title: "Learning Management System",
|
|
excerpt: "Comprehensive LMS with advanced analytics, automated grading, and seamless integration with existing educational tools.",
|
|
thumbnail: "/images/case/five.png",
|
|
slug: "learning-management-system",
|
|
display_order: 5,
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString()
|
|
}
|
|
];
|
|
|
|
// Use API data if available, otherwise use static data
|
|
const storyData = caseStudies.length > 0 ? caseStudies : staticStoryData;
|
|
|
|
// Log when API data is loaded
|
|
useEffect(() => {
|
|
if (caseStudies.length > 0) {
|
|
console.log('Case studies loaded from API:', caseStudies.length);
|
|
}
|
|
}, [caseStudies]);
|
|
|
|
const handleMouseEnter = (index: number) => {
|
|
setActiveIndex(index);
|
|
setActiveImageIndex(index);
|
|
};
|
|
|
|
|
|
return (
|
|
<section className="tp-story pt-120 pb-120 bg-black sticky-wrapper fade-wrapper">
|
|
<div className="container">
|
|
<div className="row vertical-column-gap-md">
|
|
<div className="col-12 col-lg-5">
|
|
<div className="tp-story__content sticky-item">
|
|
<h2 className="mt-8 title-anim text-white fw-7">
|
|
Enterprise Case Studies
|
|
</h2>
|
|
<div className="tp-story__items">
|
|
{storyData.map((item, index) => {
|
|
return (
|
|
<div
|
|
key={index}
|
|
className={`tp-story__single fade-top ${
|
|
index === activeIndex ? "active" : ""
|
|
}`}
|
|
onMouseEnter={() => handleMouseEnter(index)}
|
|
>
|
|
<p className="fw-6 mt-8">
|
|
<Link href={`/case-study/${item.slug}`}>
|
|
{item.category_name || "Case Study"}
|
|
</Link>
|
|
</p>
|
|
<h5 className="fw-4 mt-12 mb-12 text-white">
|
|
{item.title}
|
|
</h5>
|
|
<p className="text-xs">{item.excerpt}</p>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-12 col-lg-7 col-xxl-6 offset-xxl-1 d-none d-lg-block">
|
|
<div className="tp-story__thumbs sticky-item">
|
|
{storyData.map((item, index) => {
|
|
// Get the image URL - handle different scenarios
|
|
let imageUrl;
|
|
if (item.thumbnail) {
|
|
if (item.thumbnail.startsWith('http')) {
|
|
// Full URL (external)
|
|
imageUrl = item.thumbnail;
|
|
} else if (item.thumbnail.startsWith('/media')) {
|
|
// Relative path starting with /media
|
|
imageUrl = `${API_CONFIG.BASE_URL}${item.thumbnail}`;
|
|
} else {
|
|
// Just filename or relative path
|
|
imageUrl = `${API_CONFIG.MEDIA_URL}/${item.thumbnail}`;
|
|
}
|
|
console.log('Case study image URL:', item.title, '→', imageUrl);
|
|
} else {
|
|
// Fallback to static image
|
|
imageUrl = getValidImageUrl('/images/case/one.png', FALLBACK_IMAGES.CASE_STUDY);
|
|
console.log('Using fallback image for:', item.title);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
key={index}
|
|
className={`tp-story-thumb ${
|
|
index === activeImageIndex ? "thumb-active" : ""
|
|
}`}
|
|
>
|
|
<Image
|
|
src={imageUrl}
|
|
width={600}
|
|
height={300}
|
|
className="w-100 mh-300"
|
|
alt={item.title || "Case Study"}
|
|
/>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default Story;
|