Merge version_1 into main #14

Merged
bender merged 4 commits from version_1 into main 2026-03-12 13:42:35 +00:00
4 changed files with 56 additions and 118 deletions

View File

@@ -6,9 +6,8 @@ import FooterCard from "@/components/sections/footer/FooterCard";
import { Instagram, Twitter, Youtube, Trash2, Plus, Minus, TrendingUp } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import type { LucideIcon } from "lucide-react";
const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -19,7 +18,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
>
<path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.68v13.67a2.4 2.4 0 1 1-2.4-2.4c.34 0 .67.03 1 .09V9.41a7.12 7.12 0 0 0-1-.08C5.89 9.33 2 13.46 2 18.13s3.88 8.81 8.74 8.81c4.65 0 8.6-3.36 8.6-7.53 0-.13 0-.26 0-.39a5.5 5.5 0 0 0-.56-1.78h.09c4.87 0 8.82-3.37 8.82-7.53 0-4.16-3.96-7.53-8.82-7.53z"/>
</svg>
) as any;
);
export default function CartPage() {
const navItems = [
@@ -60,7 +59,7 @@ export default function CartPage() {
const tax = subtotal * 0.08;
const total = subtotal + shipping + tax;
const socialLinks: Array<{ icon: LucideIcon; href: string; ariaLabel: string }> = [
const socialLinks: Array<{ icon: React.ComponentType<React.SVGProps<SVGSVGElement>>; href: string; ariaLabel: string }> = [
{ icon: Instagram, href: "https://instagram.com/umbra", ariaLabel: "Instagram" },
{ icon: Twitter, href: "https://twitter.com/umbra", ariaLabel: "Twitter" },
{ icon: TikTok, href: "https://tiktok.com/@umbra", ariaLabel: "TikTok" },

View File

@@ -11,9 +11,8 @@ import ContactText from "@/components/sections/contact/ContactText";
import FooterCard from "@/components/sections/footer/FooterCard";
import Link from "next/link";
import { Sparkles, TrendingUp, Instagram, Twitter, Youtube } from "lucide-react";
import type { LucideIcon } from "lucide-react";
const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -24,7 +23,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
>
<path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.68v13.67a2.4 2.4 0 1 1-2.4-2.4c.34 0 .67.03 1 .09V9.41a7.12 7.12 0 0 0-1-.08C5.89 9.33 2 13.46 2 18.13s3.88 8.81 8.74 8.81c4.65 0 8.6-3.36 8.6-7.53 0-.13 0-.26 0-.39a5.5 5.5 0 0 0-.56-1.78h.09c4.87 0 8.82-3.37 8.82-7.53 0-4.16-3.96-7.53-8.82-7.53z"/>
</svg>
) as any;
);
export default function HomePage() {
const navItems = [
@@ -35,7 +34,7 @@ export default function HomePage() {
{ name: "Contact", id: "contact" },
];
const socialLinks: Array<{ icon: LucideIcon; href: string; ariaLabel: string }> = [
const socialLinks: Array<{ icon: React.ComponentType<React.SVGProps<SVGSVGElement>>; href: string; ariaLabel: string }> = [
{ icon: Instagram, href: "https://instagram.com/umbra", ariaLabel: "Instagram" },
{ icon: Twitter, href: "https://twitter.com/umbra", ariaLabel: "Twitter" },
{ icon: TikTok, href: "https://tiktok.com/@umbra", ariaLabel: "TikTok" },

View File

@@ -3,12 +3,11 @@
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleCentered from "@/components/navbar/NavbarStyleCentered/NavbarStyleCentered";
import FooterCard from "@/components/sections/footer/FooterCard";
import { Instagram, Twitter, Youtube, Heart, ShoppingCart, Minus, Plus } from "lucide-react";
import { Instagram, Twitter, Youtube, ShoppingCart, Heart } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import type { LucideIcon } from "lucide-react";
const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -19,7 +18,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
>
<path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.68v13.67a2.4 2.4 0 1 1-2.4-2.4c.34 0 .67.03 1 .09V9.41a7.12 7.12 0 0 0-1-.08C5.89 9.33 2 13.46 2 18.13s3.88 8.81 8.74 8.81c4.65 0 8.6-3.36 8.6-7.53 0-.13 0-.26 0-.39a5.5 5.5 0 0 0-.56-1.78h.09c4.87 0 8.82-3.37 8.82-7.53 0-4.16-3.96-7.53-8.82-7.53z"/>
</svg>
) as any;
);
export default function ProductDetailPage() {
const navItems = [
@@ -31,42 +30,24 @@ export default function ProductDetailPage() {
];
const [quantity, setQuantity] = useState(1);
const [isFavorite, setIsFavorite] = useState(false);
const [selectedSize, setSelectedSize] = useState("M");
const [selectedColor, setSelectedColor] = useState("Black");
const product = {
id: "1", name: "Classic Black Hoodie", price: 89.99,
originalPrice: 119.99,
rating: 4.8,
reviews: 128,
description: "Experience premium comfort with our Classic Black Hoodie. Crafted from high-quality materials, this versatile piece is perfect for any season. Features a spacious kangaroo pocket, drawstring hood, and relaxed fit that pairs well with any outfit.", images: [
"http://img.b2bpic.net/free-photo/medium-shot-man-posing-with-hoodie-indoors_23-2149359859.jpg", "http://img.b2bpic.net/free-photo/medium-shot-cool-man-with-electric-scooter_23-2149356776.jpg"],
sizes: ["XS", "S", "M", "L", "XL", "XXL"],
colors: ["Black", "Navy", "Gray", "Charcoal"],
specifications: [
{ label: "Material", value: "100% Premium Cotton" },
{ label: "Weight", value: "450 GSM" },
{ label: "Care", value: "Machine wash cold, tumble dry low" },
{ label: "Fit", value: "Relaxed fit" },
],
reviews: 124,
description: "Premium quality streetwear hoodie with authentic urban style. Crafted from 100% cotton for maximum comfort and durability. Perfect for everyday wear or layering. Features a relaxed fit and quality embroidered details.", imageSrc: "http://img.b2bpic.net/free-photo/medium-shot-man-posing-with-hoodie-indoors_23-2149359859.jpg", sizes: ["XS", "S", "M", "L", "XL", "2XL"],
colors: ["Black", "Gray", "Navy", "White"],
};
const socialLinks: Array<{ icon: LucideIcon; href: string; ariaLabel: string }> = [
const socialLinks: Array<{ icon: React.ComponentType<React.SVGProps<SVGSVGElement>>; href: string; ariaLabel: string }> = [
{ icon: Instagram, href: "https://instagram.com/umbra", ariaLabel: "Instagram" },
{ icon: Twitter, href: "https://twitter.com/umbra", ariaLabel: "Twitter" },
{ icon: TikTok, href: "https://tiktok.com/@umbra", ariaLabel: "TikTok" },
{ icon: Youtube, href: "https://youtube.com/@umbra", ariaLabel: "YouTube" },
];
const handleAddToCart = () => {
console.log(`Added ${quantity} of ${product.name} (${selectedSize}, ${selectedColor}) to cart`);
};
const handleToggleFavorite = () => {
setIsFavorite(!isFavorite);
};
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
@@ -88,7 +69,7 @@ export default function ProductDetailPage() {
/>
</div>
<div id="product-detail" data-section="product-detail" className="mx-auto px-4 md:px-6">
<div id="product" data-section="product" className="mx-auto px-4 md:px-6">
<div className="py-20">
<div className="max-w-6xl mx-auto">
<Link href="/shop" className="text-accent hover:text-background-accent mb-8 inline-block">
@@ -96,64 +77,37 @@ export default function ProductDetailPage() {
</Link>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
{/* Product Images */}
<div>
<div className="bg-card border border-accent/20 rounded-soft p-4 mb-4">
<img
src={product.images[0]}
alt={product.name}
className="w-full h-auto rounded-soft object-cover"
/>
</div>
<div className="grid grid-cols-4 gap-4">
{product.images.map((img, idx) => (
<div
key={idx}
className="bg-card border border-accent/20 rounded-soft p-2 cursor-pointer hover:border-accent/50 transition-colors"
>
<img src={img} alt={`${product.name} ${idx + 1}`} className="w-full h-auto object-cover" />
</div>
))}
</div>
{/* Product Image */}
<div className="flex items-center justify-center bg-card/30 rounded-soft overflow-hidden h-96 md:h-full">
<img
src={product.imageSrc}
alt={product.name}
className="w-full h-full object-cover"
/>
</div>
{/* Product Details */}
<div>
<h1 className="text-4xl font-bold text-foreground mb-4">{product.name}</h1>
<h1 className="text-4xl font-bold text-foreground mb-2">{product.name}</h1>
<div className="flex items-center gap-4 mb-6">
<span className="text-3xl font-bold text-background-accent">${product.price}</span>
<span className="text-lg line-through text-foreground/50">${product.originalPrice}</span>
<span className="px-3 py-1 bg-background-accent/20 text-background-accent rounded-full text-sm font-semibold">
{Math.round(((product.originalPrice - product.price) / product.originalPrice) * 100)}% OFF
</span>
<div className="text-xl font-semibold text-background-accent">${product.price}</div>
<div className="text-sm text-foreground/70"> {product.rating} ({product.reviews} reviews)</div>
</div>
<div className="flex items-center gap-2 mb-8">
<div className="flex text-background-accent">
{[...Array(5)].map((_, i) => (
<span key={i}></span>
))}
</div>
<span className="text-foreground/70">
{product.rating} ({product.reviews} reviews)
</span>
</div>
<p className="text-foreground/80 mb-8">{product.description}</p>
<p className="text-foreground/80 mb-8 leading-relaxed">{product.description}</p>
{/* Size Selection */}
<div className="mb-6">
<div className="mb-8">
<label className="block text-sm font-semibold text-foreground mb-3">Size</label>
<div className="grid grid-cols-6 gap-2">
<div className="flex gap-3 flex-wrap">
{product.sizes.map((size) => (
<button
key={size}
onClick={() => setSelectedSize(size)}
className={`py-2 rounded-soft font-semibold transition-colors ${
className={`px-4 py-2 rounded-soft border transition-colors ${
selectedSize === size
? "bg-background-accent text-primary-cta-text"
: "bg-card border border-accent/20 text-foreground hover:border-accent/50"
? "bg-background-accent text-primary-cta-text border-background-accent"
: "border-accent/30 text-foreground hover:border-accent/60"
}`}
>
{size}
@@ -170,10 +124,10 @@ export default function ProductDetailPage() {
<button
key={color}
onClick={() => setSelectedColor(color)}
className={`px-4 py-2 rounded-soft font-semibold transition-colors ${
className={`px-4 py-2 rounded-soft border transition-colors ${
selectedColor === color
? "bg-background-accent text-primary-cta-text"
: "bg-card border border-accent/20 text-foreground hover:border-accent/50"
? "bg-background-accent text-primary-cta-text border-background-accent"
: "border-accent/30 text-foreground hover:border-accent/60"
}`}
>
{color}
@@ -182,55 +136,42 @@ export default function ProductDetailPage() {
</div>
</div>
{/* Quantity & Buttons */}
<div className="flex gap-4 mb-8">
<div className="flex items-center gap-3 bg-card border border-accent/20 rounded-soft p-2">
{/* Quantity Selection */}
<div className="mb-8">
<label className="block text-sm font-semibold text-foreground mb-3">Quantity</label>
<div className="flex items-center gap-4">
<button
onClick={() => setQuantity(Math.max(1, quantity - 1))}
className="p-2 hover:bg-accent/20 rounded transition-colors"
className="px-4 py-2 border border-accent/30 rounded-soft hover:bg-accent/10 transition-colors"
>
<Minus size={18} className="text-foreground" />
</button>
<span className="w-8 text-center text-foreground font-semibold">{quantity}</span>
<span className="w-10 text-center font-semibold text-foreground">{quantity}</span>
<button
onClick={() => setQuantity(quantity + 1)}
className="p-2 hover:bg-accent/20 rounded transition-colors"
className="px-4 py-2 border border-accent/30 rounded-soft hover:bg-accent/10 transition-colors"
>
<Plus size={18} className="text-foreground" />
+
</button>
</div>
</div>
<button
onClick={handleAddToCart}
className="flex-1 px-6 py-3 bg-background-accent text-primary-cta-text font-semibold rounded-soft hover:bg-primary-cta transition-colors flex items-center justify-center gap-2"
>
{/* Action Buttons */}
<div className="flex gap-4 mb-8">
<button className="flex-1 px-8 py-3 bg-background-accent text-primary-cta-text font-semibold rounded-soft hover:bg-primary-cta transition-colors flex items-center justify-center gap-2">
<ShoppingCart size={20} />
Add to Cart
</button>
<button
onClick={handleToggleFavorite}
className={`px-6 py-3 rounded-soft font-semibold transition-colors ${
isFavorite
? "bg-background-accent/20 text-background-accent"
: "bg-card border border-accent/20 text-foreground hover:border-accent/50"
}`}
>
<Heart size={20} fill={isFavorite ? "currentColor" : "none"} />
<button className="px-6 py-3 border border-accent/30 text-foreground rounded-soft hover:bg-accent/10 transition-colors">
<Heart size={20} />
</button>
</div>
{/* Specifications */}
<div className="bg-card/50 border border-accent/20 rounded-soft p-6">
<h3 className="text-lg font-semibold text-foreground mb-4">Specifications</h3>
<div className="space-y-3">
{product.specifications.map((spec, idx) => (
<div key={idx} className="flex justify-between">
<span className="text-foreground/70">{spec.label}</span>
<span className="font-semibold text-foreground">{spec.value}</span>
</div>
))}
</div>
{/* Additional Info */}
<div className="border-t border-accent/20 pt-6 space-y-3">
<p className="text-sm text-foreground/70"> Free Shipping on orders over $150</p>
<p className="text-sm text-foreground/70"> 30-Day Money Back Guarantee</p>
<p className="text-sm text-foreground/70"> Premium Quality Materials</p>
</div>
</div>
</div>

View File

@@ -8,9 +8,8 @@ import ContactText from "@/components/sections/contact/ContactText";
import FooterCard from "@/components/sections/footer/FooterCard";
import Link from "next/link";
import { TrendingUp, Instagram, Twitter, Youtube } from "lucide-react";
import type { LucideIcon } from "lucide-react";
const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -21,7 +20,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>): LucideIcon => (
>
<path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.68v13.67a2.4 2.4 0 1 1-2.4-2.4c.34 0 .67.03 1 .09V9.41a7.12 7.12 0 0 0-1-.08C5.89 9.33 2 13.46 2 18.13s3.88 8.81 8.74 8.81c4.65 0 8.6-3.36 8.6-7.53 0-.13 0-.26 0-.39a5.5 5.5 0 0 0-.56-1.78h.09c4.87 0 8.82-3.37 8.82-7.53 0-4.16-3.96-7.53-8.82-7.53z"/>
</svg>
) as any;
);
export default function ShopPage() {
const navItems = [
@@ -32,7 +31,7 @@ export default function ShopPage() {
{ name: "Contact", id: "contact" },
];
const socialLinks: Array<{ icon: LucideIcon; href: string; ariaLabel: string }> = [
const socialLinks: Array<{ icon: React.ComponentType<React.SVGProps<SVGSVGElement>>; href: string; ariaLabel: string }> = [
{ icon: Instagram, href: "https://instagram.com/umbra", ariaLabel: "Instagram" },
{ icon: Twitter, href: "https://twitter.com/umbra", ariaLabel: "Twitter" },
{ icon: TikTok, href: "https://tiktok.com/@umbra", ariaLabel: "TikTok" },