import { useState, useEffect, useRef, useCallback } from ‘react’;
import { cn } from ‘./utils/cn’;
import type { ArtPiece, Size, FrameColor, SetType, CustomerInfo, Review } from ‘./types’;
// Data Constants
const SIZES: Size[] = [
{ id: ’40×50′, label: ‘٤٠×٥٠ سم’, dimensions: ’40x50cm’, price: 800 },
{ id: ’50×70′, label: ‘٥٠×٧٠ سم’, dimensions: ’50x70cm’, price: 1000 },
{ id: ’60×90′, label: ‘٦٠×٩٠ سم’, dimensions: ’60x90cm’, price: 1200 },
];
const FRAME_COLORS: FrameColor[] = [
{ id: ‘black’, label: ‘أسود’, color: ‘#1a1a1a’, borderClass: ‘border-gray-900’ },
{ id: ‘white’, label: ‘أبيض’, color: ‘#ffffff’, borderClass: ‘border-gray-300’ },
{ id: ‘wood’, label: ‘خشبي’, color: ‘#8B4513’, borderClass: ‘border-amber-700’ },
];
const SET_TYPES: SetType[] = [
{ id: ‘single’, label: ‘قطعة واحدة’, quantity: 1, discount: 0 },
{ id: ‘set2’, label: ‘طقم ٢ قطع (خصم ١٠٪)’, quantity: 2, discount: 0.10 },
{ id: ‘set3’, label: ‘طقم ٣ قطع (خصم ١٥٪)’, quantity: 3, discount: 0.15 },
];
const GOVERNORATES = [
‘القاهرة’, ‘الجيزة’, ‘الإسكندرية’, ‘الدقهلية’, ‘الشرقية’, ‘المنوفية’, ‘القليوبية’,
‘البحيرة’, ‘الغربية’, ‘كفر الشيخ’, ‘دمياط’, ‘بورسعيد’, ‘الإسماعيلية’, ‘السويس’,
‘شمال سيناء’, ‘جنوب سيناء’, ‘البحر الأحمر’, ‘الوادي الجديد’, ‘مطروح’, ‘الفيوم’,
‘بني سويف’, ‘المنيا’, ‘أسيوط’, ‘سوهاج’, ‘قنا’, ‘الأقصر’, ‘أسوان’
];
const REVIEWS: Review[] = [
{ id: 1, name: ‘أحمد محمود’, location: ‘القاهرة’, rating: 5, comment: ‘التابلوه روعة والخامة ممتازة جداً! التوصيل كان سريع والتغليف محترم’ },
{ id: 2, name: ‘سارة علي’, location: ‘الإسكندرية’, rating: 5, comment: ‘اللوحات زينت الصالون بشكل مختلف تماماً، شكراً ليكم’ },
{ id: 3, name: ‘محمد حسن’, location: ‘الجيزة’, rating: 5, comment: ‘جودة الطباعة عالية جداً والألوان زي ما في الصورة بالظبط’ },
{ id: 4, name: ‘نورهان أشرف’, location: ‘المنصورة’, rating: 5, comment: ‘دي تاني مرة أطلب منهم ومش هيبقوا الأخيرة! خدمة ممتازة’ },
{ id: 5, name: ‘عمرو سعيد’, location: ‘طنطا’, rating: 5, comment: ‘الإطار شيك جداً والتابلوه أحسن من اللي توقعته’ },
{ id: 6, name: ‘ياسمين كمال’, location: ‘الزقازيق’, rating: 5, comment: ‘هدية جميلة لصاحبتي، اتبسطت جداً بيها’ },
];
const ART_CATEGORIES = [‘طبيعة’, ‘تجريدي’, ‘إسلامي’, ‘مودرن’, ‘كلاسيكي’, ‘ورود’, ‘مناظر طبيعية’, ‘خط عربي’];
// Generate 150 art pieces with varied aspect ratios
const generateArtPieces = (): ArtPiece[] => {
const aspectRatios: (‘portrait’ | ‘landscape’ | ‘square’)[] = [‘portrait’, ‘landscape’, ‘square’];
return Array.from({ length: 150 }, (_, i) => {
const aspectRatio = aspectRatios[i % 3];
const category = ART_CATEGORIES[i % ART_CATEGORIES.length];
const width = aspectRatio === ‘portrait’ ? 400 : aspectRatio === ‘landscape’ ? 600 : 500;
const height = aspectRatio === ‘portrait’ ? 600 : aspectRatio === ‘landscape’ ? 400 : 500;
return {
id: i + 1,
title: `لوحة فنية ${i + 1}`,
category,
imageUrl: `https://picsum.photos/seed/${i + 100}/${width}/${height}`,
aspectRatio,
};
});
};
const ART_PIECES = generateArtPieces();
// Google Sheets Web App URL (replace with actual URL)
const GOOGLE_SHEETS_URL = ‘https://script.google.com/macros/s/YOUR_SCRIPT_ID/exec’;
export function App() {
const [selectedArt, setSelectedArt] = useState
(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedSize, setSelectedSize] = useState(SIZES[0]);
const [selectedFrameColor, setSelectedFrameColor] = useState(FRAME_COLORS[0]);
const [selectedSetType, setSelectedSetType] = useState(SET_TYPES[0]);
const [paymentTab, setPaymentTab] = useState<'cod' | 'paymob'>(‘cod’);
const [isSubmitting, setIsSubmitting] = useState(false);
const [orderSuccess, setOrderSuccess] = useState(false);
const [visibleItems, setVisibleItems] = useState>(new Set());
const [customerInfo, setCustomerInfo] = useState({
name: ”,
phone: ”,
address: ”,
governorate: ”,
paymentMethod: ‘cod’,
});
// Calculate pricing
const originalPrice = selectedSize.price * selectedSetType.quantity;
const discountAmount = originalPrice * selectedSetType.discount;
const totalPrice = originalPrice – discountAmount;
// Intersection Observer for lazy loading
const observerRef = useRef(null);
useEffect(() => {
observerRef.current = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const id = Number(entry.target.getAttribute(‘data-id’));
setVisibleItems((prev) => new Set([…prev, id]));
}
});
},
{ rootMargin: ‘100px’, threshold: 0.1 }
);
return () => observerRef.current?.disconnect();
}, []);
const setItemRef = useCallback((node: HTMLDivElement | null, id: number) => {
if (node && observerRef.current) {
node.setAttribute(‘data-id’, String(id));
observerRef.current.observe(node);
}
}, []);
const openModal = (art: ArtPiece) => {
setSelectedArt(art);
setIsModalOpen(true);
setSelectedSize(SIZES[0]);
setSelectedFrameColor(FRAME_COLORS[0]);
setSelectedSetType(SET_TYPES[0]);
setOrderSuccess(false);
};
const closeModal = () => {
setIsModalOpen(false);
setSelectedArt(null);
};
const handleSubmitOrder = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
const orderData = {
artId: selectedArt?.id,
artTitle: selectedArt?.title,
size: selectedSize.dimensions,
frameColor: selectedFrameColor.label,
setType: selectedSetType.label,
quantity: selectedSetType.quantity,
originalPrice,
discount: discountAmount,
totalPrice,
customerName: customerInfo.name,
customerPhone: customerInfo.phone,
customerAddress: customerInfo.address,
governorate: customerInfo.governorate,
paymentMethod: paymentTab === ‘cod’ ? ‘الدفع عند الاستلام’ : ‘بطاقة ائتمان’,
orderDate: new Date().toISOString(),
};
try {
// Send to Google Sheets
await fetch(GOOGLE_SHEETS_URL, {
method: ‘POST’,
mode: ‘no-cors’,
headers: {
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify(orderData),
});
setOrderSuccess(true);
setCustomerInfo({
name: ”,
phone: ”,
address: ”,
governorate: ”,
paymentMethod: ‘cod’,
});
} catch (error) {
console.error(‘Error submitting order:’, error);
} finally {
setIsSubmitting(false);
}
};
// Get frame-adjusted image URL (simulating different frame colors)
const getFrameImageUrl = (baseUrl: string, frameColor: FrameColor) => {
// In production, this would return different image URLs based on frame color
// For simulation, we’ll add a query parameter
return `${baseUrl}?frame=${frameColor.id}`;
};
return (
{/* Header */}
تابلوهات فنية
لوحات جدارية مميزة
{/* Hero Section */}
شحن مجاني لجميع المحافظات
حوّل جدران بيتك
لمعرض فني
أكتر من ١٥٠ تصميم فني مميز بأعلى جودة طباعة وإطارات فاخرة
اكتشف المجموعة
{/* Trust Badges */}
ضمان الجودة
١٠٠٪ رضا العميل
استرجاع مجاني
خلال ١٤ يوم
{/* Gallery Section */}
معرض اللوحات
اختار من مجموعتنا المتنوعة من اللوحات الفنية عالية الجودة
{/* Masonry Grid */}
{ART_PIECES.map((art) => (
setItemRef(node, art.id)}
className=”masonry-item”
>
openModal(art)}
className=”group relative bg-white rounded-xl overflow-hidden shadow-sm hover:shadow-xl transition-all duration-300 cursor-pointer”
>
{visibleItems.has(art.id) ? (

) : (
)}
{art.category}
))}
{/* Reviews Section */}
آراء عملائنا
أكتر من ١٠٠٠ عميل سعيد بتجربتهم معانا
{/* Marquee Reviews */}
{[…REVIEWS, …REVIEWS].map((review, idx) => (
{[…Array(5)].map((_, i) => (
))}
"{review.comment}"
{review.name.charAt(0)}
{review.name}
{review.location}
))}
{/* CTA Section */}
جاهز تجمّل بيتك؟
اختار لوحاتك المفضلة واستمتع بتوصيل سريع لباب بيتك
تسوق الآن
{/* Footer */}
{/* Product Modal */}
{isModalOpen && selectedArt && (
{
if (e.target === e.currentTarget) closeModal();
}}
>
{/* Close Button */}
{orderSuccess ? (
/* Success State */
تم استلام طلبك بنجاح!
هنتواصل معاك قريباً لتأكيد الطلب
) : (
{/* Image Section */}
{/* Details Section */}
{selectedArt.title}
لوحة فنية عالية الجودة مع إطار فاخر
{/* Size Selection */}
{SIZES.map((size) => (
))}
{/* Frame Color Selection */}
{FRAME_COLORS.map((frame) => (
))}
{/* Set Type Selection */}
{SET_TYPES.map((setType) => (
))}
{/* Price Display */}
السعر الإجمالي:
{selectedSetType.discount > 0 && (
{originalPrice} ج.م
)}
{totalPrice} ج.م
{selectedSetType.discount > 0 && (
وفّرت {discountAmount} ج.م! 🎉
)}
{/* Checkout Tabs */}
{/* Checkout Form */}
)}
)}
);
}