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 */} {/* 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 */}

تابلوهات فنية

لوحات جدارية مميزة

نقدم لك أفضل اللوحات الفنية بأعلى جودة وأسعار منافسة مع توصيل لجميع المحافظات

تواصل معنا

  • +20 100 123 4567
  • info@tableauxart.com

طرق الدفع

Visa
MasterCard
COD

© ٢٠٢٤ تابلوهات فنية. جميع الحقوق محفوظة

{/* Product Modal */} {isModalOpen && selectedArt && (
{ if (e.target === e.currentTarget) closeModal(); }} >
{/* Close Button */} {orderSuccess ? ( /* Success State */

تم استلام طلبك بنجاح!

هنتواصل معاك قريباً لتأكيد الطلب

) : (
{/* Image Section */}
{selectedArt.title}
{selectedArt.category}
{/* 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 */}
setCustomerInfo({ …customerInfo, name: e.target.value })} className=”w-full px-4 py-3 rounded-xl border border-gray-200 focus:border-amber-500 focus:ring-2 focus:ring-amber-200 outline-none transition-all” />
setCustomerInfo({ …customerInfo, phone: e.target.value })} className=”w-full px-4 py-3 rounded-xl border border-gray-200 focus:border-amber-500 focus:ring-2 focus:ring-amber-200 outline-none transition-all text-right” />