feat: dedicated 3D Models bucket in AssetBucketBrowser
Deploy to VPS / deploy (push) Has been cancelled
Deploy to VPS / deploy (push) Has been cancelled
Add a "3D Models" bucket (path: models, accept: .glb/.gltf/.usdz) to the cases scope. Previously 3D files were mixed into the Media bucket at the root. Now they have their own tab with proper file type hints and purple accent color matching the AR viewer UI. - cases/media bucket no longer lists .glb/.gltf/.usdz in accept - New bucketHint for models bucket warns on non-3D file uploads - Network page 3D tab updated with purple accent + "3D Models" button label pointing to the dedicated bucket Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -402,12 +402,12 @@ export default function NetworkManager() {
|
|||||||
<div className={activeTab === "3d" ? "block animate-in fade-in" : "hidden"}>
|
<div className={activeTab === "3d" ? "block animate-in fade-in" : "hidden"}>
|
||||||
<p className="text-xs text-[#86868B] mb-6">3D models, dimensions, and renders for the AR viewer.</p>
|
<p className="text-xs text-[#86868B] mb-6">3D models, dimensions, and renders for the AR viewer.</p>
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
<label className="block text-[10px] uppercase tracking-widest text-[#86868B] mb-1.5 flex items-center gap-2"><Box size={12}/> 3D Model (AR) — public/cases/models</label>
|
<label className="block text-[10px] uppercase tracking-widest text-[#A855F7] mb-1.5 flex items-center gap-2"><Box size={12}/> 3D Model (AR)</label>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<input name="model3DPath" defaultValue={editingNode.model3DPath || ""} placeholder="e.g., flxd60a.glb" className="flex-1 bg-black/60 border border-white/10 rounded-xl px-4 py-3 text-purple-400 font-mono text-sm focus:border-purple-400 outline-none" />
|
<input name="model3DPath" defaultValue={editingNode.model3DPath || ""} placeholder="e.g., flxd60a.glb" className="flex-1 bg-black/60 border border-white/10 rounded-xl px-4 py-3 text-[#A855F7] font-mono text-sm focus:border-[#A855F7] outline-none" />
|
||||||
<button type="button" onClick={() => { setThreeDAssetTarget("model"); setThreeDAssetsOpen(true); }} className="flex items-center gap-1.5 px-4 py-3 text-xs text-emerald-400 bg-emerald-500/10 border border-emerald-500/20 rounded-xl hover:bg-emerald-500/20 font-medium shrink-0"><FolderOpen size={14} /> Browse</button>
|
<button type="button" onClick={() => { setThreeDAssetTarget("model"); setThreeDAssetsOpen(true); }} className="flex items-center gap-1.5 px-4 py-3 text-xs text-[#A855F7] bg-[#A855F7]/10 border border-[#A855F7]/20 rounded-xl hover:bg-[#A855F7]/20 font-medium shrink-0"><FolderOpen size={14} /> 3D Models</button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-[9px] text-[#86868B] mt-1.5">GLB for Android/desktop. USDZ (iOS) auto-derived.</p>
|
<p className="text-[9px] text-[#86868B] mt-1.5">GLB for Android/desktop. USDZ (iOS) auto-derived. Files stored in the dedicated 3D Models bucket.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* DIMENSIONS PANEL */}
|
{/* DIMENSIONS PANEL */}
|
||||||
|
|||||||
@@ -57,8 +57,9 @@ export interface BucketDef {
|
|||||||
|
|
||||||
const BUCKETS_BY_SCOPE: Record<Scope, BucketDef[]> = {
|
const BUCKETS_BY_SCOPE: Record<Scope, BucketDef[]> = {
|
||||||
cases: [
|
cases: [
|
||||||
{ id: "media", path: "", label: "Media", description: "Cover, gallery, 3D models — files at the case root", icon: ImageIcon, accept: "image/*,.glb,.gltf,.usdz", accentColor: "#00F0FF" },
|
{ id: "media", path: "", label: "Media", description: "Cover and gallery images at the case root", icon: ImageIcon, accept: "image/*", accentColor: "#00F0FF" },
|
||||||
{ id: "videos", path: "videos", label: "Videos", description: "MP4 clips of the installation in operation", icon: Video, accept: "video/*", accentColor: "#4DA6FF" },
|
{ id: "videos", path: "videos", label: "Videos", description: "MP4 clips of the installation in operation", icon: Video, accept: "video/*", accentColor: "#4DA6FF" },
|
||||||
|
{ id: "models", path: "models", label: "3D Models", description: "GLB/USDZ for AR viewer and 3D display", icon: Box, accept: ".glb,.gltf,.usdz", accentColor: "#A855F7" },
|
||||||
{ id: "renders", path: "renders", label: "Renders", description: "3D rendered images of the equipment", icon: Box, accept: "image/*", accentColor: "#FF6B9D" },
|
{ id: "renders", path: "renders", label: "Renders", description: "3D rendered images of the equipment", icon: Box, accept: "image/*", accentColor: "#FF6B9D" },
|
||||||
],
|
],
|
||||||
applications: [
|
applications: [
|
||||||
@@ -88,7 +89,8 @@ function bucketHint(bucket: BucketDef, fileName: string): string | null {
|
|||||||
const isModel = ["glb", "gltf", "usdz"].includes(ext);
|
const isModel = ["glb", "gltf", "usdz"].includes(ext);
|
||||||
if (bucket.id === "videos" && !isVideo) return "Videos bucket usually holds .mp4 — this file may not display correctly.";
|
if (bucket.id === "videos" && !isVideo) return "Videos bucket usually holds .mp4 — this file may not display correctly.";
|
||||||
if (bucket.id === "renders" && !isImage) return "Renders bucket expects images (PNG/JPG/WebP).";
|
if (bucket.id === "renders" && !isImage) return "Renders bucket expects images (PNG/JPG/WebP).";
|
||||||
if (bucket.id === "media" && !isImage && !isVideo && !isModel) return "Most pages expect images, videos or 3D model files here.";
|
if (bucket.id === "models" && !isModel) return "Models bucket expects 3D files (.glb, .gltf, .usdz).";
|
||||||
|
if (bucket.id === "media" && !isImage && !isVideo) return "Media bucket expects images or videos here.";
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user