import React, { useState, useEffect } from "react"; import { createRoot } from "react-dom/client"; import { Printer, Trash2, Settings, User, Building2, FileText, Calculator, Upload, Server, Wifi, Cpu, Activity, Zap, CheckCircle2, Plus, RefreshCw, Linkedin, Phone, Mail, Globe, Menu, X, Share2, Edit, Eye } from "lucide-react"; // --- بيانات الشركة الموردة (ثابتة) --- const FIXED_COMPANY_INFO = { name: "دواجن تك - Dawajen Tech", address: "القاهرة، مصر - المنطقة التكنولوجية", email: "sales@ai-dawajen.tech", phone: "+201119935714", manager: "الاستشاري المهندس عبد الله عزوز", linkedin: "https://www.linkedin.com/in/abdallh-azouz-32bb55117/", website: "ai-dawajen.tech" }; // --- قاعدة البيانات --- const INFRASTRUCTURE_ITEMS = { noInternetBundle: [ { description: "تجهيزات شبكة لاسلكية (5-10 عنابر) - نطاق 500-1000م", price: 10000, unit: "مقطوعية", type: "أجهزة (مرة واحدة)" }, { description: "اشتراك إنترنت سنوي (باقة أعمال)", price: 3000, unit: "سنة", type: "اشتراك (يجدد)" }, { description: "خدمة تركيب وبرمجة الشبكة", price: 2000, unit: "خدمة", type: "خدمة (مرة واحدة)" } ] }; const SENSOR_TYPES = [ { id: 's-temp', name: "حساس حرارة فقط", hardwarePrice: 3000, subPrice: 300, subName: "اشتراك لوحة قراءات (حساس حرارة)" }, { id: 's-temp-hum', name: "حساس حرارة ورطوبة", hardwarePrice: 3500, subPrice: 300, subName: "اشتراك لوحة قراءات (حساس حرارة ورطوبة)" }, { id: 's-full', name: "حساس (حرارة + رطوبة + أمونيا)", hardwarePrice: 6000, subPrice: 300, subName: "اشتراك لوحة قراءات (شامل أمونيا)" }, ]; const SOFTWARE_PACKAGES = [ { id: 'sw-basic', name: "داشبورد قراءات وتحليل بياني (عنبر واحد)", price: 1000, unit: "سنة", desc: "تخزين بيانات لحساس أو أكثر - اشتراك سنوي", type: "اشتراك (يجدد)" }, { id: 'sw-ai-pred', name: "لوحة شاملة + ذكاء اصطناعي وتحليل توقعي (عنبر واحد)", price: 2000, unit: "سنة", desc: "لحساس أو أكثر - اشتراك سنوي", type: "اشتراك (يجدد)" }, { id: 'sw-farm-full', name: "لوحة مزرعة كاملة (5-10 عنابر)", price: 6000, unit: "سنة", desc: "تدعم 10 إلى 20 حساس - اشتراك سنوي", type: "اشتراك (يجدد)" }, { id: 'sw-ai-expert', name: "داشبورد الخبير (AI Expert) وتحليل السلوك والأمراض", price: 10000, unit: "سنة", desc: "لمزرعة 5-10 عنابر (بيئة شاملة) - اشتراك سنوي", type: "اشتراك (يجدد)" }, ]; interface LineItem { id: string; description: string; quantity: number; price: number; unit: string; type: string; } interface InvoiceState { invoiceNumber: string; date: string; dueDate: string; clientName: string; clientAddress: string; currency: string; taxRate: number; logo: string | null; notes: string; items: LineItem[]; } const initialState: InvoiceState = { invoiceNumber: "INV-0001", date: new Date().toISOString().split('T')[0], dueDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], clientName: "مزرعة الهدى للدواجن", clientAddress: "طريق الإسماعيلية الصحراوي", currency: "ج.م", taxRate: 14, logo: null, notes: "ملاحظات هامة:\n- الأسعار المذكورة أعلاه تشمل تكاليف السنة الأولى (الأجهزة + الاشتراكات).\n- يتم تجديد الاشتراكات (البنود الموضحة كـ 'اشتراك') بشكل سنوي.\n- ضمان عام كامل على الهاردوير ضد عيوب الصناعة.", items: [] }; // --- Components --- const EditorSidebar = ({ data, setData, activeTab, setActiveTab, hasInternet, setHasInternet, selectedSensor, setSelectedSensor, sensorQty, setSensorQty, softwareQty, setSoftwareQty, addInfrastructure, addSensorPackage, addSoftware, addManualItem, removeItem, updateItem, isVisible // New prop for mobile visibility }: any) => { const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setData((prev: any) => ({ ...prev, [name]: value })); }; const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onloadend = () => setData((prev: any) => ({ ...prev, logo: reader.result as string })); reader.readAsDataURL(file); } }; return (

مُنشئ العرض الفني

{/* --- TAB 1: SYSTEM WIZARD --- */} {activeTab === 'wizard' && (
{/* Step 1: Infrastructure */}

1. تأسيس البنية التحتية

هل يوجد نظام إنترنت في المزرعة؟

{hasInternet === false && (
باقة التأسيس الكاملة (واى فاي 10 عنابر):
  • أجهزة واى فاى (500-1000 متر) - 10,000 ج.م مرة واحدة
  • اشتراك إنترنت سنوي - 3,000 ج.م سنوي
  • خدمة تركيب - 2,000 ج.م
)}
{/* Step 2: Sensors */}

2. الحساسات والأجهزة

setSensorQty(parseInt(e.target.value) || 1)} />
{/* Step 3: Software */}

3. باقات البرمجيات

{/* Software Quantity Input */}
setSoftwareQty(Math.max(1, parseInt(e.target.value) || 1))} className="w-20 p-2 text-lg text-center border-2 border-blue-200 rounded-lg font-bold text-primary outline-none focus:border-primary" />

* هذا العدد يطبق فقط على الباقة الأولى والثانية.

{SOFTWARE_PACKAGES.map(pkg => { const isFarmPackage = pkg.id === 'sw-farm-full' || pkg.id === 'sw-ai-expert'; return ( )})}
)} {/* --- TAB 2: EDIT ITEMS --- */} {activeTab === 'items' && (
{data.items.length === 0 ? (

لم يتم إضافة أي بنود.

) : ( data.items.map((item: any, index: number) => (
updateItem(item.id, 'description', e.target.value)} className="w-full text-base font-bold text-secondary mb-3 border-b border-transparent focus:border-gray-300 outline-none pb-1 bg-transparent" />
{(item.price * item.quantity).toLocaleString()}
updateItem(item.id, 'quantity', parseFloat(e.target.value) || 0)} className="w-full text-sm p-2 border rounded text-center font-bold text-secondary focus:border-primary outline-none" />
updateItem(item.id, 'price', parseFloat(e.target.value) || 0)} className="w-full text-sm p-2 border rounded text-center text-gray-600 focus:border-primary outline-none" />
)) )}
)} {/* --- TAB 3: DETAILS --- */} {activeTab === 'details' && (
{data.logo &&
}

بيانات العميل

بيانات الشركة الموردة (ثابتة)

{FIXED_COMPANY_INFO.name}

{FIXED_COMPANY_INFO.address}

{FIXED_COMPANY_INFO.email}


مدير الشركة:

{FIXED_COMPANY_INFO.manager}

)} {/* --- TAB 4: SETTINGS --- */} {activeTab === 'settings' && (
setData((prev:any) => ({...prev, taxRate: parseFloat(e.target.value) || 0}))} className="w-full p-3 text-sm border rounded-lg focus:border-primary outline-none" />
)}
); }; const InvoicePreview = ({ data, removeItem, isVisible }: { data: InvoiceState, removeItem: (id: string) => void, isVisible: boolean }) => { // Calculations const calculateSubtotal = () => data.items.reduce((acc, item) => acc + (item.quantity * item.price), 0); const calculateTax = () => calculateSubtotal() * (data.taxRate / 100); const calculateTotal = () => calculateSubtotal() + calculateTax(); const calculateRenewalCost = () => { return data.items .filter(item => item.type && item.type.includes("اشتراك")) .reduce((acc, item) => acc + (item.quantity * item.price), 0); }; // Share handler const handleShare = async () => { try { const json = JSON.stringify(data); const encoded = btoa(unescape(encodeURIComponent(json))); const url = `${window.location.origin}${window.location.pathname}?q=${encoded}`; await navigator.clipboard.writeText(url); alert("تم نسخ رابط العرض إلى الحافظة بنجاح!\nيمكنك إرساله للعميل مباشرة."); } catch (err) { console.error('Failed to copy: ', err); alert("حدث خطأ أثناء نسخ الرابط."); } }; return (
{/* Action Bar */}
{/* Invoice Container Wrapper */}
{/* Header */}
{data.logo ? ( ) : (
)}

{FIXED_COMPANY_INFO.name}

{FIXED_COMPANY_INFO.address}

مدير الشركة: {FIXED_COMPANY_INFO.manager}

عرض سعر

رقم العرض: {data.invoiceNumber}
التاريخ: {data.date}
صالح حتى: {data.dueDate}
{/* Client Info */}

عرض سعر موجه إلى السادة

{data.clientName}

{data.clientAddress}

{/* Items Table - Scrollable on mobile */}
{data.items.map((item, idx) => ( ))} {data.items.length === 0 && ( )}
البيان / الوصف النوع الكمية الوحدة السعر الإجمالي
{item.description} {item.type} {item.quantity} {item.unit} {item.price.toLocaleString()} {(item.price * item.quantity).toLocaleString()}
لا توجد بنود.. استخدم "بناء النظام" لإضافة البنود.
{/* Footer & Totals */}

ملاحظات وشروط التعاقد

{data.notes}
{/* Renewal Cost Summary */} {calculateRenewalCost() > 0 && (
تكلفة التجديد السنوي المتوقعة (للاشتراكات): {calculateRenewalCost().toLocaleString()} {data.currency}
)}
المجموع الفرعي (السنة الأولى) {calculateSubtotal().toLocaleString()} {data.currency}
ضريبة القيمة المضافة ({data.taxRate}%) {calculateTax().toLocaleString()} {data.currency}
الإجمالي (السنة الأولى) {calculateTotal().toLocaleString()} {data.currency}

تم إصدار هذا العرض إلكترونياً بواسطة نظام دواجن تك (ai-dawajen.tech)

); }; // Main App Component const App = () => { const [data, setData] = useState(initialState); const [activeTab, setActiveTab] = useState<'wizard' | 'items' | 'details' | 'settings'>('wizard'); const [mobileView, setMobileView] = useState<'editor' | 'preview'>('editor'); // New State for Mobile View // States for the Wizard const [hasInternet, setHasInternet] = useState(null); const [selectedSensor, setSelectedSensor] = useState(SENSOR_TYPES[0].id); const [sensorQty, setSensorQty] = useState(1); const [softwareQty, setSoftwareQty] = useState(1); // Load data from URL if present useEffect(() => { const params = new URLSearchParams(window.location.search); const q = params.get('q'); if (q) { try { const json = decodeURIComponent(escape(atob(q))); const loadedData = JSON.parse(json); if (loadedData) { setData(loadedData); } } catch (e) { console.error("Failed to parse URL data", e); } } }, []); // --- Actions --- const updateItem = (id: string, field: keyof LineItem, value: any) => { setData(prev => ({ ...prev, items: prev.items.map(item => item.id === id ? { ...item, [field]: value } : item) })); }; const removeItem = (id: string) => { setData(prev => ({ ...prev, items: prev.items.filter(item => item.id !== id) })); }; const addInfrastructure = () => { const newItems = INFRASTRUCTURE_ITEMS.noInternetBundle.map(item => ({ id: Date.now().toString() + Math.random(), description: item.description, quantity: 1, price: item.price, unit: item.unit, type: item.type })); setData(prev => ({ ...prev, items: [...prev.items, ...newItems] })); }; const addSensorPackage = () => { const sensor = SENSOR_TYPES.find(s => s.id === selectedSensor); if (!sensor) return; const hwItem: LineItem = { id: Date.now().toString() + "-hw", description: `جهاز ${sensor.name}`, quantity: sensorQty, price: sensor.hardwarePrice, unit: "جهاز", type: "أجهزة (مرة واحدة)" }; const subItem: LineItem = { id: Date.now().toString() + "-sub", description: `${sensor.subName} - (يجدد سنوياً)`, quantity: sensorQty, price: sensor.subPrice, unit: "سنة", type: "اشتراك (يجدد)" }; setData(prev => ({ ...prev, items: [...prev.items, hwItem, subItem] })); }; const addSoftware = (pkg: typeof SOFTWARE_PACKAGES[0]) => { const isSingleBarnPackage = pkg.id === 'sw-basic' || pkg.id === 'sw-ai-pred'; const quantityToAdd = isSingleBarnPackage ? softwareQty : 1; const newItem: LineItem = { id: Date.now().toString() + Math.random(), description: pkg.name, quantity: quantityToAdd, price: pkg.price, unit: pkg.unit, type: pkg.type }; setData(prev => ({ ...prev, items: [...prev.items, newItem] })); }; const addManualItem = () => { setData(prev => ({ ...prev, items: [...prev.items, { id: Date.now().toString(), description: "", quantity: 1, price: 0, unit: "عدد", type: "عام" }] })); }; return (
{/* --- Mobile Bottom Navigation --- */}
); }; const root = createRoot(document.getElementById("root")!); root.render();