Skip to content

Commit 4adce0d

Browse files
Created dynamic routes for product demos, use lazy loading for optimization (#16)
1 parent aebd2c2 commit 4adce0d

12 files changed

Lines changed: 198 additions & 72 deletions

File tree

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/gazelle.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>Vite + React + TS</title>
7+
<title>Mifos Product Demo</title>
88
</head>
99
<body>
1010
<div id="root"></div>

package-lock.json

Lines changed: 54 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"lucide-react": "^0.522.0",
1818
"react": "^19.1.0",
1919
"react-dom": "^19.1.0",
20+
"react-router-dom": "^7.6.2",
2021
"tailwind-merge": "^3.3.1",
2122
"tailwindcss": "^4.1.10"
2223
},

src/App.tsx

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,13 @@
1-
import { ProductCard } from "./components/Cards/product-card";
2-
import { products } from "./data/productCardData";
31

4-
const App = () => {
2+
import { BrowserRouter } from "react-router-dom";
53

4+
import { AppRoutes } from "./routes/AppRoutes";
5+
const App = () => {
66
return (
7-
<div className="min-h-screen bg-gradient-to-br from-gray-50 via-white to-gray-50 dark:from-gray-900 dark:via-gray-900 dark:to-gray-800">
8-
<div className="pt-16 pb-16 px-6">
9-
<div className="max-w-7xl mx-auto text-center">
10-
<div className="inline-flex items-center bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 px-4 py-2 rounded-full text-sm font-medium mb-8">
11-
<span className="w-2 h-2 bg-blue-400 dark:bg-blue-500 rounded-full mr-2"></span>
12-
Product Demo Platform
13-
</div>
14-
15-
<h1 className="text-5xl md:text-6xl font-bold text-gray-900 dark:text-white mb-8 leading-tight">
16-
Welcome to the Mifos
17-
<br />
18-
<span className="bg-gradient-to-r from-blue-600 to-blue-500 dark:from-blue-400 dark:to-blue-300 bg-clip-text text-transparent">
19-
Product Demo Explorer
20-
</span>
21-
<div className="flex justify-center mt-0.5">
22-
<svg height="16" width="180" viewBox="0 0 180 16" fill="none" xmlns="http://www.w3.org/2000/svg">
23-
<path d="M2 8 Q 30 16, 60 8 T 120 8 T 178 8" stroke="#60a5fa" strokeWidth="3" fill="none" opacity="0.5" strokeLinecap="round"/>
24-
</svg>
25-
</div>
26-
</h1>
27-
28-
<p className="text-xl text-gray-600 dark:text-gray-300 max-w-3xl mx-auto leading-relaxed font-light">
29-
Experience interactive demonstrations of our products — MifosX, Phee, and VNext.
30-
Explore comprehensive step-by-step guides designed to showcase the full potential of our financial technology solutions.
31-
</p>
32-
</div>
33-
</div>
34-
35-
<div className="pb-24 px-6 pt-10">
36-
<div className="max-w-7xl mx-auto">
37-
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-8 justify-items-center">
38-
{products.map((product, index) => (
39-
<ProductCard
40-
key={index}
41-
title={product.title}
42-
description={product.description}
43-
/>
44-
))}
45-
</div>
46-
</div>
47-
</div>
48-
49-
50-
</div>
7+
<BrowserRouter>
8+
<AppRoutes/>
9+
</BrowserRouter>
5110
);
5211
};
5312

54-
export default App;
13+
export default App;

src/components/Cards/product-card.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { Button } from '../ui/button';
3+
import { useNavigate } from 'react-router-dom';
34

45
interface ProductCardProps {
56
title: string;
@@ -12,10 +13,16 @@ interface ProductCardProps {
1213
export const ProductCard: React.FC<ProductCardProps> = ({
1314
title = "MifosX",
1415
description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor",
15-
onDemoClick = () => console.log('Demo clicked')
16+
1617
}) => {
18+
const navigate = useNavigate();
19+
20+
const handleDemoButtonClick = ()=>{
21+
navigate(`/demos/${title.toLowerCase()}`);
22+
}
1723
return (
18-
<div className="bg-white dark:bg-gray-800 rounded-xl overflow-hidden w-80 border border-gray-200 dark:border-gray-700 transition-all duration-300 hover:shadow-xl hover:shadow-blue-200 dark:hover:shadow-blue-900/30 hover:-translate-y-0.15">
24+
<div className="bg-white dark:bg-gray-800 rounded-xl overflow-hidden w-80 border border-gray-200
25+
dark:border-gray-700 transition-all duration-300 hover:shadow-xl hover:shadow-blue-200 dark:hover:shadow-blue-900/30 hover:-translate-y-0.15">
1926
<div className="bg-blue-50 dark:bg-blue-900/30 px-6 py-4">
2027
<div className="flex items-center">
2128
<div className="w-8 h-8 bg-blue-200 dark:bg-blue-800 rounded-lg flex items-center justify-center mr-3">
@@ -35,7 +42,8 @@ export const ProductCard: React.FC<ProductCardProps> = ({
3542
<div className="absolute -bottom-1 left-1/2 transform -translate-x-1/2 w-2 h-2 bg-gray-400 dark:bg-gray-600"></div>
3643
<div className="absolute -left-1 top-1/2 transform -translate-y-1/2 w-2 h-2 bg-gray-400 dark:bg-gray-600"></div>
3744
<div className="absolute -right-1 top-1/2 transform -translate-y-1/2 w-2 h-2 bg-gray-400 dark:bg-gray-600"></div>
38-
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-3 h-3 bg-blue-50 dark:bg-blue-900/30 rounded-full"></div>
45+
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-3 h-3 bg-blue-50
46+
dark:bg-blue-900/30 rounded-full"></div>
3947
</div>
4048
</div>
4149

@@ -54,8 +62,8 @@ export const ProductCard: React.FC<ProductCardProps> = ({
5462

5563
<div className="flex justify-end">
5664
<Button
57-
onClick={onDemoClick}
5865
className="bg-blue-400 hover:bg-blue-500 dark:bg-blue-600 dark:hover:bg-blue-700 text-white text-sm px-6 py-2.5 rounded-full font-medium transition-colors duration-200 shadow-sm hover:shadow-md cursor-pointer"
66+
onClick={handleDemoButtonClick}
5967
>
6068
Demo
6169
</Button>

src/components/Footer/footer.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export const Footer = () => {
2+
return(
3+
<div className="bg-white dark:bg-gray-900 py-12 px-6 border-t border-gray-200 dark:border-white">
4+
<div className="max-w-7xl mx-auto text-center">
5+
<p className="text-gray-500 dark:text-gray-400 text-sm mb-8">
6+
Discover the power of open-source financial technology solutions
7+
</p>
8+
<div className="flex justify-center">
9+
<img
10+
src="/gazelle.svg"
11+
alt="Mifos Logo"
12+
width={80}
13+
height={80}
14+
className="opacity-80 dark:opacity-90"
15+
/>
16+
</div>
17+
</div>
18+
</div>
19+
)
20+
}

src/components/Navigation/SideNav.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { Home } from "lucide-react";
22

33
export const SideNav = () => {
44
return (
5-
<div className="h-screen w-14 bg-white dark:bg-gray-900 flex flex-col items-center border-r-2 border-gray-200 dark:border-gray-700">
5+
<div className="h-screen w-14 bg-white dark:bg-gray-900 flex flex-col items-center border-r-2 border-gray-200
6+
dark:border-gray-700">
67
<div className="logo h-14 w-full flex items-center justify-center border-b-2 border-gray-200 dark:border-gray-700">
78
<div className="p-1 rounded-full">
89
<img

src/main.tsx

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,23 @@ import App from "./App.tsx";
55
import { SideNav } from "./components/Navigation/SideNav.tsx";
66
import { TopNav } from "./components/Navigation/TopNav.tsx";
77
import { ThemeProvider } from "./context/ThemeContext";
8+
import { Footer } from "./components/Footer/footer.tsx";
89

910
createRoot(document.getElementById("root")!).render(
1011
<StrictMode>
1112
<ThemeProvider>
12-
<div className="h-screen w-screen overflow-hidden bg-[#1579EB] dark:bg-gray-900">
13+
<div className="h-screen w-screen overflow-hidden dark:bg-gray-900">
1314
<div className="fixed top-0 left-14 right-0 h-14 bg-[#1579EB] z-10">
1415
<TopNav title="Mifos Product Demo" />
1516
</div>
1617
<div className="fixed top-0 left-0 w-14 h-screen bg-white dark:bg-gray-900 z-10">
1718
<SideNav />
1819
</div>
19-
<div className="ml-14 mt-14 h-[calc(100vh-3.5rem)] overflow-auto">
20-
<App />
21-
<div className="bg-white dark:bg-gray-900 py-12 px-6 border-t border-gray-200 dark:border-white">
22-
<div className="max-w-7xl mx-auto text-center">
23-
<p className="text-gray-500 dark:text-gray-400 text-sm mb-8">
24-
Discover the power of open-source financial technology solutions
25-
</p>
26-
<div className="flex justify-center">
27-
<img
28-
src="/gazelle.svg"
29-
alt="Mifos Logo"
30-
width={80}
31-
height={80}
32-
className="opacity-80 dark:opacity-90"
33-
/>
34-
</div>
35-
</div>
20+
<div className="ml-14 mt-14 h-[calc(100vh-3.5rem)] overflow-auto flex flex-col">
21+
<div className="flex-grow">
22+
<App />
3623
</div>
24+
<Footer />
3725
</div>
3826
</div>
3927
</ThemeProvider>

src/pages/Home.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { ProductCard } from "@/components/Cards/product-card"
2+
import { products } from "@/data/productCardData";
3+
4+
5+
export const Home = () => {
6+
return (
7+
<div className="min-h-screen bg-gradient-to-br from-gray-50 via-white to-gray-50 dark:from-gray-900
8+
dark:via-gray-900 dark:to-gray-800">
9+
<div className="pt-16 pb-16 px-6">
10+
<div className="max-w-7xl mx-auto text-center">
11+
<div className="inline-flex items-center bg-blue-50 dark:bg-blue-900/30 text-blue-700
12+
dark:text-blue-300 px-4 py-2 rounded-full text-sm font-medium mb-8">
13+
<span className="w-2 h-2 bg-blue-400 dark:bg-blue-500 rounded-full mr-2"></span>
14+
Product Demo Platform
15+
</div>
16+
17+
<h1 className="text-5xl md:text-6xl font-bold text-gray-900 dark:text-white mb-8 leading-tight">
18+
Welcome to the Mifos
19+
<br />
20+
<span className="bg-gradient-to-r from-blue-600 to-blue-500 dark:from-blue-400 dark:to-blue-300
21+
bg-clip-text text-transparent">
22+
Product Demo Explorer
23+
</span>
24+
<div className="flex justify-center mt-0.5">
25+
<svg height="16" width="180" viewBox="0 0 180 16" fill="none" xmlns="http://www.w3.org/2000/svg">
26+
<path d="M2 8 Q 30 16, 60 8 T 120 8 T 178 8" stroke="#60a5fa" strokeWidth="3" fill="none" opacity="0.5"
27+
strokeLinecap="round"/>
28+
</svg>
29+
</div>
30+
</h1>
31+
32+
<p className="text-xl text-gray-600 dark:text-gray-300 max-w-3xl mx-auto leading-relaxed font-light">
33+
Experience interactive demonstrations of our products — MifosX, Phee, and VNext.
34+
Explore comprehensive step-by-step guides designed to showcase the full potential of our financial technology solutions.
35+
</p>
36+
</div>
37+
</div>
38+
39+
<div className="pb-24 px-6 pt-10">
40+
<div className="max-w-7xl mx-auto">
41+
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-8 justify-items-center">
42+
{products.map((product, index) => (
43+
<ProductCard
44+
key={index}
45+
title={product.title}
46+
description={product.description}
47+
/>
48+
))}
49+
</div>
50+
</div>
51+
</div>
52+
53+
54+
</div>
55+
)
56+
}

src/pages/demo/DemoList.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { lazy, Suspense } from "react";
2+
import { useParams } from "react-router-dom";
3+
4+
const demoComponentMap: Record<string, React.LazyExoticComponent<React.FC>> = {
5+
mifosx: lazy(() => import("./mifosx")),
6+
// phee: lazy(() => import("./phee")),
7+
// vnext: lazy(() => import("./vnext")),
8+
};
9+
10+
export const DemoList = () => {
11+
const { product } = useParams();
12+
13+
const Component = product ? demoComponentMap[product] : null;
14+
15+
return (
16+
<Suspense fallback={<div className="p-6 text-center">Loading demo...</div>}>
17+
{Component ? <Component /> : <div className="p-6 text-center text-red-500">Invalid demo: {product}</div>}
18+
</Suspense>
19+
);
20+
};

0 commit comments

Comments
 (0)