15 Commits

Author SHA1 Message Date
5f737566c2 Update src/app/styles/variables.css 2026-03-06 17:22:35 +00:00
458ac401fd Update src/app/styles/base.css 2026-03-06 17:22:35 +00:00
9c68f66c75 Update src/app/page.tsx 2026-03-06 17:22:34 +00:00
6480b018fd Update src/app/layout.tsx 2026-03-06 17:22:33 +00:00
2150c392b3 Add src/app/delivery/page.tsx 2026-03-06 17:22:33 +00:00
a4ecac4044 Add src/app/contact/page.tsx 2026-03-06 17:22:32 +00:00
d18999f563 Add src/app/checkout/page.tsx 2026-03-06 17:22:32 +00:00
a0900563ff Add src/app/catalog/page.tsx 2026-03-06 17:22:31 +00:00
d72637aa74 Add src/app/catalog/[id]/page.tsx 2026-03-06 17:22:31 +00:00
f6e47dcb15 Add src/app/api/orders/route.ts 2026-03-06 17:22:30 +00:00
ae5f1922a4 Add src/app/admin/page.tsx 2026-03-06 17:22:30 +00:00
b08690bb9a Add src/app/about/page.tsx 2026-03-06 17:22:30 +00:00
32e0ca77c5 Merge version_1 into main
Merge version_1 into main
2026-03-06 17:14:43 +00:00
29da3bb51c Merge version_1 into main
Merge version_1 into main
2026-03-06 17:13:53 +00:00
5b7bdf372c Merge version_1 into main
Merge version_1 into main
2026-03-06 17:12:26 +00:00
12 changed files with 1785 additions and 54 deletions

82
src/app/about/page.tsx Normal file
View File

@@ -0,0 +1,82 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import TextAbout from "@/components/sections/about/TextAbout";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
export default function AboutPage() {
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Home", id: "/" },
{ name: "Catalog", id: "/catalog" },
{ name: "About", id: "/about" },
{ name: "Delivery", id: "/delivery" },
{ name: "Contact", id: "/contact" },
]}
/>
</div>
<div id="about" data-section="about" className="pt-20">
<TextAbout
tag="💝 Our Story"
title="Fatinur Flowers - Expressing Love and Beauty Through Flowers"
useInvertedBackground={false}
buttons={[{ text: "Contact Us", href: "/contact" }]}
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers"
columns={[
{
title: "Products", items: [
{ label: "Flower Catalog", href: "/catalog" },
{ label: "Categories", href: "/catalog" },
{ label: "Popular Bouquets", href: "/catalog" },
],
},
{
title: "Company", items: [
{ label: "About Us", href: "/about" },
{ label: "Delivery Info", href: "/delivery" },
{ label: "Contact", href: "/contact" },
],
},
{
title: "Connect", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
{ label: "WhatsApp", href: "https://wa.me/998901234567" },
],
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "/privacy" },
{ label: "Terms of Service", href: "/terms" },
{ label: "Cookie Policy", href: "/cookies" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers. All rights reserved."
/>
</div>
</ThemeProvider>
);
}

633
src/app/admin/page.tsx Normal file
View File

@@ -0,0 +1,633 @@
"use client";
import { useState } from "react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
import Input from "@/components/form/Input";
import {
LogOut,
Package,
FolderOpen,
ShoppingCart,
Users,
TrendingUp,
Upload,
Edit,
Trash2,
Plus,
X,
} from "lucide-react";
type AdminTab = "login" | "products" | "categories" | "orders" | "customers" | "analytics";
interface Product {
id: string;
name: string;
price: number;
category: string;
image?: string;
description?: string;
}
interface Category {
id: string;
name: string;
}
interface Order {
id: string;
customerName: string;
status: "pending" | "processing" | "delivered" | "cancelled";
total: number;
date: string;
}
interface Customer {
id: string;
name: string;
email: string;
phone: string;
orders: number;
}
export default function AdminPanel() {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [currentTab, setCurrentTab] = useState<AdminTab>("login");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
// Products state
const [products, setProducts] = useState<Product[]>([
{
id: "1", name: "Qizil Roza Buket", price: 250000,
category: "Rozalar", description: "Premium qizil rozalar"},
{
id: "2", name: "Tula Aralash", price: 180000,
category: "Tulalar", description: "Aralash rangli tulalar"},
]);
const [newProduct, setNewProduct] = useState<Partial<Product>>({
name: "", price: 0,
category: "", description: ""});
const [editingProductId, setEditingProductId] = useState<string | null>(null);
// Categories state
const [categories, setCategories] = useState<Category[]>([
{ id: "1", name: "Rozalar" },
{ id: "2", name: "Tulalar" },
{ id: "3", name: "Siyavushlar" },
]);
const [newCategory, setNewCategory] = useState("");
// Orders state
const [orders, setOrders] = useState<Order[]>([
{
id: "1", customerName: "Ayubjon Raximov", status: "delivered", total: 250000,
date: "2025-01-15"},
{
id: "2", customerName: "Dilorom Ibragimova", status: "processing", total: 180000,
date: "2025-01-16"},
]);
// Customers state
const [customers] = useState<Customer[]>([
{
id: "1", name: "Ayubjon Raximov", email: "ayubjon@example.com", phone: "+998901234567", orders: 5,
},
{
id: "2", name: "Dilorom Ibragimova", email: "dilorom@example.com", phone: "+998912345678", orders: 3,
},
]);
// Analytics data
const topSellingProducts = [
{ name: "Qizil Roza Buket", sales: 45 },
{ name: "Tula Aralash", sales: 32 },
{ name: "Oyoq Buket", sales: 28 },
{ name: "Oq Lililar", sales: 19 },
];
const handleLogin = () => {
if (email === "admin@fatinur.com" && password === "admin123") {
setIsAuthenticated(true);
setCurrentTab("products");
setEmail("");
setPassword("");
} else {
alert("Login yoki parol noto'g'ri");
}
};
const handleLogout = () => {
setIsAuthenticated(false);
setCurrentTab("login");
};
const handleAddProduct = () => {
if (newProduct.name && newProduct.price && newProduct.category) {
if (editingProductId) {
setProducts(
products.map((p) =>
p.id === editingProductId
? { ...p, ...newProduct }
: p
) as Product[]
);
setEditingProductId(null);
} else {
setProducts([
...products,
{
id: Date.now().toString(),
name: newProduct.name,
price: newProduct.price,
category: newProduct.category,
description: newProduct.description || ""},
]);
}
setNewProduct({ name: "", price: 0, category: "", description: "" });
}
};
const handleDeleteProduct = (id: string) => {
setProducts(products.filter((p) => p.id !== id));
};
const handleAddCategory = () => {
if (newCategory.trim()) {
setCategories([
...categories,
{ id: Date.now().toString(), name: newCategory },
]);
setNewCategory("");
}
};
const handleDeleteCategory = (id: string) => {
setCategories(categories.filter((c) => c.id !== id));
};
const handleUpdateOrderStatus = (orderId: string, newStatus: Order["status"]) => {
setOrders(
orders.map((o) => (o.id === orderId ? { ...o, status: newStatus } : o))
);
};
if (!isAuthenticated) {
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Бош сахифа", id: "/" },
{ name: "Admin", id: "/admin" },
]}
/>
</div>
<div className="min-h-[calc(100vh-80px)] flex items-center justify-center bg-background p-4">
<div className="w-full max-w-md p-8 rounded-lg bg-card border border-background-accent shadow-lg">
<h1 className="text-3xl font-bold mb-8 text-center text-foreground">
Admin Panel
</h1>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Email
</label>
<Input
value={email}
onChange={setEmail}
type="email"
placeholder="admin@fatinur.com"
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Parol
</label>
<Input
value={password}
onChange={setPassword}
type="password"
placeholder="Password"
/>
</div>
<button
onClick={handleLogin}
className="w-full bg-primary-cta text-white py-2 px-4 rounded-lg hover:opacity-90 font-medium transition-opacity"
>
Kirish
</button>
<p className="text-sm text-foreground/60 text-center mt-4">
Demo credentials: admin@fatinur.com / admin123
</p>
</div>
</div>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers"
columns={[
{
title: "Aloqa", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers Admin"
/>
</div>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers Admin"
navItems={[
{ name: "Асоси", id: "/admin" },
{ name: "Товарлар", id: "/admin#products" },
{ name: "Категорияlar", id: "/admin#categories" },
{ name: "Buyurtmalar", id: "/admin#orders" },
{ name: "Чиқиш", id: "/" },
]}
/>
</div>
<div className="min-h-[calc(100vh-80px)] bg-background p-6">
<div className="max-w-7xl mx-auto">
{/* Header */}
<div className="flex justify-between items-center mb-8">
<h1 className="text-4xl font-bold text-foreground">Admin Panel</h1>
<button
onClick={handleLogout}
className="flex items-center gap-2 bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition-colors"
>
<LogOut size={20} />
Чиқиш
</button>
</div>
{/* Navigation Tabs */}
<div className="flex gap-4 mb-8 overflow-x-auto">
{[
{ id: "products", label: "Товарлар", icon: Package },
{ id: "categories", label: "Категорияlar", icon: FolderOpen },
{ id: "orders", label: "Buyurtmalar", icon: ShoppingCart },
{ id: "customers", label: "Мижозлар", icon: Users },
{ id: "analytics", label: "Статистика", icon: TrendingUp },
].map((tab) => {
const Icon = tab.icon;
return (
<button
key={tab.id}
onClick={() => setCurrentTab(tab.id as AdminTab)}
className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-all ${
currentTab === tab.id
? "bg-primary-cta text-white"
: "bg-card text-foreground hover:bg-background-accent"
}`}
>
<Icon size={20} />
{tab.label}
</button>
);
})}
</div>
{/* Content */}
<div className="bg-card rounded-lg p-6 border border-background-accent">
{/* Products Tab */}
{currentTab === "products" && (
<div className="space-y-6">
<h2 className="text-2xl font-bold text-foreground">Махсулотларни Бошқариш</h2>
{/* Add Product Form */}
<div className="bg-background rounded-lg p-4 space-y-4">
<h3 className="text-lg font-semibold text-foreground">
{editingProductId ? "Махсулотни Редактировать" : "Янги Махсулот Қўшиш"}
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Input
value={newProduct.name || ""}
onChange={(val) =>
setNewProduct({ ...newProduct, name: val })
}
placeholder="Махсулот номи"
/>
<Input
value={newProduct.price?.toString() || ""}
onChange={(val) =>
setNewProduct({ ...newProduct, price: Number(val) })
}
type="number"
placeholder="Нарх"
/>
<Input
value={newProduct.category || ""}
onChange={(val) =>
setNewProduct({ ...newProduct, category: val })
}
placeholder="Категория"
/>
<Input
value={newProduct.description || ""}
onChange={(val) =>
setNewProduct({ ...newProduct, description: val })
}
placeholder="Тавсифи"
/>
</div>
<div className="flex gap-2">
<button
onClick={handleAddProduct}
className="flex items-center gap-2 bg-primary-cta text-white px-4 py-2 rounded-lg hover:opacity-90 transition-opacity"
>
<Plus size={20} />
{editingProductId ? "Янгилаш" : "Қўшиш"}
</button>
{editingProductId && (
<button
onClick={() => {
setEditingProductId(null);
setNewProduct({ name: "", price: 0, category: "", description: "" });
}}
className="flex items-center gap-2 bg-background-accent text-foreground px-4 py-2 rounded-lg hover:opacity-90 transition-opacity"
>
<X size={20} />
Беккор
</button>
)}
</div>
</div>
{/* Products List */}
<div className="space-y-2">
{products.map((product) => (
<div
key={product.id}
className="flex justify-between items-center p-4 bg-background rounded-lg border border-background-accent"
>
<div>
<h4 className="font-semibold text-foreground">{product.name}</h4>
<p className="text-sm text-foreground/60">
Категория: {product.category} | Нарх: {product.price.toLocaleString()} so'm
</p>
</div>
<div className="flex gap-2">
<button
onClick={() => {
setEditingProductId(product.id);
setNewProduct(product);
}}
className="p-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
>
<Edit size={18} />
</button>
<button
onClick={() => handleDeleteProduct(product.id)}
className="p-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"
>
<Trash2 size={18} />
</button>
</div>
</div>
))}
</div>
</div>
)}
{/* Categories Tab */}
{currentTab === "categories" && (
<div className="space-y-6">
<h2 className="text-2xl font-bold text-foreground">Категорияларни Бошқариш</h2>
{/* Add Category Form */}
<div className="bg-background rounded-lg p-4 space-y-4">
<div className="flex gap-2">
<Input
value={newCategory}
onChange={setNewCategory}
placeholder="Янги категория номи"
/>
<button
onClick={handleAddCategory}
className="bg-primary-cta text-white px-6 py-2 rounded-lg hover:opacity-90 transition-opacity"
>
Қўшиш
</button>
</div>
</div>
{/* Categories List */}
<div className="space-y-2">
{categories.map((category) => (
<div
key={category.id}
className="flex justify-between items-center p-4 bg-background rounded-lg border border-background-accent"
>
<span className="text-foreground font-medium">{category.name}</span>
<button
onClick={() => handleDeleteCategory(category.id)}
className="p-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"
>
<Trash2 size={18} />
</button>
</div>
))}
</div>
</div>
)}
{/* Orders Tab */}
{currentTab === "orders" && (
<div className="space-y-6">
<h2 className="text-2xl font-bold text-foreground">Buyurtmаларни Бошқариш</h2>
{/* Orders List */}
<div className="space-y-3">
{orders.map((order) => (
<div
key={order.id}
className="p-4 bg-background rounded-lg border border-background-accent"
>
<div className="flex justify-between items-center mb-3">
<div>
<h4 className="font-semibold text-foreground">ID: {order.id}</h4>
<p className="text-sm text-foreground/60">{order.customerName}</p>
</div>
<div className="text-right">
<p className="font-semibold text-foreground">
{order.total.toLocaleString()} so'm
</p>
<p className="text-sm text-foreground/60">{order.date}</p>
</div>
</div>
<div className="flex gap-2">
{[
"pending", "processing", "delivered", "cancelled"].map((status) => (
<button
key={status}
onClick={() =>
handleUpdateOrderStatus(
order.id,
status as Order["status"]
)
}
className={`px-3 py-1 text-sm rounded-lg transition-all ${
order.status === status
? "bg-primary-cta text-white"
: "bg-background-accent text-foreground hover:opacity-75"
}`}
>
{status === "pending"
? "Kutilmoqda"
: status === "processing"
? "Qayta Ishlash"
: status === "delivered"
? "Yetkazib berish"
: "Bekor qilish"}
</button>
))}
</div>
</div>
))}
</div>
</div>
)}
{/* Customers Tab */}
{currentTab === "customers" && (
<div className="space-y-6">
<h2 className="text-2xl font-bold text-foreground">Мижозларни Кўриш</h2>
{/* Customers List */}
<div className="space-y-2">
{customers.map((customer) => (
<div
key={customer.id}
className="p-4 bg-background rounded-lg border border-background-accent"
>
<div className="flex justify-between items-start">
<div>
<h4 className="font-semibold text-foreground">{customer.name}</h4>
<p className="text-sm text-foreground/60">{customer.email}</p>
<p className="text-sm text-foreground/60">{customer.phone}</p>
</div>
<div className="text-right">
<p className="font-semibold text-foreground">Buyurtmalar: {customer.orders}</p>
</div>
</div>
</div>
))}
</div>
</div>
)}
{/* Analytics Tab */}
{currentTab === "analytics" && (
<div className="space-y-6">
<h2 className="text-2xl font-bold text-foreground">
Энг Йўқори Сотувчи Гуллар
</h2>
{/* Top Selling Products */}
<div className="space-y-3">
{topSellingProducts.map((product, index) => (
<div
key={index}
className="p-4 bg-background rounded-lg border border-background-accent"
>
<div className="flex justify-between items-center mb-2">
<h4 className="font-semibold text-foreground">
{index + 1}. {product.name}
</h4>
<span className="text-lg font-bold text-primary-cta">
{product.sales} сотув
</span>
</div>
<div className="w-full bg-background-accent rounded-full h-2">
<div
className="bg-primary-cta h-2 rounded-full"
style={{
width: `${(
(product.sales / topSellingProducts[0].sales) *
100
).toFixed(0)}%`,
}}
/>
</div>
</div>
))}
</div>
{/* Summary Stats */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
<div className="p-4 bg-background rounded-lg border border-background-accent">
<p className="text-foreground/60 text-sm">Умумий Махсулотлар</p>
<p className="text-3xl font-bold text-foreground">{products.length}</p>
</div>
<div className="p-4 bg-background rounded-lg border border-background-accent">
<p className="text-foreground/60 text-sm">Умумий Buyurtmalar</p>
<p className="text-3xl font-bold text-foreground">{orders.length}</p>
</div>
<div className="p-4 bg-background rounded-lg border border-background-accent">
<p className="text-foreground/60 text-sm">Умумий Мижозлар</p>
<p className="text-3xl font-bold text-foreground">{customers.length}</p>
</div>
<div className="p-4 bg-background rounded-lg border border-background-accent">
<p className="text-foreground/60 text-sm">Кўп Сотувчи Категория</p>
<p className="text-3xl font-bold text-foreground">Розалар</p>
</div>
</div>
</div>
)}
</div>
</div>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers Admin"
columns={[
{
title: "Aloqa", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers Admin Panel"
/>
</div>
</ThemeProvider>
);
}

136
src/app/api/orders/route.ts Normal file
View File

@@ -0,0 +1,136 @@
import { NextRequest, NextResponse } from "next/server";
interface OrderData {
fullName: string;
email: string;
phone: string;
address: string;
city: string;
postalCode: string;
message: string;
}
// Mock in-memory database for demonstration
const orders: OrderData[] = [];
// Telegram Bot configuration
const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN || "";
const TELEGRAM_CHAT_ID = process.env.TELEGRAM_CHAT_ID || "";
async function sendTelegramNotification(order: OrderData) {
if (!TELEGRAM_BOT_TOKEN || !TELEGRAM_CHAT_ID) {
console.warn(
"Telegram credentials not configured. Skipping notification."
);
return;
}
const message = `
🌸 *YANGI BUYURTMA* 🌸
👤 *Ism:* ${order.fullName}
📧 *Email:* ${order.email}
📞 *Telefon:* ${order.phone}
📍 *Manzil:* ${order.address}, ${order.city}
📮 *Postal kod:* ${order.postalCode || "Berilmagan"}
💬 *Xabar:* ${order.message || "Xabar berilmagan"}
⏰ *Vaqti:* ${new Date().toLocaleString("uz-UZ")}
`;
try {
const response = await fetch(
`https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`,
{
method: "POST", headers: {
"Content-Type": "application/json"},
body: JSON.stringify({
chat_id: TELEGRAM_CHAT_ID,
text: message,
parse_mode: "Markdown"}),
}
);
if (!response.ok) {
throw new Error(`Telegram API error: ${response.statusText}`);
}
console.log("Telegram notification sent successfully");
} catch (error) {
console.error("Failed to send Telegram notification:", error);
throw error;
}
}
export async function POST(request: NextRequest) {
try {
const body: OrderData = await request.json();
// Validate required fields
if (
!body.fullName ||
!body.email ||
!body.phone ||
!body.address ||
!body.city
) {
return NextResponse.json(
{ error: "Missing required fields" },
{ status: 400 }
);
}
// Add timestamp and ID
const orderWithMetadata = {
...body,
id: Date.now().toString(),
createdAt: new Date().toISOString(),
};
// Save to mock database
orders.push(body);
console.log("Order saved to database:", orderWithMetadata);
// Send Telegram notification
await sendTelegramNotification(body);
// Return success response
return NextResponse.json(
{
success: true,
message: "Buyurtma muvaffaqiyatli qabul qilindi", orderId: orderWithMetadata.id,
},
{ status: 201 }
);
} catch (error) {
console.error("Error processing order:", error);
return NextResponse.json(
{
success: false,
error: "Buyurtmani qayta ishlashda xatolik yuz berdi"},
{ status: 500 }
);
}
}
export async function GET() {
try {
return NextResponse.json(
{
orders,
total: orders.length,
},
{ status: 200 }
);
} catch (error) {
console.error("Error fetching orders:", error);
return NextResponse.json(
{ error: "Buyurtmalarni olishda xatolik yuz berdi" },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,325 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
import { Heart, Share2, Truck, Shield, RotateCcw } from "lucide-react";
import { useState } from "react";
const products: { [key: string]: any } = {
"1": {
id: "1", name: "Qizil Roza Buket", price: "250,000 so'm", description: "Eng sifatli qizil rozalardan tayyorlangan, sevgi va ishtiyoqni ifodalovchi luxurious buket.", images: [
"http://img.b2bpic.net/free-photo/beautifully-wrapped-gift-bouquet-roses_169016-8520.jpg?_wi=2", "http://img.b2bpic.net/free-photo/side-view-yellow-red-tulip-flower-grey_140725-12248.jpg?_wi=2"],
category: "Rozalar", rating: 4.8,
reviews: 45,
details: [
"20+ qizil roza", "Yangi gullar", "Professional dizayn", "Zita oramiga o'ralgan"],
},
"2": {
id: "2", name: "Tula Aralash", price: "180,000 so'm", description: "Turli rangdagi tulalardan tayyorlangan, ko'pikka va optimizmni ifodalovchi buket.", images: [
"http://img.b2bpic.net/free-photo/side-view-yellow-red-tulip-flower-grey_140725-12248.jpg?_wi=2", "http://img.b2bpic.net/free-photo/beautifully-wrapped-gift-bouquet-roses_169016-8520.jpg?_wi=2"],
category: "Tulalar", rating: 4.6,
reviews: 32,
details: [
"15+ turli rang tula", "Bahor hissiyoti", "Chiroyli dizayn", "Sifatli oramiga"],
},
"3": {
id: "3", name: "Oyoq Buket", price: "220,000 so'm", description: "Jonli sariq oyoqlardan tayyorlangan, xursandlik va farovonlikni ifodalovchi buket.", images: [
"http://img.b2bpic.net/free-photo/top-view-sunflowers-frame-with-copy-space_23-2150250788.jpg?_wi=2", "http://img.b2bpic.net/free-photo/side-view-bouquet-peach-cream-color-roses-with-asparagus-grey-wooden-background_141793-7974.jpg?_wi=2"],
category: "Oyoqlar", rating: 4.9,
reviews: 58,
details: [
"12+ sariq oyoq", "Yangi yetkazildi", "Jonli rang", "Premium dizayn"],
},
"4": {
id: "4", name: "Oq Lililar", price: "280,000 so'm", description: "Nozik oq lililardan tayyorlangan, murassa va qilburchi hissiyotini ifodalovchi buket.", images: [
"http://img.b2bpic.net/free-photo/side-view-bouquet-peach-cream-color-roses-with-asparagus-grey-wooden-background_141793-7974.jpg?_wi=2", "http://img.b2bpic.net/free-photo/beautifully-wrapped-gift-bouquet-roses_169016-8520.jpg?_wi=2"],
category: "Lililar", rating: 4.7,
reviews: 41,
details: [
"8+ oq lilia", "Aromatic xush hid", "Nozik shakllanish", "Luxury oramiga"],
},
"5": {
id: "5", name: "Orchid Elegance", price: "300,000 so'm", description: "Ekzotik orkideyalardan tayyorlangan, murassa va yuqori dadning belgisi buket.", images: [
"http://img.b2bpic.net/free-photo/beautifully-wrapped-gift-bouquet-roses_169016-8520.jpg?_wi=2", "http://img.b2bpic.net/free-photo/side-view-yellow-red-tulip-flower-grey_140725-12248.jpg?_wi=2"],
category: "Orkideya", rating: 5.0,
reviews: 23,
details: [
"10+ orkideya", "Ekzotik rang", "Premium qadri", "Davom etuvchi xush hid"],
},
"6": {
id: "6", name: "Dahlia Dream", price: "200,000 so'm", description: "Gʻamrasin dalialari, ranglariga va shakllanishiga ega, go'zal buket.", images: [
"http://img.b2bpic.net/free-photo/side-view-yellow-red-tulip-flower-grey_140725-12248.jpg?_wi=2", "http://img.b2bpic.net/free-photo/top-view-sunflowers-frame-with-copy-space_23-2150250788.jpg?_wi=2"],
category: "Dalialar", rating: 4.5,
reviews: 28,
details: [
"15+ dahlia", "Turli rang", "Rang tutgan", "Chiroyli qadri"],
},
"7": {
id: "7", name: "Mixed Spring", price: "240,000 so'm", description: "Bahor gullarining aralashmasi, tabiatning go'zalligini o'zida ifodalovchi buket.", images: [
"http://img.b2bpic.net/free-photo/top-view-sunflowers-frame-with-copy-space_23-2150250788.jpg?_wi=2", "http://img.b2bpic.net/free-photo/side-view-bouquet-peach-cream-color-roses-with-asparagus-grey-wooden-background_141793-7974.jpg?_wi=2"],
category: "Aralash", rating: 4.6,
reviews: 37,
details: [
"30+ turli gullar", "Rang harmoniyasi", "Bahor hissiyoti", "Professional surattirish"],
},
"8": {
id: "8", name: "Premium Exotic", price: "320,000 so'm", description: "Ekzotik gullarning premium jamiyati, eng yuqori sifat va dizayn standartlari.", images: [
"http://img.b2bpic.net/free-photo/side-view-bouquet-peach-cream-color-roses-with-asparagus-grey-wooden-background_141793-7974.jpg?_wi=2", "http://img.b2bpic.net/free-photo/beautifully-wrapped-gift-bouquet-roses_169016-8520.jpg?_wi=2"],
category: "Ekzotik", rating: 4.9,
reviews: 19,
details: [
"20+ ekzotik gullar", "Premium qadri", "Master florist dizayn", "Saqlanish davomi 7+ kun"],
},
};
export default function ProductDetailPage({
params,
}: {
params: { id: string };
}) {
const product = products[params.id];
const [isFavorited, setIsFavorited] = useState(false);
const [mainImage, setMainImage] = useState(0);
const [quantity, setQuantity] = useState(1);
if (!product) {
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Бош сахифа", id: "/" },
{ name: "Каталог", id: "/catalog" },
{ name: "Категорияlar", id: "#features" },
{ name: "Биз хақимизда", id: "#about" },
{ name: "Aloqa", id: "#contact" },
]}
/>
</div>
<div className="py-20 text-center">Mahsulot topilmadi</div>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Бош сахифа", id: "/" },
{ name: "Каталог", id: "/catalog" },
{ name: "Категорияlar", id: "#features" },
{ name: "Биз хақимизда", id: "#about" },
{ name: "Aloqa", id: "#contact" },
]}
/>
</div>
<div className="py-20 px-4">
<div className="max-w-6xl mx-auto">
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
{/* Product Images */}
<div>
<div className="bg-card rounded-lg overflow-hidden mb-4 aspect-square">
<img
src={product.images[mainImage]}
alt={product.name}
className="w-full h-full object-cover"
/>
</div>
<div className="flex gap-4">
{product.images.map((img: string, idx: number) => (
<button
key={idx}
onClick={() => setMainImage(idx)}
className={`w-20 h-20 rounded-lg overflow-hidden border-2 transition-all ${
mainImage === idx
? "border-primary-cta"
: "border-foreground/20 hover:border-foreground/40"
}`}
>
<img
src={img}
alt={`Thumbnail ${idx}`}
className="w-full h-full object-cover"
/>
</button>
))}
</div>
</div>
{/* Product Details */}
<div>
<div className="mb-4">
<span className="text-sm text-primary-cta font-medium">
{product.category}
</span>
</div>
<h1 className="text-4xl font-bold mb-4">{product.name}</h1>
<div className="flex items-center gap-2 mb-6">
<div className="flex text-yellow-400">
{[...Array(5)].map((_, i) => (
<span key={i}>
{i < Math.floor(product.rating) ? "★" : "☆"}
</span>
))}
</div>
<span className="text-foreground/75">
{product.rating} ({product.reviews} sharhlar)
</span>
</div>
<p className="text-2xl font-bold text-primary-cta mb-4">
{product.price}
</p>
<p className="text-foreground/75 mb-8 text-lg">
{product.description}
</p>
{/* Details List */}
<div className="mb-8">
<h3 className="font-bold mb-4">Mahsulot xususiyatlari:</h3>
<ul className="space-y-2">
{product.details.map((detail: string, idx: number) => (
<li key={idx} className="flex items-center gap-3">
<span className="text-primary-cta"></span>
<span>{detail}</span>
</li>
))}
</ul>
</div>
{/* Quantity and Actions */}
<div className="mb-8">
<label className="block text-sm font-medium mb-2">Miqdor:</label>
<div className="flex items-center gap-4 mb-6">
<button
onClick={() => setQuantity(Math.max(1, quantity - 1))}
className="px-4 py-2 bg-card rounded-lg hover:bg-foreground/10 transition"
>
</button>
<span className="text-xl font-bold w-8 text-center">
{quantity}
</span>
<button
onClick={() => setQuantity(quantity + 1)}
className="px-4 py-2 bg-card rounded-lg hover:bg-foreground/10 transition"
>
+
</button>
</div>
</div>
{/* Action Buttons */}
<div className="space-y-3">
<button className="w-full py-3 bg-primary-cta text-background rounded-lg font-bold hover:opacity-90 transition">
Savatchaga qo'shish
</button>
<div className="flex gap-3">
<button
onClick={() => setIsFavorited(!isFavorited)}
className={`flex-1 py-3 border-2 rounded-lg font-bold transition ${
isFavorited
? "bg-primary-cta border-primary-cta text-background"
: "border-foreground/30 hover:border-foreground/50"
}`}
>
<Heart className="w-5 h-5 inline mr-2" />
{isFavorited ? "Sevkili" : "Sevkilarga qo'sh"}
</button>
<button className="flex-1 py-3 border-2 border-foreground/30 rounded-lg font-bold hover:border-foreground/50 transition">
<Share2 className="w-5 h-5 inline mr-2" />
Ulashish
</button>
</div>
</div>
{/* Shipping Info */}
<div className="mt-8 space-y-4 pt-8 border-t border-foreground/10">
<div className="flex items-start gap-3">
<Truck className="w-5 h-5 text-primary-cta mt-1" />
<div>
<p className="font-bold">Tez Yetkazib Berish</p>
<p className="text-sm text-foreground/75">
Toshkent bo'ylab 2 soatda yetkazib berishni taklif etamiz
</p>
</div>
</div>
<div className="flex items-start gap-3">
<Shield className="w-5 h-5 text-primary-cta mt-1" />
<div>
<p className="font-bold">Sifat Kafolati</p>
<p className="text-sm text-foreground/75">
Eng sifatli gullar yoki pul qaytarish
</p>
</div>
</div>
<div className="flex items-start gap-3">
<RotateCcw className="w-5 h-5 text-primary-cta mt-1" />
<div>
<p className="font-bold">Oson Qaytarish</p>
<p className="text-sm text-foreground/75">
7 kunlik qaytarish siyosati
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers"
columns={[
{
title: "Mahsulotlar", items: [
{ label: "Gullar katalogi", href: "/catalog" },
{ label: "Eng mashhur buketlar", href: "/" },
],
},
{
title: "Kompaniya", items: [
{ label: "Biз haqimizda", href: "/#about" },
{ label: "Aloqa", href: "/#contact" },
],
},
{
title: "Aloqa", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers. Barcha huquqlar himoyalangan."
/>
</div>
</ThemeProvider>
);
}

147
src/app/catalog/page.tsx Normal file
View File

@@ -0,0 +1,147 @@
"use client";
import { useState } from "react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import ProductCardOne from "@/components/sections/product/ProductCardOne";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
const allProducts = [
{
id: "1", name: "Qizil Roza Buket", price: "250,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/beautifully-wrapped-gift-bouquet-roses_169016-8520.jpg?_wi=2", imageAlt: "Premium red rose bouquet", category: "roses", onProductClick: () => (window.location.href = "/catalog/1"),
},
{
id: "2", name: "Tula Aralash", price: "180,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/side-view-yellow-red-tulip-flower-grey_140725-12248.jpg?_wi=2", imageAlt: "Colorful mixed tulip arrangement", category: "tulips", onProductClick: () => (window.location.href = "/catalog/2"),
},
{
id: "3", name: "Oyoq Buket", price: "220,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/top-view-sunflowers-frame-with-copy-space_23-2150250788.jpg?_wi=2", imageAlt: "Bright sunflower bouquet", category: "sunflowers", onProductClick: () => (window.location.href = "/catalog/3"),
},
{
id: "4", name: "Oq Lililar", price: "280,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/side-view-bouquet-peach-cream-color-roses-with-asparagus-grey-wooden-background_141793-7974.jpg?_wi=2", imageAlt: "Elegant white lily arrangement", category: "lilies", onProductClick: () => (window.location.href = "/catalog/4"),
},
{
id: "5", name: "Orchid Elegance", price: "300,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/beautifully-wrapped-gift-bouquet-roses_169016-8520.jpg?_wi=2", imageAlt: "Elegant orchid bouquet", category: "orchids", onProductClick: () => (window.location.href = "/catalog/5"),
},
{
id: "6", name: "Dahlia Dream", price: "200,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/side-view-yellow-red-tulip-flower-grey_140725-12248.jpg?_wi=2", imageAlt: "Beautiful dahlia arrangement", category: "dahlias", onProductClick: () => (window.location.href = "/catalog/6"),
},
{
id: "7", name: "Mixed Spring", price: "240,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/top-view-sunflowers-frame-with-copy-space_23-2150250788.jpg?_wi=2", imageAlt: "Mixed spring flowers", category: "mixed", onProductClick: () => (window.location.href = "/catalog/7"),
},
{
id: "8", name: "Premium Exotic", price: "320,000 so'm", imageSrc: "http://img.b2bpic.net/free-photo/side-view-bouquet-peach-cream-color-roses-with-asparagus-grey-wooden-background_141793-7974.jpg?_wi=2", imageAlt: "Premium exotic bouquet", category: "exotic", onProductClick: () => (window.location.href = "/catalog/8"),
},
];
const categories = [
{ id: "all", name: "Barchasi" },
{ id: "roses", name: "Rozalar" },
{ id: "tulips", name: "Tulalar" },
{ id: "sunflowers", name: "Oyoqlar" },
{ id: "lilies", name: "Lililar" },
{ id: "orchids", name: "Orkideya" },
{ id: "dahlias", name: "Dalialar" },
{ id: "mixed", name: "Aralash" },
{ id: "exotic", name: "Ekzotik" },
];
export default function CatalogPage() {
const [selectedCategory, setSelectedCategory] = useState("all");
const filteredProducts =
selectedCategory === "all"
? allProducts
: allProducts.filter((product) => product.category === selectedCategory);
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Бош сахифа", id: "/" },
{ name: "Каталог", id: "/catalog" },
{ name: "Категорияlar", id: "#features" },
{ name: "Биз хақимизда", id: "#about" },
{ name: "Aloqa", id: "#contact" },
]}
/>
</div>
<div className="py-20 px-4">
<div className="max-w-7xl mx-auto">
<h1 className="text-5xl font-bold text-center mb-4">Gullar Katalogi</h1>
<p className="text-center text-lg text-foreground/75 mb-12">
Bizning eng chiroyli buketlarni kategoriya bo'yicha tanlang
</p>
<div className="flex flex-wrap gap-3 justify-center mb-12">
{categories.map((category) => (
<button
key={category.id}
onClick={() => setSelectedCategory(category.id)}
className={`px-6 py-2 rounded-full font-medium transition-all ${
selectedCategory === category.id
? "bg-primary-cta text-background"
: "bg-card text-foreground border border-foreground/20 hover:border-foreground/40"
}`}
>
{category.name}
</button>
))}
</div>
</div>
</div>
<div id="products" data-section="products">
<ProductCardOne
title={selectedCategory === "all" ? "Barchasi" : categories.find(c => c.id === selectedCategory)?.name}
description="Har bir buket sifat va sevgi bilan tayyorlanadi"
products={filteredProducts}
gridVariant="four-items-2x2-equal-grid"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers"
columns={[
{
title: "Mahsulotlar", items: [
{ label: "Gullar katalogi", href: "/catalog" },
{ label: "Eng mashhur buketlar", href: "/" },
],
},
{
title: "Kompaniya", items: [
{ label: "Biз haqimizda", href: "/#about" },
{ label: "Aloqa", href: "/#contact" },
],
},
{
title: "Aloqa", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers. Barcha huquqlar himoyalangan."
/>
</div>
</ThemeProvider>
);
}

251
src/app/checkout/page.tsx Normal file
View File

@@ -0,0 +1,251 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
import { useState } from "react";
import Input from "@/components/form/Input";
interface OrderFormData {
fullName: string;
email: string;
phone: string;
address: string;
city: string;
postalCode: string;
message: string;
}
export default function CheckoutPage() {
const [formData, setFormData] = useState<OrderFormData>({
fullName: "", email: "", phone: "", address: "", city: "", postalCode: "", message: ""});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitStatus, setSubmitStatus] = useState<"idle" | "success" | "error">("idle");
const handleInputChange = (field: keyof OrderFormData, value: string) => {
setFormData((prev) => ({
...prev,
[field]: value,
}));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
setSubmitStatus("idle");
try {
// Save order to database via API
const response = await fetch("/api/orders", {
method: "POST", headers: {
"Content-Type": "application/json"},
body: JSON.stringify(formData),
});
if (!response.ok) {
throw new Error("Failed to submit order");
}
setSubmitStatus("success");
setFormData({
fullName: "", email: "", phone: "", address: "", city: "", postalCode: "", message: ""});
setTimeout(() => {
setSubmitStatus("idle");
}, 3000);
} catch (error) {
console.error("Error submitting order:", error);
setSubmitStatus("error");
setTimeout(() => {
setSubmitStatus("idle");
}, 3000);
} finally {
setIsSubmitting(false);
}
};
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Бош сахифа", id: "/" },
{ name: "Каталог", id: "products" },
{ name: "Категорияlar", id: "features" },
{ name: "Биз хақимизда", id: "about" },
{ name: "Aloqa", id: "contact" },
]}
/>
</div>
<div className="min-h-screen py-20 px-4">
<div className="max-w-2xl mx-auto">
<div className="mb-12">
<h1 className="text-4xl md:text-5xl font-extrabold mb-4">
Buyurtmani Rasmiylash
</h1>
<p className="text-lg text-gray-600 dark:text-gray-400">
Quyidagi shaklni to'ldiring va buyurtmangizni tasdiqlang. Biz tez orada siz bilan bog'lanamiz.
</p>
</div>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Customer Information */}
<div className="space-y-6">
<h2 className="text-2xl font-semibold mb-4">Shaxsiy Ma'lumot</h2>
<Input
value={formData.fullName}
onChange={(value) => handleInputChange("fullName", value)}
type="text"
placeholder="To'liq Ismingiz"
required
/>
<Input
value={formData.email}
onChange={(value) => handleInputChange("email", value)}
type="email"
placeholder="Email Manzili"
required
/>
<Input
value={formData.phone}
onChange={(value) => handleInputChange("phone", value)}
type="tel"
placeholder="Telefon Raqami (+998...)"
required
/>
</div>
{/* Delivery Information */}
<div className="space-y-6">
<h2 className="text-2xl font-semibold mb-4">Yetkazib Berish Manzili</h2>
<Input
value={formData.address}
onChange={(value) => handleInputChange("address", value)}
type="text"
placeholder="Manzil (Ko'cha, uy raqami)"
required
/>
<div className="grid grid-cols-2 gap-4">
<Input
value={formData.city}
onChange={(value) => handleInputChange("city", value)}
type="text"
placeholder="Shahar"
required
/>
<Input
value={formData.postalCode}
onChange={(value) => handleInputChange("postalCode", value)}
type="text"
placeholder="Pochtali Kod"
/>
</div>
</div>
{/* Additional Message */}
<div className="space-y-4">
<h2 className="text-2xl font-semibold mb-4">Qo'shimcha Xabar</h2>
<textarea
value={formData.message}
onChange={(e) => handleInputChange("message", e.target.value)}
placeholder="Ustozga qo'shimcha so'zlar yoki taklif (ixtiyoriy)"
rows={4}
className="w-full px-4 py-3 rounded-lg bg-opacity-50 backdrop-blur-sm border border-opacity-20 focus:outline-none focus:ring-2 transition-all duration-300 placeholder-opacity-75"
/>
</div>
{/* Status Messages */}
{submitStatus === "success" && (
<div className="p-4 bg-green-100 dark:bg-green-900 border border-green-300 dark:border-green-700 rounded-lg text-green-800 dark:text-green-100">
Buyurtma muvaffaqiyatli qabul qilindi! Biz tez orada siz bilan bog'lanamiz.
</div>
)}
{submitStatus === "error" && (
<div className="p-4 bg-red-100 dark:bg-red-900 border border-red-300 dark:border-red-700 rounded-lg text-red-800 dark:text-red-100">
✗ Xatolik yuz berdi. Iltimos, qayta urinib ko'ring.
</div>
)}
{/* Submit Button */}
<button
type="submit"
disabled={isSubmitting}
className="w-full py-3 px-6 rounded-lg font-semibold text-white bg-gradient-to-r from-pink-500 to-rose-500 hover:from-pink-600 hover:to-rose-600 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed"
>
{isSubmitting ? "Yuborilmoqda..." : "Buyurtmani Tasdiqlash"}
</button>
</form>
<div className="mt-8 p-6 rounded-lg bg-opacity-50 backdrop-blur-sm border border-opacity-20">
<p className="text-sm text-gray-600 dark:text-gray-400">
💬 Savollaringiz bo'lsa, biz bilan bog'laning:
<br />
📞 <a href="https://t.me/fatinur_flowers" className="text-pink-500 hover:text-pink-600 ml-2">Telegram</a>
<a href="https://wa.me/998901234567" className="text-pink-500 hover:text-pink-600 ml-2">WhatsApp</a>
<a href="https://instagram.com/fatinur_flowers" className="text-pink-500 hover:text-pink-600 ml-2">Instagram</a>
</p>
</div>
</div>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers"
columns={[
{
title: "Mahsulotlar", items: [
{ label: "Gullar katalogi", href: "#products" },
{ label: "Kategoriyalar", href: "#features" },
{ label: "Eng mashhur buketlar", href: "#products" },
],
},
{
title: "Kompaniya", items: [
{ label: "Biз haqimizda", href: "#about" },
{ label: "Yetkazib berish", href: "#contact" },
{ label: "Aloqa", href: "#contact" },
],
},
{
title: "Aloqa", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
{ label: "WhatsApp", href: "https://wa.me/998901234567" },
],
},
{
title: "Qonuniy", items: [
{ label: "Maxfiylik siyosati", href: "#" },
{ label: "Foydalanish shartlari", href: "#" },
{ label: "Kukilar siyosati", href: "#" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers. Barcha huquqlar himoyalangan."
/>
</div>
</ThemeProvider>
);
}

101
src/app/contact/page.tsx Normal file
View File

@@ -0,0 +1,101 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import ContactText from "@/components/sections/contact/ContactText";
import SocialProofOne from "@/components/sections/socialProof/SocialProofOne";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
export default function ContactPage() {
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Home", id: "/" },
{ name: "Catalog", id: "/catalog" },
{ name: "About", id: "/about" },
{ name: "Delivery", id: "/delivery" },
{ name: "Contact", id: "/contact" },
]}
/>
</div>
<div id="contact-section" data-section="contact" className="pt-20">
<ContactText
text="Get in touch with Fatinur Flowers. We're here to help you express your love and beauty through flowers."
animationType="entrance-slide"
buttons={[
{ text: "Order on Telegram", href: "https://t.me/fatinur_flowers" },
{ text: "Message on Instagram", href: "https://instagram.com/fatinur_flowers" },
{ text: "WhatsApp", href: "https://wa.me/998901234567" },
]}
background={{ variant: "plain" }}
useInvertedBackground={false}
/>
</div>
<div id="social" data-section="social">
<SocialProofOne
title="Connect With Us"
description="Follow us on social media for daily flower inspiration and special offers"
tag="📱 Social Links"
names={["Telegram", "Instagram", "WhatsApp", "Facebook"]}
textboxLayout="default"
useInvertedBackground={false}
speed={40}
showCard={true}
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers"
columns={[
{
title: "Products", items: [
{ label: "Flower Catalog", href: "/catalog" },
{ label: "Categories", href: "/catalog" },
{ label: "Popular Bouquets", href: "/catalog" },
],
},
{
title: "Company", items: [
{ label: "About Us", href: "/about" },
{ label: "Delivery Info", href: "/delivery" },
{ label: "Contact", href: "/contact" },
],
},
{
title: "Connect", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
{ label: "WhatsApp", href: "https://wa.me/998901234567" },
],
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "/privacy" },
{ label: "Terms of Service", href: "/terms" },
{ label: "Cookie Policy", href: "/cookies" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers. All rights reserved."
/>
</div>
</ThemeProvider>
);
}

96
src/app/delivery/page.tsx Normal file
View File

@@ -0,0 +1,96 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import FeatureBento from "@/components/sections/feature/FeatureBento";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
import { MapPin, Clock, ShieldCheck } from "lucide-react";
export default function DeliveryPage() {
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="mediumSmall"
sizing="mediumLarge"
background="circleGradient"
cardStyle="subtle-shadow"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Fatinur Flowers"
navItems={[
{ name: "Home", id: "/" },
{ name: "Catalog", id: "/catalog" },
{ name: "About", id: "/about" },
{ name: "Delivery", id: "/delivery" },
{ name: "Contact", id: "/contact" },
]}
/>
</div>
<div id="delivery" data-section="delivery" className="pt-20">
<FeatureBento
title="Fast & Reliable Delivery"
description="We ensure your flowers arrive fresh and beautiful, on time, every time."
tag="🚚 Delivery Information"
features={[
{
title: "2-Hour Delivery", description: "Express delivery available throughout the city", bentoComponent: "reveal-icon", icon: Clock,
},
{
title: "Tracked Delivery", description: "Real-time tracking of your flower delivery", bentoComponent: "reveal-icon", icon: MapPin,
},
{
title: "Guaranteed Quality", description: "Fresh flowers guaranteed or your money back", bentoComponent: "reveal-icon", icon: ShieldCheck,
},
]}
textboxLayout="default"
animationType="slide-up"
useInvertedBackground={false}
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Fatinur Flowers"
columns={[
{
title: "Products", items: [
{ label: "Flower Catalog", href: "/catalog" },
{ label: "Categories", href: "/catalog" },
{ label: "Popular Bouquets", href: "/catalog" },
],
},
{
title: "Company", items: [
{ label: "About Us", href: "/about" },
{ label: "Delivery Info", href: "/delivery" },
{ label: "Contact", href: "/contact" },
],
},
{
title: "Connect", items: [
{ label: "Telegram", href: "https://t.me/fatinur_flowers" },
{ label: "Instagram", href: "https://instagram.com/fatinur_flowers" },
{ label: "WhatsApp", href: "https://wa.me/998901234567" },
],
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "/privacy" },
{ label: "Terms of Service", href: "/terms" },
{ label: "Cookie Policy", href: "/cookies" },
],
},
]}
copyrightText="© 2025 Fatinur Flowers. All rights reserved."
/>
</div>
</ThemeProvider>
);
}

View File

@@ -1,57 +1,17 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Halant } from "next/font/google";
import { Inter } from "next/font/google";
import { Manrope } from "next/font/google";
import "./globals.css"; import "./globals.css";
import { ServiceWrapper } from "@/components/ServiceWrapper";
import Tag from "@/tag/Tag";
const halant = Halant({
variable: "--font-halant", subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
});
const inter = Inter({
variable: "--font-inter", subsets: ["latin"],
});
const manrope = Manrope({
variable: "--font-manrope", subsets: ["latin"],
});
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Fatinur Flowers | Premium Gul Do'koni Toshkent", description: "Fatinur Flowers eng sifatli va yangi gullar. Tez yetkazib berish, professional dizayn va sevgi bilan tayyorlangan buketlar.", keywords: "gullar, buket, sevgi, gul do'koni, Toshkent, yetkazib berish, rossali, oq roza, qizil roza, tula", metadataBase: new URL("https://fatinur-flowers.uz"), title: "Fatinur Flowers", description: "Premium flower delivery service"};
alternates: {
canonical: "https://fatinur-flowers.uz"},
openGraph: {
title: "Fatinur Flowers | Premium Gul Do'koni", description: "Har bir lahza uchun eng chiroyli gullar. Tez yetkazib berish va professional florist xizmati.", url: "https://fatinur-flowers.uz", siteName: "Fatinur Flowers", images: [
{
url: "http://img.b2bpic.net/free-photo/brunette-girl-red-buy-flowers-flower-store_627829-9126.jpg", alt: "Fatinur Flowers Premium Bouquet"},
],
type: "website"},
twitter: {
card: "summary_large_image", title: "Fatinur Flowers | Premium Gul Do'koni", description: "Har bir lahza uchun eng chiroyli gullar", images: ["http://img.b2bpic.net/free-photo/brunette-girl-red-buy-flowers-flower-store_627829-9126.jpg"],
},
robots: {
index: true,
follow: true,
},
};
export default function RootLayout({ export default function RootLayout({
children, children,
}: Readonly<{ }: {
children: React.ReactNode; children: React.ReactNode;
}>) { }) {
return ( return (
<html lang="en" suppressHydrationWarning> <html lang="en">
<ServiceWrapper> <body>{children}
<body
className={`${halant.variable} ${inter.variable} ${manrope.variable} antialiased`}
>
<Tag />
{children}
<script <script
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: ` __html: `
@@ -1419,7 +1379,6 @@ export default function RootLayout({
}} }}
/> />
</body> </body>
</ServiceWrapper>
</html> </html>
); );
} }

View File

@@ -30,11 +30,12 @@ export default function LandingPage() {
<NavbarStyleApple <NavbarStyleApple
brandName="Fatinur Flowers" brandName="Fatinur Flowers"
navItems={[ navItems={[
{ name: "Бош сахифа", id: "hero" }, { name: "Бош сахифа", id: "/" },
{ name: "Каталог", id: "products" }, { name: "Каталог", id: "products" },
{ name: "Категорияlar", id: "features" }, { name: "Категорияlar", id: "features" },
{ name: "Биз хақимизда", id: "about" }, { name: "Биз хақимизда", id: "about" },
{ name: "Aloqa", id: "contact" }, { name: "Aloqa", id: "contact" },
{ name: "Admin", id: "/admin" },
]} ]}
/> />
</div> </div>

View File

@@ -11,7 +11,7 @@ html {
body { body {
background-color: var(--background); background-color: var(--background);
color: var(--foreground); color: var(--foreground);
font-family: var(--font-manrope), sans-serif; font-family: var(--font-poppins), sans-serif;
position: relative; position: relative;
min-height: 100vh; min-height: 100vh;
overscroll-behavior: none; overscroll-behavior: none;
@@ -24,5 +24,5 @@ h3,
h4, h4,
h5, h5,
h6 { h6 {
font-family: var(--font-manrope), sans-serif; font-family: var(--font-poppins), sans-serif;
} }

View File

@@ -10,15 +10,15 @@
--accent: #ffffff; --accent: #ffffff;
--background-accent: #ffffff; */ --background-accent: #ffffff; */
--background: #f5f5f5; --background: #faf8f5;
--card: #ffffff; --card: #ffffff;
--foreground: #1c1c1c; --foreground: #2d1b1f;
--primary-cta: #1f514c; --primary-cta: #d4606b;
--primary-cta-text: #f5f5f5; --primary-cta-text: #f5f5f5;
--secondary-cta: #ffffff; --secondary-cta: #ffffff;
--secondary-cta-text: #1c1c1c; --secondary-cta-text: #1c1c1c;
--accent: #159c49; --accent: #7dd3a0;
--background-accent: #a8e8ba; --background-accent: #e8d4d9;
/* text sizing - set by ThemeProvider */ /* text sizing - set by ThemeProvider */
/* --text-2xs: clamp(0.465rem, 0.62vw, 0.62rem); /* --text-2xs: clamp(0.465rem, 0.62vw, 0.62rem);