Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5581b8b9f3 | |||
| 1da08052b1 | |||
| 10616de12f | |||
| a01535d2b0 | |||
| cfc57e2bdc | |||
| 35bf3268c7 | |||
| 80478cd770 | |||
| 1812740d52 |
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
155
src/app/page.tsx
155
src/app/page.tsx
@@ -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" },
|
||||
];
|
||||
@@ -26,7 +131,7 @@ export default function LandingPage() {
|
||||
{
|
||||
id: "trading", title: "Trading Solutions", description:
|
||||
"Expert trading services with real-time market analysis, strategic portfolio management, and competitive pricing for maximum returns.", tag: "Trading", imageSrc:
|
||||
"http://img.b2bpic.net/free-photo/general-director-examining-statistics-big-data-computer-control-room_482257-90941.jpg", imageAlt: "Professional Trading Services", buttons: [{ text: "Explore Trading", href: "#" }],
|
||||
"http://img.b2bpic.net/free-photo/general-director-examining-statistics-big-data-computer-control-room_482257-90941.jpg", imageAlt: "Professional Trading Services", buttons: [{ text: "Start Trading Now", href: "#" }],
|
||||
},
|
||||
{
|
||||
id: "cleaning", title: "Professional Cleaning", description:
|
||||
@@ -36,7 +141,7 @@ export default function LandingPage() {
|
||||
{
|
||||
id: "moving", title: "Seamless Moving", description:
|
||||
"Reliable moving and relocation services with professional logistics management. Safe handling and timely delivery guaranteed for your peace of mind.", tag: "Moving", imageSrc:
|
||||
"http://img.b2bpic.net/free-photo/young-courier-pointing-something-while-witting-with-his-coworker-back-delivery-van_637285-2286.jpg", imageAlt: "Professional Moving Services", buttons: [{ text: "Book Moving", href: "#" }],
|
||||
"http://img.b2bpic.net/free-photo/young-courier-pointing-something-while-witting-with-his-coworker-back-delivery-van_637285-2286.jpg", imageAlt: "Professional Moving Services", buttons: [{ text: "Get Moving Quote", href: "#" }],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user