Skip to content

Commit d914ecd

Browse files
chore: data, types, functions, modular components (#63)
1 parent 1a30195 commit d914ecd

8 files changed

Lines changed: 114 additions & 64 deletions

File tree

src/components/Cards/product-card.tsx

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,46 +25,62 @@ export const ProductCard: React.FC<ProductCardProps> = ({
2525
return firstLetter;
2626
};
2727

28-
const productIcon = getProductIcon(title);
29-
3028
return (
3129
<div className="group relative">
32-
<div
33-
className="bg-white dark:bg-gray-800 rounded-xl overflow-hidden w-80 border border-gray-200
34-
dark:border-gray-700 transition-all duration-300 hover:shadow-md hover:shadow-blue-100 dark:hover:shadow-blue-900/30 hover:-translate-y-0.15"
35-
>
36-
<div className="bg-blue-50 dark:bg-blue-900/30 px-6 py-4">
30+
<div className="absolute -inset-0.5 bg-gradient-to-r from-blue-600/20 to-blue-400/20 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-300 blur-sm"></div>
31+
32+
<div className="relative bg-white dark:bg-gray-800 rounded-xl overflow-hidden w-80 border border-gray-200/60 dark:border-gray-700/60 backdrop-blur-sm transition-all duration-300 hover:shadow-xl hover:shadow-blue-100/50 dark:hover:shadow-blue-900/20 hover:-translate-y-1 hover:border-blue-200/40 dark:hover:border-blue-600/30">
33+
<div className="relative bg-gradient-to-br from-blue-50/80 via-blue-50/60 to-indigo-50/40 dark:from-blue-900/20 dark:via-blue-900/15 dark:to-indigo-900/10 px-6 py-5 border-b border-gray-100/80 dark:border-gray-700/50">
3734
<div className="flex items-center">
38-
<div className="w-8 h-8 bg-blue-200 dark:bg-blue-800 rounded-lg flex items-center justify-center mr-3">
39-
<span className="text-blue-700 dark:text-blue-300 font-semibold text-sm">
40-
{productIcon}
35+
<div className="relative w-10 h-10 bg-gradient-to-br from-blue-200/80 to-blue-300/60 dark:from-blue-700/60 dark:to-blue-600/40 rounded-xl flex items-center justify-center mr-4 shadow-sm">
36+
<span className="text-blue-700 dark:text-blue-200 font-bold text-base">
37+
{getProductIcon(title)}
4138
</span>
39+
<div className="absolute inset-0 bg-gradient-to-br from-white/20 to-transparent rounded-xl"></div>
4240
</div>
43-
<h3 className="text-lg font-semibold text-gray-800 dark:text-white">
41+
<h3 className="text-lg font-semibold text-gray-800 dark:text-white tracking-tight">
4442
{title}
4543
</h3>
4644
</div>
4745
</div>
4846

49-
<div className="p-6">
50-
<div className="mb-4">
51-
<h4 className="text-base font-semibold text-gray-900 dark:text-white mb-1">
52-
About
47+
<div className="p-6 space-y-4">
48+
<div className="space-y-2">
49+
<h4 className="text-sm font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
50+
Overview
5351
</h4>
52+
<div className="w-8 h-0.5 bg-gradient-to-r from-blue-400/60 to-transparent rounded-full"></div>
5453
</div>
5554

56-
<p className="text-sm text-gray-700 dark:text-gray-300 leading-relaxed mb-6">
55+
<p
56+
className="text-md text-gray-600 dark:text-gray-300 leading-relaxed line-clamp-3"
57+
title={description}
58+
>
5759
{description}
5860
</p>
5961

60-
<div className="flex justify-end">
62+
<div className="pt-2">
6163
<Button
62-
className="bg-blue-400 hover:bg-blue-500 dark:bg-blue-600 dark:hover:bg-blue-700 text-white text-sm
63-
px-6 py-2.5 rounded-full font-medium transition-colors duration-200 shadow-sm hover:shadow-md cursor-pointer"
64+
className="w-full bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 dark:from-blue-600 dark:to-blue-700 dark:hover:from-blue-700 dark:hover:to-blue-800 text-white text-sm px-6 py-2.5 rounded-lg font-medium transition-all duration-200 shadow-sm hover:shadow-md hover:scale-[1.02] active:scale-[0.98]"
6465
onClick={handleDemoButtonClick}
65-
title="View Demo"
66+
title={`View ${title} Demo`}
6667
>
67-
Demo
68+
<span className="flex items-center justify-center gap-2">
69+
Explore Demo
70+
<svg
71+
className="w-4 h-4 transition-transform group-hover:translate-x-0.5"
72+
fill="none"
73+
stroke="currentColor"
74+
viewBox="0 0 24 24"
75+
>
76+
<path
77+
strokeLinecap="round"
78+
strokeLinejoin="round"
79+
strokeWidth={2}
80+
d="M13 7l5 5m0 0l-5 5m5-5H6"
81+
/>
82+
</svg>
83+
</span>
6884
</Button>
6985
</div>
7086
</div>

src/data/productCardData.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,10 @@ export const products = [
1515
'Next-generation financial platform built with modern architecture for enhanced scalability and performance.',
1616
},
1717
];
18+
19+
export const platformDemos = [
20+
{
21+
title: 'Platform_Demos',
22+
description: 'Mmore than one product or non-product demos',
23+
},
24+
];

src/lib/demofileparser/getBaseUrl.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
export const mapUrl = new Map<string, string>([
2-
['http://mifos.mifos.gazelle.test', 'MifosX'],
3-
['https://ops.mifos.gazelle.test', 'PHEE'],
4-
['http://vnextadmin.mifos.gazelle.test', 'Vnext'],
5-
]);
1+
import { mapUrl } from '@/types/demodata';
62

73
export const getUniqueBaseUrls = (
84
url: string,

src/pages/Home.tsx

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ProductCard } from '@/components/Cards/product-card';
2-
import { products } from '@/data/productCardData';
2+
import { platformDemos, products } from '@/data/productCardData';
33

44
export const Home = () => {
55
return (
@@ -78,21 +78,40 @@ export const Home = () => {
7878
</section>
7979

8080
<section id="demos" className="relative py-24 px-6">
81-
<div className="max-w-7xl mx-auto">
82-
<div className="text-center mb-16">
83-
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-8 text-center">
84-
Explore Product Demos
85-
</h2>
81+
<div className="max-w-7xl mx-auto flex flex-col gap-24">
82+
<div>
83+
<div className="text-center mb-16">
84+
<h2 className="text-4xl font-bold text-gray-900 dark:text-white mb-8 text-center">
85+
Explore Product Demos
86+
</h2>
87+
</div>
88+
89+
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-16 justify-items-center mt-14">
90+
{products.map((product, index) => (
91+
<ProductCard
92+
key={index}
93+
title={product.title}
94+
description={product.description}
95+
/>
96+
))}
97+
</div>
8698
</div>
99+
<div>
100+
<div className="text-center mb-16">
101+
<h2 className="text-4xl font-bold text-gray-900 dark:text-white mb-8 text-center">
102+
Explore Platform Demos
103+
</h2>
104+
</div>
87105

88-
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-16 justify-items-center mt-14">
89-
{products.map((product, index) => (
90-
<ProductCard
91-
key={index}
92-
title={product.title}
93-
description={product.description}
94-
/>
95-
))}
106+
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-16 justify-items-center mt-14">
107+
{platformDemos.map((product, index) => (
108+
<ProductCard
109+
key={index}
110+
title={product.title}
111+
description={product.description}
112+
/>
113+
))}
114+
</div>
96115
</div>
97116
</div>
98117
</section>

src/pages/demo-list/platform-demos.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,8 @@ import {
3131
} from '@/components/ui/dropdown-menu';
3232
// import { fetchDemoListData } from '@/lib/api/fetchDemoListData';
3333
import { SamplePlatformDemoData } from '@/data/sample-platform-demos';
34-
35-
interface DemoData {
36-
demoID: string;
37-
demoName: string;
38-
demoDescription: string;
39-
platforms: string[];
40-
}
34+
import type { PlatformDemoData as DemoData } from '@/types/demodata';
35+
import { allPlatforms } from '@/types/demodata';
4136

4237
const columnHelper = createColumnHelper<DemoData>();
4338

@@ -51,7 +46,6 @@ export default function PlatformDemos() {
5146
// const [data, setData] = useState<DemoData[]>([]);
5247
const [loading, setLoading] = useState(true);
5348
const [selectedPlatforms, setSelectedPlatforms] = useState<string[]>([]);
54-
const allPlatforms = ['MifosX', 'PHEE', 'Vnext'];
5549

5650
useEffect(() => {
5751
setLoading(true);

src/pages/demo-list/product-demos.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,13 @@ import { useNavigate } from 'react-router-dom';
2222
import slugify from 'slugify';
2323
// import { fetchDemoListData } from '@/lib/api/fetchDemoListData';
2424
import { DemoSampleData } from '@/data/DemoTableSampleData';
25-
26-
interface DemoData {
27-
demoID: string;
28-
demoName: string;
29-
demoDescription: string;
30-
}
25+
import type {
26+
ProductDemoData as DemoData,
27+
ProductDemosProps,
28+
} from '@/types/demodata';
3129

3230
const columnHelper = createColumnHelper<DemoData>();
3331

34-
type ProductDemosProps = {
35-
product: 'mifosx' | 'phee' | 'vnext';
36-
};
37-
3832
export default function ProductDemos({ product }: ProductDemosProps) {
3933
const navigate = useNavigate();
4034
const NavigateToDemo = (id: string, demoName: string) => {

src/pages/demo/demo-page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
// import { fetchDemoData } from '@/lib/api/fetchDemoData';
1212
import { SamplePlatformDemo } from '@/data/platform-demo';
1313
import { Button } from '@/components/ui/button';
14-
import { getUniqueBaseUrls, mapUrl } from '@/lib/demofileparser/getBaseUrl';
14+
import { getUniqueBaseUrls } from '@/lib/demofileparser/getBaseUrl';
15+
import { mapUrl } from '@/types/demodata';
1516

1617
interface Step {
1718
title: string;
@@ -31,6 +32,10 @@ export const DemoPage = () => {
3132
const [isLoading, setIsLoading] = useState(true);
3233
const [activeBaseUrl, setActiveBaseUrl] = useState<string>('');
3334
const firstStepUrl = SamplePlatformDemo?.steps[0].url;
35+
const [currentStep, setCurrentStep] = useState(0);
36+
const [iframeUrl, setIframeUrl] = useState('');
37+
const [isAutoPlay, setIsAutoPlay] = useState(false);
38+
const [isTransitioning, setIsTransitioning] = useState(false);
3439
const [baseUrls, setBaseUrls] = useState<Map<string, string>>(
3540
firstStepUrl
3641
? new Map([[firstStepUrl, firstStepUrl]])
@@ -59,11 +64,6 @@ export const DemoPage = () => {
5964
setActiveBaseUrl(initialBaseUrl);
6065
}, []);
6166

62-
const [currentStep, setCurrentStep] = useState(0);
63-
const [iframeUrl, setIframeUrl] = useState('');
64-
const [isAutoPlay, setIsAutoPlay] = useState(false);
65-
const [isTransitioning, setIsTransitioning] = useState(false);
66-
6767
useEffect(() => {
6868
let interval: NodeJS.Timeout;
6969
if (isAutoPlay && demoData) {

src/types/demodata.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export interface ProductDemoData {
2+
demoID: string;
3+
demoName: string;
4+
demoDescription: string;
5+
}
6+
7+
export type ProductDemosProps = {
8+
product: 'mifosx' | 'phee' | 'vnext';
9+
};
10+
11+
export interface PlatformDemoData {
12+
demoID: string;
13+
demoName: string;
14+
demoDescription: string;
15+
platforms: string[];
16+
}
17+
18+
export const allPlatforms = ['MifosX', 'PHEE', 'Vnext'];
19+
20+
export const mapUrl = new Map<string, string>([
21+
['http://mifos.mifos.gazelle.test', 'MifosX'],
22+
['https://ops.mifos.gazelle.test', 'PHEE'],
23+
['http://vnextadmin.mifos.gazelle.test', 'Vnext'],
24+
]);

0 commit comments

Comments
 (0)