|
@@ -85,7 +85,35 @@
|
|
|
<div v-else class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-start">
|
|
<div v-else class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-start">
|
|
|
<!-- Active scan 3D viewer (Top on mobile, right on desktop) -->
|
|
<!-- Active scan 3D viewer (Top on mobile, right on desktop) -->
|
|
|
<div class="lg:col-span-7 lg:order-2 space-y-4">
|
|
<div class="lg:col-span-7 lg:order-2 space-y-4">
|
|
|
|
|
+ <!-- Toggle 3D vs Real Photo -->
|
|
|
|
|
+ <div v-if="activeScan.has_photo" class="flex gap-1.5 p-1 bg-card/60 border border-border/40 rounded-2xl w-fit">
|
|
|
|
|
+ <button
|
|
|
|
|
+ @click="showRealPhoto = false"
|
|
|
|
|
+ class="px-4 py-1.5 rounded-xl text-xs font-black transition-all"
|
|
|
|
|
+ :class="!showRealPhoto ? 'bg-primary text-primary-foreground shadow-lg shadow-primary/20' : 'text-muted-foreground hover:text-white'"
|
|
|
|
|
+ >
|
|
|
|
|
+ 360° View
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ @click="showRealPhoto = true"
|
|
|
|
|
+ class="px-4 py-1.5 rounded-xl text-xs font-black transition-all"
|
|
|
|
|
+ :class="showRealPhoto ? 'bg-primary text-primary-foreground shadow-lg shadow-primary/20' : 'text-muted-foreground hover:text-white'"
|
|
|
|
|
+ >
|
|
|
|
|
+ Original Photo
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Photorealistic Image Container -->
|
|
|
|
|
+ <div v-if="showRealPhoto && activeScan.has_photo" class="relative group aspect-square lg:aspect-video rounded-[2.5rem] border border-border/50 bg-black/45 overflow-hidden flex items-center justify-center backdrop-blur-sm">
|
|
|
|
|
+ <img
|
|
|
|
|
+ :src="`${RESOURCES_BASE_URL}/uploads/scans/${activeScan.folder_name}/photo.webp`"
|
|
|
|
|
+ alt="Original physical object"
|
|
|
|
|
+ class="max-w-full max-h-full object-contain"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<ThreeSixtyViewer
|
|
<ThreeSixtyViewer
|
|
|
|
|
+ v-else
|
|
|
:folder-name="activeScan.folder_name"
|
|
:folder-name="activeScan.folder_name"
|
|
|
:frames-count="activeScan.frames_count"
|
|
:frames-count="activeScan.frames_count"
|
|
|
:resources-base-url="RESOURCES_BASE_URL"
|
|
:resources-base-url="RESOURCES_BASE_URL"
|
|
@@ -105,7 +133,7 @@
|
|
|
<button
|
|
<button
|
|
|
v-for="scan in scans"
|
|
v-for="scan in scans"
|
|
|
:key="scan.id"
|
|
:key="scan.id"
|
|
|
- @click="activeScan = scan"
|
|
|
|
|
|
|
+ @click="activeScan = scan; showRealPhoto = false"
|
|
|
class="w-full text-left p-4 rounded-2xl border transition-all duration-300 flex gap-4 bg-card/20 hover:bg-card/45"
|
|
class="w-full text-left p-4 rounded-2xl border transition-all duration-300 flex gap-4 bg-card/20 hover:bg-card/45"
|
|
|
:class="activeScan.id === scan.id ? 'border-primary/50 bg-primary/5 shadow-lg shadow-primary/5' : 'border-border/35 hover:border-border/60'"
|
|
:class="activeScan.id === scan.id ? 'border-primary/50 bg-primary/5 shadow-lg shadow-primary/5' : 'border-border/35 hover:border-border/60'"
|
|
|
>
|
|
>
|
|
@@ -191,6 +219,7 @@ const { t, locale } = useI18n();
|
|
|
|
|
|
|
|
const scans = ref<any[]>([]);
|
|
const scans = ref<any[]>([]);
|
|
|
const activeScan = ref<any>(null);
|
|
const activeScan = ref<any>(null);
|
|
|
|
|
+const showRealPhoto = ref(false);
|
|
|
const loading = ref(true);
|
|
const loading = ref(true);
|
|
|
|
|
|
|
|
const getIcon = (step: string) => {
|
|
const getIcon = (step: string) => {
|