Merge version_1 into main #11

Merged
bender merged 4 commits from version_1 into main 2026-03-12 08:18:50 +00:00
4 changed files with 139 additions and 141 deletions

View File

@@ -6,8 +6,9 @@ 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>) => (
const TikTok: LucideIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -18,7 +19,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
>
<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 LucideIcon;
export default function CartPage() {
const navItems = [
@@ -59,7 +60,7 @@ export default function CartPage() {
const tax = subtotal * 0.08;
const total = subtotal + shipping + tax;
const socialLinks = [
const socialLinks: Array<{ icon: LucideIcon; 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,8 +11,9 @@ 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>) => (
const TikTok: LucideIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -23,7 +24,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
>
<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 LucideIcon;
export default function HomePage() {
const navItems = [
@@ -34,7 +35,7 @@ export default function HomePage() {
{ name: "Contact", id: "contact" },
];
const socialLinks = [
const socialLinks: Array<{ icon: LucideIcon; 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,11 +3,12 @@
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleCentered from "@/components/navbar/NavbarStyleCentered/NavbarStyleCentered";
import FooterCard from "@/components/sections/footer/FooterCard";
import { Instagram, Twitter, Youtube, ShoppingCart, Heart, Share2 } from "lucide-react";
import { Instagram, Twitter, Youtube, Heart, ShoppingCart } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import type { LucideIcon } from "lucide-react";
const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
const TikTok: LucideIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -18,7 +19,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
>
<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 LucideIcon;
export default function ProductPage() {
const navItems = [
@@ -29,27 +30,18 @@ export default function ProductPage() {
{ name: "Contact", id: "contact" },
];
const [quantity, setQuantity] = useState(1);
const [selectedSize, setSelectedSize] = useState("M");
const [selectedColor, setSelectedColor] = useState("Black");
const [isFavorite, setIsFavorite] = useState(false);
const [quantity, setQuantity] = useState(1);
const [isFavorited, setIsFavorited] = useState(false);
const socialLinks = [
const socialLinks: Array<{ icon: LucideIcon; 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 product = {
id: "1", name: "Classic Black Hoodie", price: 89.99,
description: "Our signature Classic Black Hoodie combines premium comfort with timeless style. Crafted from high-quality cotton blend fabric, this oversized hoodie features a spacious kangaroo pocket, adjustable drawstrings, and reinforced seams for durability. Perfect for layering or wearing solo, it's the essential streetwear piece for any wardrobe.", image: "http://img.b2bpic.net/free-photo/medium-shot-man-posing-with-hoodie-indoors_23-2149359859.jpg", rating: 4.8,
reviewCount: 247,
inStock: true,
sizes: ["XS", "S", "M", "L", "XL", "XXL"],
colors: ["Black", "Gray", "Navy", "White"],
material: "80% Cotton, 20% Polyester", care: "Machine wash cold with similar colors. Tumble dry low."};
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
@@ -71,150 +63,153 @@ export default function ProductPage() {
/>
</div>
<div id="product" data-section="product" className="mx-auto px-4 md:px-6 py-20">
<div className="max-w-6xl mx-auto">
<Link href="/shop" className="text-accent hover:text-background-accent mb-8 inline-block">
Back to Shop
</Link>
<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">
Back to Shop
</Link>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 mb-16">
{/* Product Image */}
<div>
<div className="bg-card rounded-soft overflow-hidden h-96 md:h-full">
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
{/* Product Image */}
<div className="flex items-center justify-center bg-card/50 border border-accent/20 rounded-soft h-96 md:h-auto">
<img
src={product.image}
alt={product.name}
className="w-full h-full object-cover"
src="http://img.b2bpic.net/free-photo/medium-shot-man-posing-with-hoodie-indoors_23-2149359859.jpg"
alt="Classic Black Hoodie"
className="w-full h-full object-cover rounded-soft"
/>
</div>
</div>
{/* Product Details */}
<div className="flex flex-col">
<h1 className="text-4xl font-semibold text-foreground mb-4">{product.name}</h1>
<div className="flex items-center gap-4 mb-6">
<div className="flex items-center">
<span className="text-xl font-semibold text-background-accent">{product.rating}</span>
<span className="text-foreground/50 ml-2">({product.reviewCount} reviews)</span>
{/* Product Details */}
<div>
<div className="mb-6">
<p className="text-accent text-sm font-semibold mb-2">Premium Collection</p>
<h1 className="text-4xl font-semibold text-foreground mb-3">Classic Black Hoodie</h1>
<p className="text-2xl font-bold text-background-accent mb-4">$89.99</p>
<p className="text-foreground/70 leading-relaxed">
Experience the perfect blend of comfort and style with our Classic Black Hoodie. Crafted from premium materials, this versatile piece is ideal for layering or wearing alone. The spacious fit and quality construction make it a wardrobe essential for any streetwear enthusiast.
</p>
</div>
</div>
<div className="text-3xl font-bold text-background-accent mb-6">
${product.price.toFixed(2)}
</div>
{/* Color Selection */}
<div className="mb-6">
<label className="block text-foreground font-semibold mb-3">Color</label>
<div className="flex gap-3">
{["Black", "Grey", "Navy"].map((color) => (
<button
key={color}
onClick={() => setSelectedColor(color)}
className={`px-4 py-2 rounded-soft border-2 transition-all ${
selectedColor === color
? "border-background-accent bg-background-accent/10"
: "border-accent/30 hover:border-accent/50"
}`}
>
{color}
</button>
))}
</div>
</div>
<p className="text-foreground/70 mb-8 leading-relaxed">{product.description}</p>
{/* Size Selection */}
<div className="mb-6">
<label className="block text-foreground font-semibold mb-3">Size</label>
<div className="flex gap-3">
{["XS", "S", "M", "L", "XL", "XXL"].map((size) => (
<button
key={size}
onClick={() => setSelectedSize(size)}
className={`w-10 h-10 rounded-soft border-2 transition-all flex items-center justify-center ${
selectedSize === size
? "border-background-accent bg-background-accent/10"
: "border-accent/30 hover:border-accent/50"
}`}
>
{size}
</button>
))}
</div>
</div>
{/* Size Selection */}
<div className="mb-8">
<label className="block text-foreground font-semibold mb-3">Size</label>
<div className="flex flex-wrap gap-3">
{product.sizes.map((size) => (
{/* Quantity */}
<div className="mb-8">
<label className="block text-foreground font-semibold mb-3">Quantity</label>
<div className="flex items-center gap-4 w-fit">
<button
key={size}
onClick={() => setSelectedSize(size)}
className={`px-4 py-2 border rounded-soft transition-all ${
selectedSize === size
? "bg-background-accent text-primary-cta-text border-background-accent"
: "border-accent/30 text-foreground hover:border-accent"
}`}
onClick={() => setQuantity(Math.max(1, quantity - 1))}
className="w-10 h-10 rounded-soft border border-accent/30 flex items-center justify-center hover:bg-accent/10"
>
{size}
</button>
))}
</div>
</div>
{/* Color Selection */}
<div className="mb-8">
<label className="block text-foreground font-semibold mb-3">Color</label>
<div className="flex flex-wrap gap-3">
{product.colors.map((color) => (
<span className="text-lg font-semibold text-foreground w-8 text-center">{quantity}</span>
<button
key={color}
onClick={() => setSelectedColor(color)}
className={`px-4 py-2 border rounded-soft transition-all ${
selectedColor === color
? "bg-background-accent text-primary-cta-text border-background-accent"
: "border-accent/30 text-foreground hover:border-accent"
}`}
onClick={() => setQuantity(quantity + 1)}
className="w-10 h-10 rounded-soft border border-accent/30 flex items-center justify-center hover:bg-accent/10"
>
{color}
+
</button>
))}
</div>
</div>
</div>
{/* Quantity */}
<div className="mb-8">
<label className="block text-foreground font-semibold mb-3">Quantity</label>
<div className="flex items-center gap-4 bg-accent/10 rounded-soft p-2 w-fit">
<button
onClick={() => setQuantity(Math.max(1, quantity - 1))}
className="px-3 py-1 hover:bg-accent/20 rounded transition-colors"
>
{/* Action Buttons */}
<div className="flex gap-4 mb-8">
<button 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">
<ShoppingCart size={20} />
Add to Cart
</button>
<span className="text-foreground font-semibold w-8 text-center">{quantity}</span>
<button
onClick={() => setQuantity(quantity + 1)}
className="px-3 py-1 hover:bg-accent/20 rounded transition-colors"
onClick={() => setIsFavorited(!isFavorited)}
className="px-6 py-3 border border-accent/50 text-foreground font-semibold rounded-soft hover:bg-accent/10 transition-colors flex items-center justify-center gap-2"
>
+
<Heart size={20} fill={isFavorited ? "currentColor" : "none"} />
</button>
</div>
</div>
{/* Action Buttons */}
<div className="flex flex-col gap-3 mb-8">
<button className="w-full px-6 py-3 bg-background-accent text-primary-cta-text font-semibold rounded-soft hover:bg-primary-cta hover:text-primary-cta-text transition-colors flex items-center justify-center gap-2">
<ShoppingCart size={20} />
Add to Cart
</button>
<div className="flex gap-3">
<button
onClick={() => setIsFavorite(!isFavorite)}
className={`flex-1 px-6 py-3 border rounded-soft font-semibold transition-all ${
isFavorite
? "bg-background-accent/20 border-background-accent text-background-accent"
: "border-accent/30 text-foreground hover:border-accent"
}`}
>
<Heart size={20} className="inline mr-2" />
Favorite
</button>
<button className="flex-1 px-6 py-3 border border-accent/30 text-foreground font-semibold rounded-soft hover:border-accent transition-colors flex items-center justify-center gap-2">
<Share2 size={20} />
Share
</button>
{/* Product Info */}
<div className="bg-card/50 border border-accent/20 rounded-soft p-6 space-y-4">
<div>
<p className="text-accent font-semibold text-sm">Material</p>
<p className="text-foreground">100% Premium Cotton</p>
</div>
<div>
<p className="text-accent font-semibold text-sm">Shipping</p>
<p className="text-foreground">Free shipping on orders over $150</p>
</div>
<div>
<p className="text-accent font-semibold text-sm">Returns</p>
<p className="text-foreground">30-day return policy</p>
</div>
</div>
</div>
{product.inStock ? (
<p className="text-background-accent font-semibold"> In Stock - Ships within 24 hours</p>
) : (
<p className="text-red-500 font-semibold">Out of Stock</p>
)}
</div>
</div>
{/* Product Info */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-16 bg-card/50 border border-accent/20 rounded-soft p-8">
<div>
<h3 className="text-xl font-semibold text-foreground mb-4">Material & Care</h3>
<p className="text-foreground/70 mb-4">
<span className="font-semibold">Material:</span> {product.material}
</p>
<p className="text-foreground/70">
<span className="font-semibold">Care:</span> {product.care}
</p>
</div>
<div>
<h3 className="text-xl font-semibold text-foreground mb-4">Shipping & Returns</h3>
<p className="text-foreground/70 mb-2"> Free shipping on orders over $150</p>
<p className="text-foreground/70 mb-2"> 30-day returns with free return shipping</p>
<p className="text-foreground/70"> Easy exchanges within 30 days</p>
{/* Related Products */}
<div className="mt-20">
<h2 className="text-3xl font-semibold text-foreground mb-8">Related Products</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{[
{
name: "Vintage Denim Jacket", price: "$129.99", image: "http://img.b2bpic.net/free-photo/fashionable-woman-wearing-denim-jacket_23-2148859621.jpg"},
{
name: "Cargo Pants - Khaki", price: "$79.99", image: "http://img.b2bpic.net/free-photo/young-woman-wearing-trucker-hat_23-2149432334.jpg"},
{
name: "Oversized T-Shirt", price: "$49.99", image: "http://img.b2bpic.net/free-photo/teenager-boy-stylish-clothes-posing_23-2149085228.jpg"},
].map((product, i) => (
<Link key={i} href="#" className="group">
<div className="bg-card/50 border border-accent/20 rounded-soft overflow-hidden mb-4 h-60">
<img
src={product.image}
alt={product.name}
className="w-full h-full object-cover group-hover:scale-105 transition-transform"
/>
</div>
<h3 className="text-foreground font-semibold mb-2 group-hover:text-background-accent transition-colors">
{product.name}
</h3>
<p className="text-background-accent font-semibold">{product.price}</p>
</Link>
))}
</div>
</div>
</div>
</div>

View File

@@ -8,8 +8,9 @@ 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>) => (
const TikTok: LucideIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -20,7 +21,7 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
>
<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 LucideIcon;
export default function ShopPage() {
const navItems = [
@@ -31,7 +32,7 @@ export default function ShopPage() {
{ name: "Contact", id: "contact" },
];
const socialLinks = [
const socialLinks: Array<{ icon: LucideIcon; 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" },