Spaces:
Running
Running
quick preview function seems broken
Browse files
script.js
CHANGED
|
@@ -986,14 +986,178 @@ function copyTags() {
|
|
| 986 |
navigator.clipboard.writeText(tags);
|
| 987 |
showToast('Tags copied to clipboard!', 'success');
|
| 988 |
}
|
| 989 |
-
|
| 990 |
-
function draftAnalysis() {
|
| 991 |
if (uploadedPhotos.length === 0) {
|
| 992 |
showToast('Upload photos first for preview', 'error');
|
| 993 |
return;
|
| 994 |
}
|
| 995 |
-
|
| 996 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 997 |
}
|
| 998 |
async function callAI(messages, temperature = 0.7) {
|
| 999 |
const provider = localStorage.getItem('ai_provider') || 'openai';
|
|
|
|
| 986 |
navigator.clipboard.writeText(tags);
|
| 987 |
showToast('Tags copied to clipboard!', 'success');
|
| 988 |
}
|
| 989 |
+
async function draftAnalysis() {
|
|
|
|
| 990 |
if (uploadedPhotos.length === 0) {
|
| 991 |
showToast('Upload photos first for preview', 'error');
|
| 992 |
return;
|
| 993 |
}
|
| 994 |
+
|
| 995 |
+
const artist = document.getElementById('artistInput').value.trim();
|
| 996 |
+
const title = document.getElementById('titleInput').value.trim();
|
| 997 |
+
|
| 998 |
+
// Show loading state
|
| 999 |
+
const dropZone = document.getElementById('dropZone');
|
| 1000 |
+
const spinner = document.getElementById('uploadSpinner');
|
| 1001 |
+
spinner.classList.remove('hidden');
|
| 1002 |
+
dropZone.classList.add('pointer-events-none');
|
| 1003 |
+
startAnalysisProgressSimulation();
|
| 1004 |
+
|
| 1005 |
+
try {
|
| 1006 |
+
// Try OCR/AI analysis if available
|
| 1007 |
+
const service = getAIService();
|
| 1008 |
+
let ocrResult = null;
|
| 1009 |
+
|
| 1010 |
+
if (service && service.apiKey && uploadedPhotos.length > 0) {
|
| 1011 |
+
try {
|
| 1012 |
+
ocrResult = await service.analyzeRecordImages(uploadedPhotos.slice(0, 2)); // Limit to 2 photos for speed
|
| 1013 |
+
populateFieldsFromOCR(ocrResult);
|
| 1014 |
+
} catch (e) {
|
| 1015 |
+
console.log('Preview OCR failed:', e);
|
| 1016 |
+
}
|
| 1017 |
+
}
|
| 1018 |
+
|
| 1019 |
+
// Generate quick preview results
|
| 1020 |
+
const catNo = document.getElementById('catInput').value.trim() || ocrResult?.catalogueNumber || '';
|
| 1021 |
+
const year = document.getElementById('yearInput').value.trim() || ocrResult?.year || '';
|
| 1022 |
+
const detectedArtist = artist || ocrResult?.artist || 'Unknown Artist';
|
| 1023 |
+
const detectedTitle = title || ocrResult?.title || 'Unknown Title';
|
| 1024 |
+
|
| 1025 |
+
const baseTitle = `${detectedArtist} - ${detectedTitle}`;
|
| 1026 |
+
|
| 1027 |
+
// Generate quick titles
|
| 1028 |
+
const quickTitles = [
|
| 1029 |
+
`${baseTitle} ${year ? `(${year})` : ''} ${catNo} VG+`.substring(0, 80),
|
| 1030 |
+
`${baseTitle} Original Pressing Vinyl LP`.substring(0, 80),
|
| 1031 |
+
`${detectedArtist} ${detectedTitle} ${catNo || 'LP'}`.substring(0, 80)
|
| 1032 |
+
].map((t, i) => ({
|
| 1033 |
+
text: t,
|
| 1034 |
+
chars: t.length,
|
| 1035 |
+
style: ['Quick', 'Standard', 'Compact'][i]
|
| 1036 |
+
}));
|
| 1037 |
+
|
| 1038 |
+
// Quick pricing estimate based on condition
|
| 1039 |
+
const cost = parseFloat(document.getElementById('costInput').value) || 10;
|
| 1040 |
+
const vinylCond = document.getElementById('vinylConditionInput').value;
|
| 1041 |
+
const sleeveCond = document.getElementById('sleeveConditionInput').value;
|
| 1042 |
+
|
| 1043 |
+
const conditionMultipliers = { 'M': 3, 'NM': 2.5, 'VG+': 1.8, 'VG': 1.2, 'G+': 0.8, 'G': 0.5 };
|
| 1044 |
+
const condMult = (conditionMultipliers[vinylCond] || 1) * 0.7 + (conditionMultipliers[sleeveCond] || 1) * 0.3;
|
| 1045 |
+
|
| 1046 |
+
const estimatedValue = Math.round(cost * Math.max(condMult, 1.5));
|
| 1047 |
+
const suggestedPrice = Math.round(estimatedValue * 0.9);
|
| 1048 |
+
|
| 1049 |
+
// Render preview results
|
| 1050 |
+
renderTitleOptions(quickTitles);
|
| 1051 |
+
|
| 1052 |
+
// Quick pricing card
|
| 1053 |
+
document.getElementById('pricingStrategy').innerHTML = `
|
| 1054 |
+
<div class="pricing-card recommended">
|
| 1055 |
+
<div class="flex items-center gap-2 mb-3">
|
| 1056 |
+
<span class="px-2 py-1 bg-accent/20 text-accent text-xs font-medium rounded">QUICK ESTIMATE</span>
|
| 1057 |
+
</div>
|
| 1058 |
+
<p class="text-3xl font-bold text-white mb-1">£${suggestedPrice}</p>
|
| 1059 |
+
<p class="text-sm text-gray-400 mb-3">Suggested Buy It Now</p>
|
| 1060 |
+
<div class="space-y-2 text-sm">
|
| 1061 |
+
<p class="flex justify-between"><span class="text-gray-500">Est. Value:</span> <span class="text-gray-300">£${estimatedValue}</span></p>
|
| 1062 |
+
<p class="flex justify-between"><span class="text-gray-500">Your Cost:</span> <span class="text-gray-300">£${cost.toFixed(2)}</span></p>
|
| 1063 |
+
<p class="flex justify-between"><span class="text-gray-500">Condition:</span> <span class="text-gray-300">${vinylCond}/${sleeveCond}</span></p>
|
| 1064 |
+
</div>
|
| 1065 |
+
</div>
|
| 1066 |
+
<div class="space-y-3">
|
| 1067 |
+
<h4 class="text-sm font-medium text-gray-400 uppercase tracking-wide">Preview Notes</h4>
|
| 1068 |
+
<div class="p-3 bg-surface rounded-lg text-sm text-gray-400">
|
| 1069 |
+
${ocrResult ?
|
| 1070 |
+
`<p class="text-green-400 mb-2">✓ AI detected information from photos</p>` :
|
| 1071 |
+
`<p class="text-yellow-400 mb-2">⚠ Add API key in Settings for auto-detection</p>`
|
| 1072 |
+
}
|
| 1073 |
+
<p>This is a quick estimate based on your cost and condition. Run "Generate Full Listing" for complete market analysis, sold comps, and optimized pricing.</p>
|
| 1074 |
+
</div>
|
| 1075 |
+
${ocrResult ? `
|
| 1076 |
+
<div class="p-3 bg-green-500/10 border border-green-500/20 rounded-lg">
|
| 1077 |
+
<p class="text-xs text-green-400 font-medium mb-1">Detected from photos:</p>
|
| 1078 |
+
<ul class="text-xs text-gray-400 space-y-1">
|
| 1079 |
+
${ocrResult.artist ? `<li>• Artist: ${ocrResult.artist}</li>` : ''}
|
| 1080 |
+
${ocrResult.title ? `<li>• Title: ${ocrResult.title}</li>` : ''}
|
| 1081 |
+
${ocrResult.catalogueNumber ? `<li>• Cat#: ${ocrResult.catalogueNumber}</li>` : ''}
|
| 1082 |
+
${ocrResult.year ? `<li>• Year: ${ocrResult.year}</li>` : ''}
|
| 1083 |
+
</ul>
|
| 1084 |
+
</div>
|
| 1085 |
+
` : ''}
|
| 1086 |
+
</div>
|
| 1087 |
+
`;
|
| 1088 |
+
|
| 1089 |
+
// Simple fee floor
|
| 1090 |
+
const fees = suggestedPrice * 0.16;
|
| 1091 |
+
const safeFloor = Math.ceil(cost + fees + 6);
|
| 1092 |
+
|
| 1093 |
+
document.getElementById('feeFloor').innerHTML = `
|
| 1094 |
+
<div class="text-center p-4 bg-surface rounded-lg">
|
| 1095 |
+
<p class="text-xs text-gray-500 uppercase mb-1">Your Cost</p>
|
| 1096 |
+
<p class="text-xl font-bold text-gray-300">£${cost.toFixed(2)}</p>
|
| 1097 |
+
</div>
|
| 1098 |
+
<div class="text-center p-4 bg-surface rounded-lg">
|
| 1099 |
+
<p class="text-xs text-gray-500 uppercase mb-1">Est. Fees</p>
|
| 1100 |
+
<p class="text-xl font-bold text-red-400">£${fees.toFixed(2)}</p>
|
| 1101 |
+
</div>
|
| 1102 |
+
<div class="text-center p-4 bg-surface rounded-lg">
|
| 1103 |
+
<p class="text-xs text-gray-500 uppercase mb-1">Ship + Pack</p>
|
| 1104 |
+
<p class="text-xl font-bold text-gray-300">£6.00</p>
|
| 1105 |
+
</div>
|
| 1106 |
+
<div class="text-center p-4 bg-green-500/10 rounded-lg border border-green-500/30">
|
| 1107 |
+
<p class="text-xs text-green-500 uppercase mb-1">Safe Floor</p>
|
| 1108 |
+
<p class="text-2xl font-bold text-green-400">£${safeFloor}</p>
|
| 1109 |
+
</div>
|
| 1110 |
+
`;
|
| 1111 |
+
|
| 1112 |
+
// Preview HTML description
|
| 1113 |
+
const previewHtml = `<!-- QUICK PREVIEW - Generated by VinylVault Pro -->
|
| 1114 |
+
<div style="max-width: 700px; margin: 0 auto; font-family: sans-serif;">
|
| 1115 |
+
<h2 style="color: #333;">${detectedArtist} - ${detectedTitle}</h2>
|
| 1116 |
+
${year ? `<p><strong>Year:</strong> ${year}</p>` : ''}
|
| 1117 |
+
${catNo ? `<p><strong>Catalogue #:</strong> ${catNo}</p>` : ''}
|
| 1118 |
+
<p><strong>Condition:</strong> Vinyl ${vinylCond}, Sleeve ${sleeveCond}</p>
|
| 1119 |
+
<hr style="margin: 20px 0;">
|
| 1120 |
+
<p style="color: #666;">[Full description will be generated with complete market analysis]</p>
|
| 1121 |
+
</div>`;
|
| 1122 |
+
|
| 1123 |
+
document.getElementById('htmlOutput').value = previewHtml;
|
| 1124 |
+
|
| 1125 |
+
// Preview tags
|
| 1126 |
+
const previewTags = [
|
| 1127 |
+
detectedArtist,
|
| 1128 |
+
detectedTitle,
|
| 1129 |
+
'vinyl',
|
| 1130 |
+
'record',
|
| 1131 |
+
vinylCond,
|
| 1132 |
+
'lp',
|
| 1133 |
+
year || 'vintage'
|
| 1134 |
+
].filter(Boolean);
|
| 1135 |
+
|
| 1136 |
+
document.getElementById('tagsOutput').innerHTML = previewTags.map(t => `
|
| 1137 |
+
<span class="px-3 py-1.5 bg-pink-500/10 text-pink-400 rounded-full text-sm border border-pink-500/20">${t}</span>
|
| 1138 |
+
`).join('');
|
| 1139 |
+
|
| 1140 |
+
// Update shot list
|
| 1141 |
+
renderShotList();
|
| 1142 |
+
|
| 1143 |
+
// Show results
|
| 1144 |
+
resultsSection.classList.remove('hidden');
|
| 1145 |
+
emptyState.classList.add('hidden');
|
| 1146 |
+
resultsSection.scrollIntoView({ behavior: 'smooth' });
|
| 1147 |
+
|
| 1148 |
+
showToast('Quick preview ready! Click "Generate Full Listing" for complete analysis.', 'success');
|
| 1149 |
+
|
| 1150 |
+
} catch (error) {
|
| 1151 |
+
console.error('Preview error:', error);
|
| 1152 |
+
showToast('Preview failed: ' + error.message, 'error');
|
| 1153 |
+
} finally {
|
| 1154 |
+
stopAnalysisProgress();
|
| 1155 |
+
setTimeout(() => {
|
| 1156 |
+
spinner.classList.add('hidden');
|
| 1157 |
+
dropZone.classList.remove('pointer-events-none');
|
| 1158 |
+
updateAnalysisProgress('Initializing...', 0);
|
| 1159 |
+
}, 300);
|
| 1160 |
+
}
|
| 1161 |
}
|
| 1162 |
async function callAI(messages, temperature = 0.7) {
|
| 1163 |
const provider = localStorage.getItem('ai_provider') || 'openai';
|