import React, { useState, useEffect } from 'react';
import { Building2, Target, MessageSquare, TrendingUp, Award, ChevronRight, Phone, CheckCircle, XCircle, Clock, BarChart3, Sparkles, Brain, Lightbulb, Trophy } from 'lucide-react';
const API_URL = "https://api.anthropic.com/v1/messages";
const RealEstateTraining = () => {
const [screen, setScreen] = useState('welcome');
const [userName, setUserName] = useState('');
const [experienceLevel, setExperienceLevel] = useState('beginner');
const [currentLevel, setCurrentLevel] = useState(1);
const [currentModule, setCurrentModule] = useState(null);
const [userResponse, setUserResponse] = useState('');
const [conversation, setConversation] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [feedback, setFeedback] = useState(null);
const [scenarioData, setScenarioData] = useState(null);
const [progress, setProgress] = useState({
level1: 0,
level2: 0,
level3: 0,
level4: 0,
level5: 0,
level6: 0,
completedModules: [],
strengths: [],
areasForImprovement: []
});
const levels = [
{
id: 1,
name: 'Foundation',
description: 'Master the basics: value proposition, motivated sellers, and success metrics',
modules: [
{ id: 'foundation-value', name: 'Company Value Proposition', icon: Building2 },
{ id: 'foundation-motivated', name: 'Motivated vs Unmotivated Sellers', icon: Target },
{ id: 'foundation-metrics', name: 'KPIs & Success Metrics', icon: BarChart3 }
]
},
{
id: 2,
name: 'Discovery & Control',
description: 'Learn to ask powerful questions and control conversations',
modules: [
{ id: 'discovery-questions', name: 'Qualification Questions', icon: MessageSquare },
{ id: 'discovery-control', name: 'Conversation Control', icon: Brain },
{ id: 'discovery-motivation', name: 'Uncovering True Motivation', icon: Lightbulb }
]
},
{
id: 3,
name: 'Objection Mastery',
description: 'Handle any objection with confidence and tactical empathy',
modules: [
{ id: 'objection-common', name: 'Common Objections', icon: MessageSquare },
{ id: 'objection-framework', name: 'Response Framework', icon: Target },
{ id: 'objection-practice', name: 'Live Objection Practice', icon: Phone }
]
},
{
id: 4,
name: 'Pricing & Negotiation',
description: 'Master pricing strategy and problem-focused selling',
modules: [
{ id: 'pricing-mao', name: 'MAO Calculations', icon: BarChart3 },
{ id: 'pricing-strategy', name: 'Offer Strategy', icon: Target },
{ id: 'pricing-negotiation', name: 'Negotiation Techniques', icon: TrendingUp }
]
},
{
id: 5,
name: 'Follow-Up Excellence',
description: 'Master persistence and follow-up cadences',
modules: [
{ id: 'followup-cadence', name: 'Call Cadences', icon: Clock },
{ id: 'followup-persistence', name: 'Persistence Strategies', icon: Trophy },
{ id: 'followup-crm', name: 'ReiFax Workflow', icon: CheckCircle }
]
},
{
id: 6,
name: 'Advanced Mastery',
description: 'Handle complex scenarios and multi-stakeholder deals',
modules: [
{ id: 'advanced-scenarios', name: 'Complex Scenarios', icon: Brain },
{ id: 'advanced-stakeholders', name: 'Multiple Decision Makers', icon: MessageSquare },
{ id: 'advanced-closing', name: 'Expert-Level Closing', icon: Award }
]
}
];
const startModule = async (moduleId) => {
setCurrentModule(moduleId);
setScreen('training');
setUserResponse('');
setConversation([]);
setFeedback(null);
setIsLoading(true);
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'claude-sonnet-4-20250514',
max_tokens: 2000,
messages: [{
role: 'user',
content: `You are an expert real estate acquisition trainer for M&J FL Realty LLC. Generate an interactive training scenario for module: ${moduleId}.
Based on the M&J training materials:
- Daily targets: 100+ calls, 20+ contacts, 5+ meaningful conversations
- Focus on motivated sellers (problem-solving over price)
- Never say "Yes, but..." - use "I can understand, what we do is..."
- MAO Formula: (Real FMV) x 50-65% - repairs - costs
- Value props: all cash, no commissions, fast closing, help with moving, pay closing costs
- The money is in the follow-up (8-12 touches minimum)
Create a realistic scenario with:
1. Seller persona with specific situation (foreclosure, probate, divorce, etc.)
2. Property details and motivation level
3. An opening situation for the rep to respond to
Format as JSON:
{
"scenario": "description",
"sellerName": "name",
"sellerSituation": "situation",
"propertyAddress": "address",
"motivationLevel": "high/medium/low",
"challenge": "what makes this scenario challenging",
"learningObjective": "what the rep should practice"
}`
}]
})
});
const data = await response.json();
let responseText = data.content[0].text;
responseText = responseText.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim();
const scenario = JSON.parse(responseText);
setScenarioData(scenario);
setConversation([{
role: 'system',
content: `π **${scenario.sellerName}** (${scenario.motivationLevel} motivation)\nπ ${scenario.propertyAddress}\n\n${scenario.scenario}`
}]);
} catch (error) {
console.error('Error generating scenario:', error);
setConversation([{
role: 'system',
content: 'Unable to generate scenario. Please try again.'
}]);
}
setIsLoading(false);
};
const handleSubmitResponse = async () => {
if (!userResponse.trim() || isLoading) return;
const newConversation = [...conversation, { role: 'user', content: userResponse }];
setConversation(newConversation);
setUserResponse('');
setIsLoading(true);
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'claude-sonnet-4-20250514',
max_tokens: 1500,
messages: [
{
role: 'user',
content: `You are role-playing as ${scenarioData.sellerName}, a property seller in this situation: ${scenarioData.sellerSituation}
Current conversation:
${newConversation.map(m => `${m.role}: ${m.content}`).join('\n')}
As the seller, respond naturally to the acquisition rep's last message. Be realistic - show emotions, concerns, and objections that real sellers have. Your motivation level is ${scenarioData.motivationLevel}.
Then, provide coaching feedback on the rep's response:
- What they did well (be specific)
- What could be improved (be specific)
- Suggested alternative approach from M&J training
- Score their response (1-10)
Format as JSON:
{
"sellerResponse": "what the seller says",
"feedback": {
"strengths": ["strength 1", "strength 2"],
"improvements": ["improvement 1", "improvement 2"],
"suggestion": "specific suggestion",
"score": 7
}
}`
}
]
})
});
const data = await response.json();
let responseText = data.content[0].text;
responseText = responseText.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim();
const result = JSON.parse(responseText);
setConversation([...newConversation, { role: 'assistant', content: result.sellerResponse }]);
setFeedback(result.feedback);
} catch (error) {
console.error('Error:', error);
setConversation([...newConversation, { role: 'assistant', content: 'I appreciate you working with me on this. What else can you tell me about your solution?' }]);
}
setIsLoading(false);
};
const completeModule = () => {
const levelKey = `level${currentLevel}`;
const newProgress = { ...progress };
if (!newProgress.completedModules.includes(currentModule)) {
newProgress.completedModules.push(currentModule);
const currentLevelModules = levels.find(l => l.id === currentLevel).modules.length;
const completedInLevel = newProgress.completedModules.filter(m => m.startsWith(levels[currentLevel - 1].name.toLowerCase().replace(/\s+/g, '-').replace(/&/g, ''))).length;
newProgress[levelKey] = Math.round((completedInLevel / currentLevelModules) * 100);
}
if (feedback && feedback.score >= 8) {
newProgress.strengths.push(currentModule);
} else if (feedback && feedback.score < 7) {
newProgress.areasForImprovement.push(currentModule);
}
setProgress(newProgress);
setScreen('dashboard');
setCurrentModule(null);
setFeedback(null);
};
if (screen === 'welcome') {
return (
);
}
if (screen === 'dashboard') {
const currentLevelData = levels.find(l => l.id === currentLevel);
return (
{(progress.strengths.length > 0 || progress.areasForImprovement.length > 0) && (
);
}
if (screen === 'training') {
return (
{scenarioData && (
)}
{feedback ? (
{feedback.strengths.length > 0 && (
What You Did Well
)}
{feedback.improvements.length > 0 && (
Areas for Improvement
)}
{feedback.suggestion && (
M&J Technique Suggestion
)}
) : (
)}
);
}
return null;
};
export default RealEstateTraining;
M&J Acquisition Rep Training
Master the art of real estate acquisitions
setUserName(e.target.value)}
placeholder="Enter your name"
className="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:border-blue-600 focus:outline-none"
/>
What You'll Learn:
-
The M&J Way: Persistence, motivation detection, and problem-solving -
Discovery questions and conversation control techniques -
Objection handling with tactical empathy -
Pricing strategy and MAO calculations -
Follow-up cadences and persistence strategies
Welcome back, {userName}! π
Ready to become an acquisition expert?
{progress.completedModules.length}
Modules Completed
100+
Daily Call Target
20+
Contact Goal
8-12
Touches to Close
Training Levels
{levels.map((level) => (
))}
{currentLevelData.name}
{currentLevelData.description}
{currentLevelData.modules.map((module) => {
const Icon = module.icon;
const isCompleted = progress.completedModules.includes(module.id);
return (
);
})}
{progress.strengths.length > 0 && (
)}
{progress.areasForImprovement.length > 0 && (
)}
)}
Your Strengths
-
{progress.strengths.slice(-3).map((module, i) => (
-
{module.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
))}
Focus Areas
-
{progress.areasForImprovement.slice(-3).map((module, i) => (
-
{module.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
))}
{currentModule?.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
{scenarioData && ({scenarioData.learningObjective}
)}
Live Call Simulation
{scenarioData && (
Scenario Context:
Challenge: {scenarioData.challenge}
Motivation: {scenarioData.motivationLevel}
{conversation.map((msg, i) => (
))}
{isLoading && (
)}
{msg.role === 'system' ? (
{msg.content}
) : (
{msg.content}
)}
Seller is thinking...
Real-Time Coaching
{feedback ? (
{feedback.score}/10
Response Score
-
{feedback.strengths.map((strength, i) => (
-
{strength}
))}
-
{feedback.improvements.map((improvement, i) => (
-
{improvement}
))}
{feedback.suggestion}
Send a response to receive coaching feedback
π‘ M&J Quick Tips:
- β’ Focus on solving THEIR problem, not pitching price
- β’ Use "I can understand, what we do is..." not "Yes, but..."
- β’ Ask "Why are you selling?" to uncover true motivation
- β’ Smile on the phone - they can hear it!
- β’ The money is in the follow-up