*/ const { useState, useEffect } = React; const { X, Menu, LayoutGrid, List, Plus, Edit2, Trash2, Users, BarChart3, Home, LogOut, Eye, EyeOff, ChevronDown } = lucide; // Lucide Icons Component Loader const LucideIcon = ({ name, ...props }) => { const icons = { X, Menu, LayoutGrid, List, Plus, Edit2, Trash2, Users, BarChart3, Home, LogOut, Eye, EyeOff, ChevronDown }; const Icon = icons[name]; return Icon ? React.createElement(Icon, props) : null; }; // AdSense Placeholder Component const AdSenseUnit = ({ format = 'horizontal' }) => { const styles = { horizontal: 'w-full h-24 bg-gradient-to-r from-slate-100 to-slate-50', vertical: 'w-full h-96 bg-gradient-to-b from-slate-100 to-slate-50', square: 'w-full aspect-square bg-gradient-to-br from-slate-100 to-slate-50' }; // To use AdSense: Replace this entire return statement with your AdSense ad unit code return (
Advertisement
); }; // Initial Data const INITIAL_PROPERTIES = [ { id: '1', address: '123 Ocean Drive, Miami Beach', price: 1250000, type: 'Condo', bedrooms: 3, bathrooms: 2, stage: 'Active', agent: 'John Doe', clientId: '1', notes: 'Ocean view, recently renovated' }, { id: '2', address: '456 Sunset Boulevard, Coral Gables', price: 890000, type: 'Single Family', bedrooms: 4, bathrooms: 3, stage: 'Pending', agent: 'Jane Smith', clientId: '2', notes: 'Pool, large backyard' } ]; const INITIAL_CLIENTS = [ { id: '1', name: 'Robert Johnson', email: 'robert@email.com', phone: '305-555-0100', type: 'Buyer' }, { id: '2', name: 'Maria Garcia', email: 'maria@email.com', phone: '305-555-0101', type: 'Seller' } ]; const STAGES = ['Active', 'Pending', 'Title', 'Sold']; const STAGE_COLORS = { Active: 'bg-blue-500', Pending: 'bg-amber-500', Title: 'bg-purple-500', Sold: 'bg-emerald-500' }; // Main App Component function RealEstateCRM() { const [currentUser, setCurrentUser] = useState(null); const [showAuthModal, setShowAuthModal] = useState(false); const [showTermsModal, setShowTermsModal] = useState(false); const [termsAccepted, setTermsAccepted] = useState(false); const [currentPage, setCurrentPage] = useState('dashboard'); const [viewMode, setViewMode] = useState('kanban'); const [properties, setProperties] = useState([]); const [clients, setClients] = useState([]); const [draggedItem, setDraggedItem] = useState(null); const [showPropertyModal, setShowPropertyModal] = useState(false); const [editingProperty, setEditingProperty] = useState(null); const [showClientModal, setShowClientModal] = useState(false); const [editingClient, setEditingClient] = useState(null); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); // Load data from localStorage useEffect(() => { const savedUser = localStorage.getItem('crm_user'); const savedTerms = localStorage.getItem('crm_terms_accepted'); const savedProperties = localStorage.getItem('crm_properties'); const savedClients = localStorage.getItem('crm_clients'); if (savedUser) setCurrentUser(JSON.parse(savedUser)); if (savedTerms) setTermsAccepted(JSON.parse(savedTerms)); if (savedProperties) { setProperties(JSON.parse(savedProperties)); } else { setProperties(INITIAL_PROPERTIES); } if (savedClients) { setClients(JSON.parse(savedClients)); } else { setClients(INITIAL_CLIENTS); } }, []); // Save data to localStorage useEffect(() => { if (properties.length > 0) { localStorage.setItem('crm_properties', JSON.stringify(properties)); } }, [properties]); useEffect(() => { if (clients.length > 0) { localStorage.setItem('crm_clients', JSON.stringify(clients)); } }, [clients]); // Auth Functions const handleLogin = (email, password) => { const user = { email, name: email.split('@')[0] }; setCurrentUser(user); localStorage.setItem('crm_user', JSON.stringify(user)); setShowAuthModal(false); if (!termsAccepted) { setShowTermsModal(true); } }; const handleLogout = () => { setCurrentUser(null); localStorage.removeItem('crm_user'); setTermsAccepted(false); localStorage.removeItem('crm_terms_accepted'); }; const acceptTerms = () => { setTermsAccepted(true); localStorage.setItem('crm_terms_accepted', 'true'); setShowTermsModal(false); }; // Property Functions const addProperty = (property) => { const newProperty = { ...property, id: Date.now().toString() }; setProperties([...properties, newProperty]); setShowPropertyModal(false); setEditingProperty(null); }; const updateProperty = (property) => { setProperties(properties.map(p => p.id === property.id ? property : p)); setShowPropertyModal(false); setEditingProperty(null); }; const deleteProperty = (id) => { setProperties(properties.filter(p => p.id !== id)); }; const moveProperty = (propertyId, newStage) => { setProperties(properties.map(p => p.id === propertyId ? { ...p, stage: newStage } : p )); }; // Client Functions const addClient = (client) => { const newClient = { ...client, id: Date.now().toString() }; setClients([...clients, newClient]); setShowClientModal(false); setEditingClient(null); }; const updateClient = (client) => { setClients(clients.map(c => c.id === client.id ? client : c)); setShowClientModal(false); setEditingClient(null); }; const deleteClient = (id) => { setClients(clients.filter(c => c.id !== id)); }; // Drag and Drop Handlers const handleDragStart = (e, property) => { setDraggedItem(property); e.dataTransfer.effectAllowed = 'move'; }; const handleDragOver = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }; const handleDrop = (e, stage) => { e.preventDefault(); if (draggedItem && draggedItem.stage !== stage) { moveProperty(draggedItem.id, stage); } setDraggedItem(null); }; // Show auth modal if not logged in if (!currentUser) { return ; } // Show terms modal if not accepted if (!termsAccepted) { return ; } // Main App UI return (
{/* Header */}

Claropixel CRM

{currentUser.name}

{currentUser.email}

{/* Mobile Menu */} {mobileMenuOpen && (
)}
{/* Main Content */}
{currentPage === 'dashboard' && } {currentPage === 'properties' && ( { setEditingProperty(null); setShowPropertyModal(true); }} onEditProperty={(prop) => { setEditingProperty(prop); setShowPropertyModal(true); }} onDeleteProperty={deleteProperty} onDragStart={handleDragStart} onDragOver={handleDragOver} onDrop={handleDrop} draggedItem={draggedItem} /> )} {currentPage === 'clients' && ( { setEditingClient(null); setShowClientModal(true); }} onEditClient={(client) => { setEditingClient(client); setShowClientModal(true); }} onDeleteClient={deleteClient} /> )}
{/* Footer */}
{/* Modals */} {showPropertyModal && ( { setShowPropertyModal(false); setEditingProperty(null); }} /> )} {showClientModal && ( { setShowClientModal(false); setEditingClient(null); }} /> )}
); } // Navigation Button Component const NavButton = ({ active, onClick, children }) => ( ); const MobileNavButton = ({ active, onClick, children }) => ( ); // Dashboard Component const Dashboard = ({ properties, clients }) => { const stats = { active: properties.filter(p => p.stage === 'Active').length, pending: properties.filter(p => p.stage === 'Pending').length, title: properties.filter(p => p.stage === 'Title').length, sold: properties.filter(p => p.stage === 'Sold').length, totalValue: properties.reduce((sum, p) => sum + p.price, 0), totalClients: clients.length }; return (

Pipeline Overview

Portfolio Value

${(stats.totalValue / 1000000).toFixed(2)}M

{properties.length} total properties

Client Base

{stats.totalClients}

Active clients

); }; const StatCard = ({ title, value, color }) => { const colors = { blue: 'from-blue-500 to-blue-600', amber: 'from-amber-500 to-amber-600', purple: 'from-purple-500 to-purple-600', emerald: 'from-emerald-500 to-emerald-600' }; return (

{title}

{value}

); }; // Properties Page Component const PropertiesPage = ({ properties, clients, viewMode, setViewMode, onAddProperty, onEditProperty, onDeleteProperty, onDragStart, onDragOver, onDrop, draggedItem }) => { return (

Properties

{viewMode === 'kanban' ? ( ) : ( )}
); }; // Kanban View Component const KanbanView = ({ properties, clients, onEdit, onDelete, onDragStart, onDragOver, onDrop, draggedItem }) => { return (
{STAGES.map(stage => (
onDrop(e, stage)} >

{stage}

{properties.filter(p => p.stage === stage).length}
{properties .filter(p => p.stage === stage) .map(property => ( ))}
))}
); }; // Property Card Component const PropertyCard = ({ property, clients, onEdit, onDelete, onDragStart, isDragging }) => { const client = clients.find(c => c.id === property.clientId); return (
onDragStart(e, property)} className={`bg-white rounded-lg p-4 shadow-sm border border-slate-200 cursor-move hover:shadow-md transition-all ${ isDragging ? 'opacity-50 scale-95' : '' }`} >
{property.type}

{property.address}

${property.price.toLocaleString()}

Bed/Bath: {property.bedrooms}bd / {property.bathrooms}ba
Agent: {property.agent}
{client && (
Client: {client.name}
)}
{property.notes && (

{property.notes}

)}
); }; // List View Component const ListView = ({ properties, clients, onEdit, onDelete }) => { return (
{properties.map((property, index) => { const client = clients.find(c => c.id === property.clientId); return ( {index % 3 === 2 && ( )} ); })}
Address Price Type Stage Agent Client Actions
{property.address} ${property.price.toLocaleString()} {property.type} {property.stage} {property.agent} {client?.name || '-'}
); }; // Clients Page Component const ClientsPage = ({ clients, onAddClient, onEditClient, onDeleteClient }) => { return (

Clientes

{clients.map(client => (
{client.name.charAt(0)}

{client.name}

{client.type}

Email: {client.email}

Phone: {client.phone}

))}
); }; // Property Modal Component const PropertyModal = ({ property, clients, onSave, onClose }) => { const [formData, setFormData] = useState( property || { address: '', price: '', type: 'Single Family', bedrooms: '', bathrooms: '', stage: 'Active', agent: '', clientId: '', notes: '' } ); const handleSubmit = (e) => { e.preventDefault(); onSave({ ...formData, price: parseFloat(formData.price) || 0, bedrooms: parseInt(formData.bedrooms) || 0, bathrooms: parseInt(formData.bathrooms) || 0 }); }; const handleNumberChange = (field, value) => { setFormData({ ...formData, [field]: value }); }; return (

{property ? 'Edit Property' : 'Add New Property'}

setFormData({ ...formData, address: e.target.value })} className="w-full px-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" placeholder="123 Main St, City, State" />
handleNumberChange('price', e.target.value)} className="w-full px-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" placeholder="500000" min="0" step="1000" />
handleNumberChange('bedrooms', e.target.value)} className="w-full px-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" placeholder="3" min="0" max="20" />
handleNumberChange('bathrooms', e.target.value)} className="w-full px-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" placeholder="2" min="0" max="20" step="0.5" />
setFormData({ ...formData, agent: e.target.value })} className="w-full px-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" placeholder="Agent Name" />