Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ShopCo</title>

<!-- Custom Fonts -->
<!-- Integral CF for headings -->
<link href="https://db.onlinewebfonts.com/c/f1fcc5aed1e20fc0cdb9f8a7573625bd?family=Integral+CF+Regular" rel="stylesheet">

<!-- Satoshi for UI text -->
<link href="https://api.fontshare.com/v2/css?f[]=satoshi@300,301,400,401,500,501,700,701,900,901,1,2&display=swap" rel="stylesheet">


<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="/favicon.ico?v=1">
<link rel="shortcut icon" href="/favicon.ico?v=1" type="image/x-icon">
<link rel="apple-touch-icon" href="/favicon.ico?v=1">
<meta name="msapplication-TileImage" content="/favicon.ico?v=1">
<meta name="msapplication-TileColor" content="#000000">
</head>
<body>
<div id="root"></div>
Expand Down
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dependencies": {
"@tanstack/react-query": "^5.90.2",
"axios": "^1.12.2",
"lucide-react": "^0.544.0",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-query": "^3.39.3",
Expand Down
Binary file added client/public/favicon.ico
Binary file not shown.
28 changes: 17 additions & 11 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { Routes, Route } from 'react-router-dom'
import Landing from './pages/Landing'
import ApiStatus from './components/ApiStatus'
import Home from './pages/home'
// import ApiStatus from './components/ApiStatus'
import Header from './components/layout/Header'

function App() {
return (
<div className="min-h-screen bg-gray-50">
{/* API Status Indicator */}
<div className="fixed top-4 right-4 z-50">
<ApiStatus showDetails={true} />
</div>
<div className="min-h-screen bg-white overflow-x-hidden">
<Header />
{/* API Status Indicator - Mobile responsive positioning */}
{/* <div className="fixed top-2 right-2 z-50 sm:top-4 sm:right-4">
<div className="bg-white/90 backdrop-blur-sm rounded-lg px-2 py-1 shadow-sm sm:px-3 sm:py-2">
<ApiStatus showDetails={true} />
</div>
</div> */}

{/* Main App Routes */}
<Routes>
<Route path="/" element={<Landing />} />
</Routes>
{/* Main App Routes with minimal top padding to account for fixed header */}
<div className="pt-0">
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</div>
</div>
)
}
Expand Down
Binary file added client/src/assets/images/Browse/Casual.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/Browse/Formal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/Browse/Gym.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/Browse/Party.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/brands/CalvinKlein.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/brands/Gucci.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/brands/Prada.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/brands/Versace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/brands/Zara.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/hero/hero_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/icons/star_big.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/icons/star_small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/products/Bermuda.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/products/Courage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/images/products/TapeDetails.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions client/src/components/ApiStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,18 @@ const ApiStatus: React.FC<ApiStatusProps> = ({ showDetails = false }) => {
};

return (
<div className={`flex items-center space-x-2 text-sm ${getStatusColor()}`}>
<span>{getStatusIcon()}</span>
<span>{getStatusText()}</span>
<div className={`flex items-center space-x-2 text-xs sm:text-sm ${getStatusColor()}`}>
<span className="text-sm sm:text-base">{getStatusIcon()}</span>
<span className="font-sans font-medium">{getStatusText()}</span>
{showDetails && lastChecked && (
<span className="text-gray-500">
<span className="text-gray-500 hidden sm:inline font-sans">
(Last checked: {lastChecked.toLocaleTimeString()})
</span>
)}
{!isHealthy && (
<button
onClick={checkHealth}
className="ml-2 px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600"
className="ml-2 px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 font-sans touch-manipulation"
disabled={isChecking}
>
Retry
Expand Down
45 changes: 45 additions & 0 deletions client/src/components/Newsletter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const Newsletter = () => {
return (
<section className="py-16 bg-white">
<div className="max-w-7xl mx-auto px-8">
{/* Newsletter Card - Floating appearance */}
<div className="bg-black rounded-3xl px-12 py-8 flex items-center justify-between">
{/* Left side - Text */}
<div className="flex-1">
<h2 className="text-white text-4xl font-bold leading-tight">
STAY UPTO DATE ABOUT
<br />
OUR LATEST OFFERS
</h2>
</div>

{/* Right side - Form */}
<div className="flex-1 max-w-md ml-12">
<div className="space-y-4">
{/* Email Input */}
<div className="relative">
<div className="absolute inset-y-0 left-4 flex items-center">
<svg className="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207" />
</svg>
</div>
<input
type="email"
placeholder="Enter your email address"
className="w-full pl-12 pr-4 py-3 rounded-full bg-white text-gray-900 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-300"
/>
</div>

{/* Subscribe Button */}
<button className="w-full bg-white text-black py-3 rounded-full font-medium hover:bg-gray-100 transition-colors duration-200">
Subscribe to Newsletter
</button>
</div>
</div>
</div>
</div>
</section>
);
};

export default Newsletter;
111 changes: 111 additions & 0 deletions client/src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const Footer = () => {
return (
<footer className="bg-gray-100 pt-12 pb-6">
<div className="max-w-7xl mx-auto px-8">
{/* Main Footer Content */}
<div className="grid grid-cols-5 gap-8 mb-8">
{/* Brand Section */}
<div className="col-span-1">
<h3 className="text-3xl font-bold text-black mb-4">SHOP.CO</h3>
<p className="text-gray-600 text-sm leading-relaxed mb-6">
We have clothes that suits your style and which you're proud to wear. From women to men.
</p>
{/* Social Media Icons */}
<div className="flex gap-3">
<div className="w-8 h-8 bg-white rounded-full flex items-center justify-center border border-gray-300">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/>
</svg>
</div>
<div className="w-8 h-8 bg-black rounded-full flex items-center justify-center">
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 24 24">
<path d="M22.46 6c-.77.35-1.6.58-2.46.69.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21 16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56.84-.6 1.56-1.36 2.14-2.23z"/>
</svg>
</div>
<div className="w-8 h-8 bg-white rounded-full flex items-center justify-center border border-gray-300">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.174-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.402.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.357-.629-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24.009 12.017 24.009c6.624 0 11.99-5.367 11.99-11.988C24.007 5.367 18.641.001.012.001z"/>
</svg>
</div>
</div>
</div>

{/* Company Links */}
<div>
<h4 className="font-medium text-black mb-4 tracking-wider">COMPANY</h4>
<ul className="space-y-3 text-sm text-gray-600">
<li><a href="#" className="hover:text-black transition-colors">About</a></li>
<li><a href="#" className="hover:text-black transition-colors">Features</a></li>
<li><a href="#" className="hover:text-black transition-colors">Works</a></li>
<li><a href="#" className="hover:text-black transition-colors">Career</a></li>
</ul>
</div>

{/* Help Links */}
<div>
<h4 className="font-medium text-black mb-4 tracking-wider">HELP</h4>
<ul className="space-y-3 text-sm text-gray-600">
<li><a href="#" className="hover:text-black transition-colors">Customer Support</a></li>
<li><a href="#" className="hover:text-black transition-colors">Delivery Details</a></li>
<li><a href="#" className="hover:text-black transition-colors">Terms & Conditions</a></li>
<li><a href="#" className="hover:text-black transition-colors">Privacy Policy</a></li>
</ul>
</div>

{/* FAQ Links */}
<div>
<h4 className="font-medium text-black mb-4 tracking-wider">FAQ</h4>
<ul className="space-y-3 text-sm text-gray-600">
<li><a href="#" className="hover:text-black transition-colors">Account</a></li>
<li><a href="#" className="hover:text-black transition-colors">Manage Deliveries</a></li>
<li><a href="#" className="hover:text-black transition-colors">Orders</a></li>
<li><a href="#" className="hover:text-black transition-colors">Payments</a></li>
</ul>
</div>

{/* Resources Links */}
<div>
<h4 className="font-medium text-black mb-4 tracking-wider">RESOURCES</h4>
<ul className="space-y-3 text-sm text-gray-600">
<li><a href="#" className="hover:text-black transition-colors">Free eBooks</a></li>
<li><a href="#" className="hover:text-black transition-colors">Development Tutorial</a></li>
<li><a href="#" className="hover:text-black transition-colors">How to - Blog</a></li>
<li><a href="#" className="hover:text-black transition-colors">Youtube Playlist</a></li>
</ul>
</div>
</div>

{/* Divider */}
<div className="border-t border-gray-300 pt-6">
<div className="flex items-center justify-between">
{/* Copyright */}
<p className="text-sm text-gray-600">
Shop.co © 2000-2023, All Rights Reserved
</p>

{/* Payment Methods */}
<div className="flex items-center gap-3">
<div className="w-12 h-8 bg-white rounded border border-gray-300 flex items-center justify-center">
<span className="text-xs font-bold text-blue-600">VISA</span>
</div>
<div className="w-12 h-8 bg-white rounded border border-gray-300 flex items-center justify-center">
<div className="w-6 h-4 bg-gradient-to-r from-orange-500 to-red-500 rounded-sm"></div>
</div>
<div className="w-12 h-8 bg-white rounded border border-gray-300 flex items-center justify-center">
<span className="text-xs font-bold text-blue-600">PayPal</span>
</div>
<div className="w-12 h-8 bg-white rounded border border-gray-300 flex items-center justify-center">
<span className="text-xs font-bold">Pay</span>
</div>
<div className="w-12 h-8 bg-white rounded border border-gray-300 flex items-center justify-center">
<span className="text-xs font-bold">G Pay</span>
</div>
</div>
</div>
</div>
</div>
</footer>
);
};

export default Footer;
97 changes: 97 additions & 0 deletions client/src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useState } from 'react'
import { Link } from 'react-router-dom'
import { Menu, X, Search, ShoppingCart, User, ChevronDown } from 'lucide-react'

export default function Header() {
const [isOpen, setIsOpen] = useState(false)

return (
<header className="sticky top-0 z-40 w-full bg-white/80 backdrop-blur supports-[backdrop-filter]:bg-white/60 border-b">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="flex h-16 items-center justify-between lg:grid lg:grid-cols-[auto_1fr_auto] lg:gap-4">
{/* Left: Mobile menu button & Logo */}
<div className="flex items-center gap-3">
<button
aria-label="Open Menu"
aria-expanded={isOpen}
aria-controls="mobile-menu"
className="inline-flex items-center justify-center rounded-md p-2 text-gray-700 hover:bg-gray-100 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-gray-300 lg:hidden"
onClick={() => setIsOpen(!isOpen)}
>
{isOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
</button>

{/* Logo */}
<Link to="/" className="font-black tracking-tight text-xl select-none hover:opacity-90 transition-opacity">
<span className="font-heading">SHOP.CO</span>
</Link>
{/* Desktop nav */}
<nav className="hidden lg:flex items-center gap-6 text-sm ml-6 whitespace-nowrap">
<button className="inline-flex items-center gap-1 text-gray-800 hover:text-black transition-colors">Shop
<ChevronDown className="h-4 w-4 opacity-70" />
</button>
<Link to="#" className="text-gray-800 hover:text-black transition-colors">On Sale</Link>
<Link to="#" className="text-gray-800 hover:text-black transition-colors">New Arrivals</Link>
<Link to="#" className="text-gray-800 hover:text-black transition-colors">Brands</Link>
</nav>
</div>

{/* Center: Search (desktop only) */}
<div className="hidden lg:block justify-self-center w-full max-w-[400px]">
<div className="relative">
<span className="absolute inset-y-0 left-3 flex items-center text-gray-500">
<Search className="h-4 w-4" />
</span>
<input
type="text"
placeholder="Search for products..."
className="w-full rounded-full bg-gray-100 pl-9 pr-4 py-2.5 text-sm outline-none ring-1 ring-transparent focus:ring-gray-300 placeholder:text-gray-500 transition-shadow duration-200 focus:shadow-sm"
/>
</div>
</div>

{/* Right: Icons */}
<div className="flex items-center gap-4 justify-self-end">
{/* Search icon on mobile */}
<button aria-label="Search" className="lg:hidden text-gray-800 hover:text-black transition-colors">
<Search className="h-5 w-5" />
</button>
<button aria-label="Cart" className="text-gray-800 hover:text-black transition-colors">
<ShoppingCart className="h-5 w-5" />
</button>
<button aria-label="Account" className="text-gray-800 hover:text-black transition-colors">
<User className="h-5 w-5" />
</button>
</div>
</div>
</div>

{/* Mobile dropdown overlay */}
<div
id="mobile-menu"
className={`lg:hidden fixed inset-x-0 top-16 z-50 border-b bg-white/95 supports-[backdrop-filter]:bg-white/90 backdrop-blur shadow-sm transition-all duration-300 ease-out overflow-hidden ${
isOpen ? 'max-h-[70vh] opacity-100 translate-y-0' : 'max-h-0 opacity-0 -translate-y-2'
}`}
>
<div className="mx-auto max-w-7xl px-6 py-4 space-y-2">
<Link to="#" className="block py-2 text-sm text-gray-800 hover:text-black transition-colors">Shop</Link>
<Link to="#" className="block py-2 text-sm text-gray-800 hover:text-black transition-colors">On Sale</Link>
<Link to="#" className="block py-2 text-sm text-gray-800 hover:text-black transition-colors">New Arrivals</Link>
<Link to="#" className="block py-2 text-sm text-gray-800 hover:text-black transition-colors">Brands</Link>
<div className="pt-2">
<div className="relative">
<span className="absolute inset-y-0 left-3 flex items-center text-gray-500">
<Search className="h-4 w-4" />
</span>
<input
type="text"
placeholder="Search for products..."
className="w-full rounded-full bg-gray-100 pl-9 pr-4 py-2.5 text-sm outline-none ring-1 ring-transparent focus:ring-gray-300 placeholder:text-gray-500 transition-shadow duration-200 focus:shadow-sm"
/>
</div>
</div>
</div>
</div>
</header>
)
}
3 changes: 3 additions & 0 deletions client/src/index.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

@import url(https://db.onlinewebfonts.com/c/f1fcc5aed1e20fc0cdb9f8a7573625bd?family=Integral+CF+Regular);
@import url('https://api.fontshare.com/v2/css?f[]=satoshi@300,301,400,401,500,501,700,701,900,901,1,2&display=swap');

@tailwind base;
@tailwind components;
@tailwind utilities;
Expand Down
Loading