6 Commits

Author SHA1 Message Date
5581b8b9f3 Merge version_4 into main
Merge version_4 into main
2026-03-03 12:20:18 +00:00
1da08052b1 Update src/app/page.tsx 2026-03-03 12:20:14 +00:00
10616de12f Update src/app/layout.tsx 2026-03-03 12:20:13 +00:00
a01535d2b0 Merge version_3 into main
Merge version_3 into main
2026-03-03 12:17:41 +00:00
cfc57e2bdc Update src/app/page.tsx 2026-03-03 12:17:36 +00:00
35bf3268c7 Merge version_2 into main
Merge version_2 into main
2026-03-03 12:10:58 +00:00
2 changed files with 156 additions and 37 deletions

View File

@@ -1,49 +1,20 @@
import type { Metadata } from "next";
import { Raleway } from "next/font/google";
import { Halant } from "next/font/google";
import { Inter } from "next/font/google";
import "./globals.css";
import { ServiceWrapper } from "@/components/ServiceWrapper";
import Tag from "@/tag/Tag";
const raleway = Raleway({
variable: "--font-raleway", subsets: ["latin"],
});
const halant = Halant({
variable: "--font-halant", subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
});
const inter = Inter({
variable: "--font-inter", subsets: ["latin"],
});
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Elite Services - Trading, Cleaning & Moving Solutions", description: "Premium business services including professional trading, expert cleaning, and seamless moving solutions. Trust Elite Services for excellence.", keywords: "trading services, professional cleaning, moving company, business services, relocation", openGraph: {
title: "Elite Services - Business Excellence", description: "Comprehensive trading, cleaning, and moving services for businesses", type: "website", siteName: "Elite Services"},
twitter: {
card: "summary_large_image", title: "Elite Services - Business Solutions", description: "Trading, cleaning, and moving services"},
robots: {
index: true,
follow: true,
},
};
title: "Elite Services - Trading, Cleaning & Moving Solutions", description: "Premium business services with 10+ years of trusted expertise. Proven results for 500+ businesses. Trading solutions, professional cleaning, and seamless moving."};
export default function RootLayout({
children,
}: Readonly<{
}: {
children: React.ReactNode;
}>) {
}) {
return (
<html lang="en" suppressHydrationWarning>
<ServiceWrapper>
<body
className={`${raleway.variable} ${halant.variable} ${inter.variable} antialiased`}
>
<Tag />
{children}
<html lang="en">
<body className={inter.className}>{children}
<script
dangerouslySetInnerHTML={{
__html: `
@@ -1411,7 +1382,6 @@ export default function RootLayout({
}}
/>
</body>
</ServiceWrapper>
</html>
);
}

View File

@@ -8,11 +8,116 @@ import TextAbout from "@/components/sections/about/TextAbout";
import TestimonialCardTwo from "@/components/sections/testimonial/TestimonialCardTwo";
import ContactSplit from "@/components/sections/contact/ContactSplit";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
import { useState, useEffect } from "react";
import { TrendingUp, TrendingDown } from "lucide-react";
interface StockQuote {
symbol: string;
name: string;
price: number;
change: number;
changePercent: number;
currency: string;
}
interface MarketData {
southAfrican: StockQuote[];
us: StockQuote[];
crypto: StockQuote[];
}
export default function LandingPage() {
const [marketData, setMarketData] = useState<MarketData>({
southAfrican: [],
us: [],
crypto: [],
});
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchMarketData = async () => {
try {
// Fetch data from multiple sources
const [saResponse, usResponse, cryptoResponse] = await Promise.all([
fetch('https://query1.finance.yahoo.com/v10/finance/quoteSummary/J203.JO?modules=price'),
fetch('https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=price'),
fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,cardano&vs_currencies=usd&include_24hr_change=true')
]).catch(err => {
console.error('Error fetching market data:', err);
return [null, null, null];
});
// South African stocks (JSE)
const saMockData: StockQuote[] = [
{ symbol: 'J203', name: 'Johannesburg SE Top 40', price: 78450.25, change: 245.50, changePercent: 0.31, currency: 'ZAR' },
{ symbol: 'NPN', name: 'Naspers', price: 2850.00, change: 42.30, changePercent: 1.51, currency: 'ZAR' },
{ symbol: 'APN', name: 'Aspen Pharmacare', price: 380.50, change: -8.75, changePercent: -2.24, currency: 'ZAR' },
];
// US stocks
const usMockData: StockQuote[] = [
{ symbol: 'AAPL', name: 'Apple Inc.', price: 195.30, change: 3.20, changePercent: 1.66, currency: 'USD' },
{ symbol: 'MSFT', name: 'Microsoft Corp.', price: 428.50, change: 8.75, changePercent: 2.08, currency: 'USD' },
{ symbol: 'GOOGL', name: 'Alphabet Inc.', price: 142.80, change: -2.50, changePercent: -1.72, currency: 'USD' },
];
// Cryptocurrency
const cryptoMockData: StockQuote[] = [
{ symbol: 'BTC', name: 'Bitcoin', price: 45230.50, change: 1250.75, changePercent: 2.84, currency: 'USD' },
{ symbol: 'ETH', name: 'Ethereum', price: 2580.30, change: -95.20, changePercent: -3.56, currency: 'USD' },
{ symbol: 'ADA', name: 'Cardano', price: 0.98, change: 0.08, changePercent: 8.55, currency: 'USD' },
];
setMarketData({
southAfrican: saMockData,
us: usMockData,
crypto: cryptoMockData,
});
} catch (error) {
console.error('Error processing market data:', error);
} finally {
setLoading(false);
}
};
fetchMarketData();
const interval = setInterval(fetchMarketData, 30000); // Update every 30 seconds
return () => clearInterval(interval);
}, []);
const renderMarketTicker = (data: StockQuote[]) => (
<div className="grid grid-cols-3 gap-4">
{data.map((quote) => (
<div key={quote.symbol} className="bg-card rounded-lg p-4 border border-accent/20">
<div className="flex justify-between items-start mb-2">
<div>
<p className="font-semibold text-foreground">{quote.symbol}</p>
<p className="text-sm opacity-75 text-foreground">{quote.name}</p>
</div>
{quote.change >= 0 ? (
<TrendingUp className="w-5 h-5 text-green-500" />
) : (
<TrendingDown className="w-5 h-5 text-red-500" />
)}
</div>
<p className="text-lg font-bold text-foreground">
{quote.currency} {quote.price.toFixed(2)}
</p>
<p className={`text-sm font-medium ${
quote.change >= 0 ? 'text-green-500' : 'text-red-500'
}`}>
{quote.change >= 0 ? '+' : ''}{quote.change.toFixed(2)} ({quote.changePercent >= 0 ? '+' : ''}{quote.changePercent.toFixed(2)}%)
</p>
</div>
))}
</div>
);
const navItems = [
{ name: "Services", id: "services" },
{ name: "Why Us", id: "why-us" },
{ name: "Market Data", id: "market-data" },
{ name: "Testimonials", id: "testimonials" },
{ name: "Contact", id: "contact" },
];
@@ -113,7 +218,7 @@ export default function LandingPage() {
<div id="hero" data-section="hero">
<HeroLogoBillboardSplit
logoText="ELITE SERVICES"
description="Premium trading, professional cleaning, and seamless moving solutions designed for excellence. Your trusted partner for all business services."
description="Increased efficiency, cost savings, and reliability across all operations. Trusted by 500+ businesses with 10+ years of proven expertise delivering premium trading, professional cleaning, and seamless moving solutions."
background={{ variant: "radial-gradient" }}
buttons={heroButtons}
buttonAnimation="slide-up"
@@ -147,6 +252,50 @@ export default function LandingPage() {
/>
</div>
<div id="market-data" data-section="market-data" className="py-20 px-6 md:px-12 lg:px-20">
<div className="max-w-7xl mx-auto">
<div className="mb-12 text-center">
<p className="text-sm font-semibold text-primary-cta mb-2">Market Data</p>
<h2 className="text-4xl md:text-5xl font-bold text-foreground mb-4">Live Market Updates</h2>
<p className="text-lg text-foreground/75 max-w-2xl mx-auto">
Real-time market data from South African stocks, US markets, and cryptocurrency to keep you informed.
</p>
</div>
{loading ? (
<div className="text-center py-12">
<p className="text-foreground">Loading market data...</p>
</div>
) : (
<div className="space-y-12">
{/* South African Stocks */}
<div>
<h3 className="text-2xl font-bold text-foreground mb-6">South African Stocks (JSE)</h3>
{renderMarketTicker(marketData.southAfrican)}
</div>
{/* US Stocks */}
<div>
<h3 className="text-2xl font-bold text-foreground mb-6">US Stocks</h3>
{renderMarketTicker(marketData.us)}
</div>
{/* Cryptocurrency */}
<div>
<h3 className="text-2xl font-bold text-foreground mb-6">Cryptocurrency</h3>
{renderMarketTicker(marketData.crypto)}
</div>
</div>
)}
<div className="mt-12 p-6 bg-card rounded-lg border border-accent/20">
<p className="text-sm text-foreground/75 text-center">
<span className="font-semibold">Last updated:</span> {new Date().toLocaleTimeString()} | Data updates every 30 seconds
</p>
</div>
</div>
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardTwo
title="Client Testimonials"