7 Commits

Author SHA1 Message Date
00f477b7a9 Merge version_2 into main
Merge version_2 into main
2026-06-05 12:19:36 +00:00
83ae5b9524 Update src/app/page.tsx 2026-06-05 12:19:33 +00:00
2bd54da73f Merge version_2 into main
Merge version_2 into main
2026-06-05 12:19:12 +00:00
e82b3f1d81 Add src/app/types/portfolio.ts 2026-06-05 12:19:09 +00:00
7ccbec2976 Update src/app/page.tsx 2026-06-05 12:19:09 +00:00
b5e7520f7a Add src/app/lib/github.ts 2026-06-05 12:19:08 +00:00
7f2d5e1957 Add src/app/hooks/usePortfolioData.ts 2026-06-05 12:19:08 +00:00
4 changed files with 132 additions and 133 deletions

View File

@@ -0,0 +1,44 @@
"use client";
import { useState, useEffect, useCallback } from 'react';
import { PortfolioData } from '@/app/types/portfolio';
import { fetchGithubJsonFile } from '@/app/lib/github';
interface UsePortfolioDataResult {
portfolio: PortfolioData | null;
loading: boolean;
error: string | null;
refetch: () => void;
}
const PORTFOLIO_DATA_PATH = 'portfolio.json'; // Assumed filename for structured portfolio data within the repository
export function usePortfolioData(): UsePortfolioDataResult {
const [portfolio, setPortfolio] = useState<PortfolioData | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const fetchData = useCallback(async () => {
setLoading(true);
setError(null);
try {
const data = await fetchGithubJsonFile<PortfolioData>(PORTFOLIO_DATA_PATH);
if (data) {
setPortfolio(data);
} else {
setError('Could not fetch portfolio data. Check repository path or file content.');
}
} catch (err) {
setError('Failed to load portfolio data.');
console.error('Error in usePortfolioData:', err);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchData();
}, [fetchData]);
return { portfolio, loading, error, refetch: fetchData };
}

25
src/app/lib/github.ts Normal file
View File

@@ -0,0 +1,25 @@
const GITHUB_REPO_OWNER = 'MamunFarhat';
const GITHUB_REPO_NAME = 'aboutmamun';
const GITHUB_API_BASE_URL = `https://api.github.com/repos/${GITHUB_REPO_OWNER}/${GITHUB_REPO_NAME}`;
export async function fetchGithubJsonFile<T>(path: string): Promise<T | null> {
try {
const response = await fetch(`${GITHUB_API_BASE_URL}/contents/${path}`, {
headers: {
'Accept': 'application/vnd.github.v3.raw' // Request raw content
}
});
if (!response.ok) {
console.error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
return null;
}
const textContent = await response.text();
return JSON.parse(textContent) as T;
} catch (error) {
console.error(`Error fetching GitHub JSON file from ${path}:`, error);
return null;
}
}

View File

@@ -60,21 +60,11 @@ export default function LandscapingPage() {
textPosition="top"
testimonials={[
{
name: "Sarah M.",
handle: "Homeowner",
testimonial: "GreenScape completely transformed our backyard. The team was professional, creative, and delivered beyond our expectations.",
rating: 5,
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/web-agency-2/team-2.jpg",
imageAlt: "Sarah M.",
},
name: "Sarah M.", handle: "Homeowner", testimonial: "GreenScape completely transformed our backyard. The team was professional, creative, and delivered beyond our expectations.", rating: 5,
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/web-agency-2/team-2.jpg", imageAlt: "Sarah M."},
{
name: "David K.",
handle: "Property Manager",
testimonial: "We've used GreenScape for all our commercial properties. Their maintenance plans keep everything looking pristine year-round.",
rating: 5,
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/web-agency-2/team-1.jpg",
imageAlt: "David K.",
},
name: "David K.", handle: "Property Manager", testimonial: "We've used GreenScape for all our commercial properties. Their maintenance plans keep everything looking pristine year-round.", rating: 5,
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/web-agency-2/team-1.jpg", imageAlt: "David K."},
]}
/>
</div>
@@ -106,37 +96,13 @@ export default function LandscapingPage() {
imageContainerClassName="!rotate-0 !aspect-square"
features={[
{
tag: "Design",
title: "Landscape Design",
subtitle: "Custom Plans",
description: "We create tailored landscape designs that complement your property's architecture and your personal style.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-2.jpg",
imageAlt: "Landscape design",
},
tag: "Design", title: "Landscape Design", subtitle: "Custom Plans", description: "We create tailored landscape designs that complement your property's architecture and your personal style.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-2.jpg", imageAlt: "Landscape design"},
{
tag: "Installation",
title: "Hardscape & Softscape",
subtitle: "Full Installation",
description: "From patios and walkways to gardens and trees, we handle the complete installation process.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-3.jpg",
imageAlt: "Hardscape installation",
},
tag: "Installation", title: "Hardscape & Softscape", subtitle: "Full Installation", description: "From patios and walkways to gardens and trees, we handle the complete installation process.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-3.jpg", imageAlt: "Hardscape installation"},
{
tag: "Maintenance",
title: "Lawn & Garden Care",
subtitle: "Ongoing Service",
description: "Keep your property looking pristine year-round with our professional maintenance plans.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-4.jpg",
imageAlt: "Lawn maintenance",
},
tag: "Maintenance", title: "Lawn & Garden Care", subtitle: "Ongoing Service", description: "Keep your property looking pristine year-round with our professional maintenance plans.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-4.jpg?_wi=1", imageAlt: "Lawn maintenance"},
{
tag: "Irrigation",
title: "Smart Irrigation",
subtitle: "Water Management",
description: "Efficient irrigation systems that keep your landscape healthy while conserving water.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-5.jpg",
imageAlt: "Irrigation system",
},
tag: "Irrigation", title: "Smart Irrigation", subtitle: "Water Management", description: "Efficient irrigation systems that keep your landscape healthy while conserving water.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-5.jpg", imageAlt: "Irrigation system"},
]}
/>
</div>
@@ -148,29 +114,14 @@ export default function LandscapingPage() {
textboxLayout="default"
useInvertedBackground={false}
gridVariant="uniform-all-items-equal"
animationType="slide-up"
animationType="depth-3d"
members={[
{
id: "1",
name: "Expert Craftsmanship",
role: "Decades of combined experience in landscape design and installation.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-6.jpg",
imageAlt: "Expert craftsmanship",
},
id: "1", name: "Expert Craftsmanship", role: "Decades of combined experience in landscape design and installation.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-6.jpg", imageAlt: "Expert craftsmanship"},
{
id: "2",
name: "Eco-Friendly Approach",
role: "Sustainable practices and native plant selections that thrive naturally.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-7.jpg",
imageAlt: "Eco-friendly landscaping",
},
id: "2", name: "Eco-Friendly Approach", role: "Sustainable practices and native plant selections that thrive naturally.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-7.jpg", imageAlt: "Eco-friendly landscaping"},
{
id: "3",
name: "Full-Service Care",
role: "From initial design to ongoing maintenance, we handle everything.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-8.jpg",
imageAlt: "Full-service care",
},
id: "3", name: "Full-Service Care", role: "From initial design to ongoing maintenance, we handle everything.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-8.jpg", imageAlt: "Full-service care"},
]}
/>
</div>
@@ -186,26 +137,11 @@ export default function LandscapingPage() {
animationType="slide-up"
members={[
{
id: "1",
name: "James Carter",
role: "Lead Designer",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-11.jpg",
imageAlt: "James Carter",
},
id: "1", name: "James Carter", role: "Lead Designer", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-11.jpg?_wi=1", imageAlt: "James Carter"},
{
id: "2",
name: "Maria Silva",
role: "Horticulturist",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-10.jpg",
imageAlt: "Maria Silva",
},
id: "2", name: "Maria Silva", role: "Horticulturist", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-10.jpg?_wi=1", imageAlt: "Maria Silva"},
{
id: "3",
name: "Ryan Mitchell",
role: "Project Manager",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-9.jpg",
imageAlt: "Ryan Mitchell",
},
id: "3", name: "Ryan Mitchell", role: "Project Manager", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-9.jpg?_wi=1", imageAlt: "Ryan Mitchell"},
]}
/>
</div>
@@ -221,29 +157,13 @@ export default function LandscapingPage() {
useInvertedBackground={false}
testimonials={[
{
id: "1",
name: "Sarah M.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-10.jpg",
imageAlt: "Sarah M.",
},
id: "1", name: "Sarah M.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-10.jpg?_wi=2", imageAlt: "Sarah M."},
{
id: "2",
name: "David K.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-11.jpg",
imageAlt: "David K.",
},
id: "2", name: "David K.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-11.jpg?_wi=2", imageAlt: "David K."},
{
id: "3",
name: "Emily R.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-4.jpg",
imageAlt: "Emily R.",
},
id: "3", name: "Emily R.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-4.jpg?_wi=2", imageAlt: "Emily R."},
{
id: "4",
name: "Ryan M.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-9.jpg",
imageAlt: "Ryan M.",
},
id: "4", name: "Ryan M.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/default/templates/landscaping/img-9.jpg?_wi=2", imageAlt: "Ryan M."},
]}
/>
</div>
@@ -258,35 +178,17 @@ export default function LandscapingPage() {
faqsAnimation="slide-up"
faqs={[
{
id: "1",
title: "How long does a typical landscaping project take?",
content: "Most residential projects take 1-3 weeks depending on scope. We'll provide a detailed timeline during your consultation so you know exactly what to expect.",
},
id: "1", title: "How long does a typical landscaping project take?", content: "Most residential projects take 1-3 weeks depending on scope. We'll provide a detailed timeline during your consultation so you know exactly what to expect."},
{
id: "2",
title: "Do you offer free consultations?",
content: "Yes! We offer complimentary on-site consultations where we assess your property, discuss your vision, and provide a detailed estimate — no obligation.",
},
id: "2", title: "Do you offer free consultations?", content: "Yes! We offer complimentary on-site consultations where we assess your property, discuss your vision, and provide a detailed estimate — no obligation."},
{
id: "3",
title: "What areas do you serve?",
content: "We serve the greater metropolitan area and surrounding suburbs within a 50-mile radius. Contact us to confirm service availability in your location.",
},
id: "3", title: "What areas do you serve?", content: "We serve the greater metropolitan area and surrounding suburbs within a 50-mile radius. Contact us to confirm service availability in your location."},
{
id: "4",
title: "Do you provide ongoing maintenance?",
content: "Absolutely. We offer weekly, bi-weekly, and monthly maintenance plans that include mowing, trimming, fertilization, and seasonal cleanups.",
},
id: "4", title: "Do you provide ongoing maintenance?", content: "Absolutely. We offer weekly, bi-weekly, and monthly maintenance plans that include mowing, trimming, fertilization, and seasonal cleanups."},
{
id: "5",
title: "Are your practices eco-friendly?",
content: "Yes, sustainability is core to our approach. We use native plants, organic fertilizers, smart irrigation, and environmentally responsible methods whenever possible.",
},
id: "5", title: "Are your practices eco-friendly?", content: "Yes, sustainability is core to our approach. We use native plants, organic fertilizers, smart irrigation, and environmentally responsible methods whenever possible."},
{
id: "6",
title: "Do you handle permits and HOA approvals?",
content: "We handle all necessary permits and can work directly with your HOA to ensure your project meets community guidelines and gets approved smoothly.",
},
id: "6", title: "Do you handle permits and HOA approvals?", content: "We handle all necessary permits and can work directly with your HOA to ensure your project meets community guidelines and gets approved smoothly."},
]}
/>
</div>
@@ -319,9 +221,7 @@ export default function LandscapingPage() {
{ name: "phone", type: "tel", placeholder: "Phone Number" },
]}
multiSelect={{
name: "service",
label: "Select a Service",
options: ["Landscape Design", "Hardscape & Softscape", "Lawn & Garden Care", "Smart Irrigation"],
name: "service", label: "Select a Service", options: ["Landscape Design", "Hardscape & Softscape", "Lawn & Garden Care", "Smart Irrigation"],
}}
textarea={{ name: "message", placeholder: "Tell us about your project...", rows: 4, required: true }}
/>
@@ -331,8 +231,7 @@ export default function LandscapingPage() {
<FooterSimple
columns={[
{
title: "Services",
items: [
title: "Services", items: [
{ label: "Landscape Design", href: "#services" },
{ label: "Hardscape & Softscape", href: "#services" },
{ label: "Lawn & Garden Care", href: "#services" },
@@ -340,8 +239,7 @@ export default function LandscapingPage() {
],
},
{
title: "Company",
items: [
title: "Company", items: [
{ label: "About", href: "#about" },
{ label: "Team", href: "#team" },
{ label: "Testimonials", href: "#testimonials" },
@@ -349,8 +247,7 @@ export default function LandscapingPage() {
],
},
{
title: "Contact",
items: [
title: "Contact", items: [
{ label: "(555) 123-4567", href: "tel:5551234567" },
{ label: "hello@greenscape.com", href: "mailto:hello@greenscape.com" },
{ label: "Los Angeles, CA" },
@@ -364,4 +261,4 @@ export default function LandscapingPage() {
</ReactLenis>
</ThemeProvider>
);
}
}

View File

@@ -0,0 +1,33 @@
export interface Project {
id: string;
name: string;
description: string;
technologies: string[];
githubUrl?: string;
demoUrl?: string;
imageUrl?: string;
}
export interface Skill {
name: string;
category: string; // e.g., 'Frontend', 'Backend', 'DevOps'
level?: 'Beginner' | 'Intermediate' | 'Advanced' | 'Expert';
}
export interface Experience {
id: string;
title: string;
company: string;
location: string;
startDate: string; // YYYY-MM-DD
endDate?: string; // YYYY-MM-DD or 'Present'
description: string[];
}
export interface PortfolioData {
name: string;
bio: string;
projects: Project[];
skills: Skill[];
experience: Experience[];
}