Spaces:
Build error
Build error
Update templates/index.html
Browse files- templates/index.html +78 -59
templates/index.html
CHANGED
|
@@ -284,45 +284,11 @@
|
|
| 284 |
analyzeImage(file);
|
| 285 |
}
|
| 286 |
|
| 287 |
-
function analyzeImage(file) {
|
| 288 |
-
const formData = new FormData();
|
| 289 |
-
formData.append('image', file);
|
| 290 |
-
|
| 291 |
-
// Show loading
|
| 292 |
-
loading.style.display = 'block';
|
| 293 |
-
results.style.display = 'none';
|
| 294 |
|
| 295 |
-
// Simulate progress
|
| 296 |
-
let progress = 0;
|
| 297 |
-
const progressFill = document.querySelector('.progress-fill');
|
| 298 |
-
const progressInterval = setInterval(() => {
|
| 299 |
-
progress += Math.random() * 15;
|
| 300 |
-
if (progress > 90) progress = 90;
|
| 301 |
-
progressFill.style.width = progress + '%';
|
| 302 |
-
}, 500);
|
| 303 |
-
|
| 304 |
-
fetch('/analyze', {
|
| 305 |
-
method: 'POST',
|
| 306 |
-
body: formData
|
| 307 |
-
})
|
| 308 |
-
.then(response => response.json())
|
| 309 |
-
.then(data => {
|
| 310 |
-
clearInterval(progressInterval);
|
| 311 |
-
progressFill.style.width = '100%';
|
| 312 |
-
|
| 313 |
-
setTimeout(() => {
|
| 314 |
-
loading.style.display = 'none';
|
| 315 |
-
displayResults(data);
|
| 316 |
-
}, 1000);
|
| 317 |
-
})
|
| 318 |
-
.catch(error => {
|
| 319 |
-
clearInterval(progressInterval);
|
| 320 |
-
loading.style.display = 'none';
|
| 321 |
-
alert('Analysis failed: ' + error.message);
|
| 322 |
-
});
|
| 323 |
-
}
|
| 324 |
|
| 325 |
function displayResults(data) {
|
|
|
|
|
|
|
| 326 |
if (data.error) {
|
| 327 |
results.innerHTML = `
|
| 328 |
<div class="error-card">
|
|
@@ -334,15 +300,16 @@
|
|
| 334 |
return;
|
| 335 |
}
|
| 336 |
|
| 337 |
-
|
| 338 |
-
const
|
| 339 |
-
const
|
| 340 |
-
const
|
| 341 |
-
const
|
| 342 |
-
const
|
| 343 |
-
const
|
| 344 |
-
const
|
| 345 |
-
const
|
|
|
|
| 346 |
|
| 347 |
results.innerHTML = `
|
| 348 |
<!-- Analysis Summary -->
|
|
@@ -413,12 +380,12 @@
|
|
| 413 |
<div class="col-md-6">
|
| 414 |
<h6>Competitive Advantages:</h6>
|
| 415 |
<ul>
|
| 416 |
-
${market.competitive_advantages.map(adv => `<li>${adv}</li>`).join('')}
|
| 417 |
</ul>
|
| 418 |
|
| 419 |
<h6>Differentiation Factors:</h6>
|
| 420 |
<ul>
|
| 421 |
-
${market.differentiation_factors.map(factor => `<li>${factor}</li>`).join('')}
|
| 422 |
</ul>
|
| 423 |
</div>
|
| 424 |
</div>
|
|
@@ -435,23 +402,23 @@
|
|
| 435 |
<div class="col-md-6">
|
| 436 |
<h6><i class="fas fa-bullhorn"></i> Marketing Tips</h6>
|
| 437 |
<ul>
|
| 438 |
-
${insights.marketing_tips.map(tip => `<li>${tip}</li>`).join('')}
|
| 439 |
</ul>
|
| 440 |
|
| 441 |
<h6><i class="fas fa-users"></i> Target Audience</h6>
|
| 442 |
<ul>
|
| 443 |
-
${insights.target_audience.map(audience => `<li>${audience}</li>`).join('')}
|
| 444 |
</ul>
|
| 445 |
</div>
|
| 446 |
<div class="col-md-6">
|
| 447 |
<h6><i class="fas fa-dollar-sign"></i> Pricing Considerations</h6>
|
| 448 |
<ul>
|
| 449 |
-
${insights.pricing_considerations.map(consideration => `<li>${consideration}</li>`).join('')}
|
| 450 |
</ul>
|
| 451 |
|
| 452 |
<h6><i class="fas fa-tools"></i> Improvement Suggestions</h6>
|
| 453 |
<ul>
|
| 454 |
-
${insights.improvement_suggestions.map(suggestion => `<li>${suggestion}</li>`).join('')}
|
| 455 |
</ul>
|
| 456 |
</div>
|
| 457 |
</div>
|
|
@@ -471,7 +438,7 @@
|
|
| 471 |
|
| 472 |
<h6>Scene Concepts:</h6>
|
| 473 |
<div>
|
| 474 |
-
${scene.scene_concepts.map(concept =>
|
| 475 |
`<span class="scene-concept">${concept.concept} (${(concept.confidence * 100).toFixed(1)}%)</span>`
|
| 476 |
).join('')}
|
| 477 |
</div>
|
|
@@ -479,14 +446,14 @@
|
|
| 479 |
<div class="col-md-6">
|
| 480 |
<h6>Quality Indicators:</h6>
|
| 481 |
<ul>
|
| 482 |
-
${scene.style_analysis.quality_indicators.map(indicator =>
|
| 483 |
`<li>${indicator.concept} (${(indicator.confidence * 100).toFixed(1)}%)</li>`
|
| 484 |
).join('')}
|
| 485 |
</ul>
|
| 486 |
|
| 487 |
<h6>Functionality Indicators:</h6>
|
| 488 |
<ul>
|
| 489 |
-
${scene.style_analysis.functionality_indicators.map(indicator =>
|
| 490 |
`<li>${indicator.concept} (${(indicator.confidence * 100).toFixed(1)}%)</li>`
|
| 491 |
).join('')}
|
| 492 |
</ul>
|
|
@@ -505,23 +472,23 @@
|
|
| 505 |
<div class="col-md-6">
|
| 506 |
<h6>Strengths:</h6>
|
| 507 |
<ul>
|
| 508 |
-
${assessment.strengths.map(strength => `<li class="insight-card">${strength}</li>`).join('')}
|
| 509 |
</ul>
|
| 510 |
|
| 511 |
<h6>Weaknesses:</h6>
|
| 512 |
<ul>
|
| 513 |
-
${assessment.weaknesses.map(weakness => `<li class="warning-card">${weakness}</li>`).join('')}
|
| 514 |
</ul>
|
| 515 |
</div>
|
| 516 |
<div class="col-md-6">
|
| 517 |
<h6>Recommendations:</h6>
|
| 518 |
<ul>
|
| 519 |
-
${assessment.recommendations.map(rec => `<li class="insight-card">${rec}</li>`).join('')}
|
| 520 |
</ul>
|
| 521 |
|
| 522 |
<h6>Market Opportunities:</h6>
|
| 523 |
<ul>
|
| 524 |
-
${market.market_opportunities.map(opp => `<li class="insight-card">${opp}</li>`).join('')}
|
| 525 |
</ul>
|
| 526 |
</div>
|
| 527 |
</div>
|
|
@@ -537,7 +504,7 @@
|
|
| 537 |
<div class="row">
|
| 538 |
<div class="col-md-6">
|
| 539 |
<h6>Detected Objects:</h6>
|
| 540 |
-
${objects.objects.map(obj => `
|
| 541 |
<div class="object-item">
|
| 542 |
<span><i class="fas fa-tag"></i> ${obj.label}</span>
|
| 543 |
<div class="confidence-bar">
|
|
@@ -584,6 +551,58 @@
|
|
| 584 |
results.style.display = 'block';
|
| 585 |
}
|
| 586 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 587 |
function getScoreClass(score) {
|
| 588 |
if (score >= 85) return 'score-excellent';
|
| 589 |
if (score >= 70) return 'score-good';
|
|
|
|
| 284 |
analyzeImage(file);
|
| 285 |
}
|
| 286 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
|
| 289 |
function displayResults(data) {
|
| 290 |
+
console.log('Received data:', data); // Debug log
|
| 291 |
+
|
| 292 |
if (data.error) {
|
| 293 |
results.innerHTML = `
|
| 294 |
<div class="error-card">
|
|
|
|
| 300 |
return;
|
| 301 |
}
|
| 302 |
|
| 303 |
+
// Safely extract data with defaults
|
| 304 |
+
const summary = data.analysis_summary || {};
|
| 305 |
+
const roomClass = data.room_classification || { room_type: 'Unknown', confidence: 0 };
|
| 306 |
+
const quality = data.quality_analysis || { quality_score: 0, quality_level: 'Unknown' };
|
| 307 |
+
const objects = data.object_detection || { objects: [], analysis: {} };
|
| 308 |
+
const assessment = data.property_assessment || { overall_score: 0, professional_grade: false };
|
| 309 |
+
const insights = data.property_insights || { marketing_tips: [], target_audience: [], pricing_considerations: [], improvement_suggestions: [] };
|
| 310 |
+
const scene = data.scene_analysis || { style_analysis: { dominant_style: 'Unknown', style_confidence: 0, quality_indicators: [], functionality_indicators: [] }, scene_concepts: [] };
|
| 311 |
+
const market = data.market_analysis || { market_tier: 'Unknown', target_market: 'Unknown', price_positioning: 'Unknown', competitive_position: 'Unknown', competitive_advantages: [], differentiation_factors: [], market_opportunities: [] };
|
| 312 |
+
const roomSize = data.room_size_estimation || { estimated_size: 'Unknown', confidence: 'Low' };
|
| 313 |
|
| 314 |
results.innerHTML = `
|
| 315 |
<!-- Analysis Summary -->
|
|
|
|
| 380 |
<div class="col-md-6">
|
| 381 |
<h6>Competitive Advantages:</h6>
|
| 382 |
<ul>
|
| 383 |
+
${(market.competitive_advantages || []).map(adv => `<li>${adv}</li>`).join('')}
|
| 384 |
</ul>
|
| 385 |
|
| 386 |
<h6>Differentiation Factors:</h6>
|
| 387 |
<ul>
|
| 388 |
+
${(market.differentiation_factors || []).map(factor => `<li>${factor}</li>`).join('')}
|
| 389 |
</ul>
|
| 390 |
</div>
|
| 391 |
</div>
|
|
|
|
| 402 |
<div class="col-md-6">
|
| 403 |
<h6><i class="fas fa-bullhorn"></i> Marketing Tips</h6>
|
| 404 |
<ul>
|
| 405 |
+
${(insights.marketing_tips || []).map(tip => `<li>${tip}</li>`).join('')}
|
| 406 |
</ul>
|
| 407 |
|
| 408 |
<h6><i class="fas fa-users"></i> Target Audience</h6>
|
| 409 |
<ul>
|
| 410 |
+
${(insights.target_audience || []).map(audience => `<li>${audience}</li>`).join('')}
|
| 411 |
</ul>
|
| 412 |
</div>
|
| 413 |
<div class="col-md-6">
|
| 414 |
<h6><i class="fas fa-dollar-sign"></i> Pricing Considerations</h6>
|
| 415 |
<ul>
|
| 416 |
+
${(insights.pricing_considerations || []).map(consideration => `<li>${consideration}</li>`).join('')}
|
| 417 |
</ul>
|
| 418 |
|
| 419 |
<h6><i class="fas fa-tools"></i> Improvement Suggestions</h6>
|
| 420 |
<ul>
|
| 421 |
+
${(insights.improvement_suggestions || []).map(suggestion => `<li>${suggestion}</li>`).join('')}
|
| 422 |
</ul>
|
| 423 |
</div>
|
| 424 |
</div>
|
|
|
|
| 438 |
|
| 439 |
<h6>Scene Concepts:</h6>
|
| 440 |
<div>
|
| 441 |
+
${(scene.scene_concepts || []).map(concept =>
|
| 442 |
`<span class="scene-concept">${concept.concept} (${(concept.confidence * 100).toFixed(1)}%)</span>`
|
| 443 |
).join('')}
|
| 444 |
</div>
|
|
|
|
| 446 |
<div class="col-md-6">
|
| 447 |
<h6>Quality Indicators:</h6>
|
| 448 |
<ul>
|
| 449 |
+
${(scene.style_analysis.quality_indicators || []).map(indicator =>
|
| 450 |
`<li>${indicator.concept} (${(indicator.confidence * 100).toFixed(1)}%)</li>`
|
| 451 |
).join('')}
|
| 452 |
</ul>
|
| 453 |
|
| 454 |
<h6>Functionality Indicators:</h6>
|
| 455 |
<ul>
|
| 456 |
+
${(scene.style_analysis.functionality_indicators || []).map(indicator =>
|
| 457 |
`<li>${indicator.concept} (${(indicator.confidence * 100).toFixed(1)}%)</li>`
|
| 458 |
).join('')}
|
| 459 |
</ul>
|
|
|
|
| 472 |
<div class="col-md-6">
|
| 473 |
<h6>Strengths:</h6>
|
| 474 |
<ul>
|
| 475 |
+
${(assessment.strengths || []).map(strength => `<li class="insight-card">${strength}</li>`).join('')}
|
| 476 |
</ul>
|
| 477 |
|
| 478 |
<h6>Weaknesses:</h6>
|
| 479 |
<ul>
|
| 480 |
+
${(assessment.weaknesses || []).map(weakness => `<li class="warning-card">${weakness}</li>`).join('')}
|
| 481 |
</ul>
|
| 482 |
</div>
|
| 483 |
<div class="col-md-6">
|
| 484 |
<h6>Recommendations:</h6>
|
| 485 |
<ul>
|
| 486 |
+
${(assessment.recommendations || []).map(rec => `<li class="insight-card">${rec}</li>`).join('')}
|
| 487 |
</ul>
|
| 488 |
|
| 489 |
<h6>Market Opportunities:</h6>
|
| 490 |
<ul>
|
| 491 |
+
${(market.market_opportunities || []).map(opp => `<li class="insight-card">${opp}</li>`).join('')}
|
| 492 |
</ul>
|
| 493 |
</div>
|
| 494 |
</div>
|
|
|
|
| 504 |
<div class="row">
|
| 505 |
<div class="col-md-6">
|
| 506 |
<h6>Detected Objects:</h6>
|
| 507 |
+
${(objects.objects || []).map(obj => `
|
| 508 |
<div class="object-item">
|
| 509 |
<span><i class="fas fa-tag"></i> ${obj.label}</span>
|
| 510 |
<div class="confidence-bar">
|
|
|
|
| 551 |
results.style.display = 'block';
|
| 552 |
}
|
| 553 |
|
| 554 |
+
// Add error handling for the fetch request
|
| 555 |
+
function analyzeImage(file) {
|
| 556 |
+
const formData = new FormData();
|
| 557 |
+
formData.append('image', file);
|
| 558 |
+
|
| 559 |
+
// Show loading
|
| 560 |
+
loading.style.display = 'block';
|
| 561 |
+
results.style.display = 'none';
|
| 562 |
+
|
| 563 |
+
// Simulate progress
|
| 564 |
+
let progress = 0;
|
| 565 |
+
const progressFill = document.querySelector('.progress-fill');
|
| 566 |
+
const progressInterval = setInterval(() => {
|
| 567 |
+
progress += Math.random() * 15;
|
| 568 |
+
if (progress > 90) progress = 90;
|
| 569 |
+
progressFill.style.width = progress + '%';
|
| 570 |
+
}, 500);
|
| 571 |
+
|
| 572 |
+
fetch('/analyze', {
|
| 573 |
+
method: 'POST',
|
| 574 |
+
body: formData
|
| 575 |
+
})
|
| 576 |
+
.then(response => {
|
| 577 |
+
if (!response.ok) {
|
| 578 |
+
throw new Error(`HTTP error! status: ${response.status}`);
|
| 579 |
+
}
|
| 580 |
+
return response.json();
|
| 581 |
+
})
|
| 582 |
+
.then(data => {
|
| 583 |
+
clearInterval(progressInterval);
|
| 584 |
+
progressFill.style.width = '100%';
|
| 585 |
+
|
| 586 |
+
setTimeout(() => {
|
| 587 |
+
loading.style.display = 'none';
|
| 588 |
+
displayResults(data);
|
| 589 |
+
}, 1000);
|
| 590 |
+
})
|
| 591 |
+
.catch(error => {
|
| 592 |
+
clearInterval(progressInterval);
|
| 593 |
+
loading.style.display = 'none';
|
| 594 |
+
console.error('Analysis failed:', error);
|
| 595 |
+
results.innerHTML = `
|
| 596 |
+
<div class="error-card">
|
| 597 |
+
<h5><i class="fas fa-exclamation-triangle"></i> Analysis Failed</h5>
|
| 598 |
+
<p>Error: ${error.message}</p>
|
| 599 |
+
<p>Please try again or check the server logs.</p>
|
| 600 |
+
</div>
|
| 601 |
+
`;
|
| 602 |
+
results.style.display = 'block';
|
| 603 |
+
});
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
function getScoreClass(score) {
|
| 607 |
if (score >= 85) return 'score-excellent';
|
| 608 |
if (score >= 70) return 'score-good';
|