@tnkrai/tnkr-editor 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -74793,7 +74793,9 @@ const PartContextMenu = ({ contextMenu, onClose, onHighlight, onRemoveHighlight,
74793
74793
 
74794
74794
  const TnkrEditorModelViewCore = ({ htmlString, className, style, onElementsReady,
74795
74795
  // Accept all dependencies as props instead of using hooks
74796
- parts, phases = [], selectedPhaseId, selectedStepId, selectStep, isAnimating = false, isPreparingAnimation = false, setIsAnimating, setIsPreparingAnimation, }) => {
74796
+ parts, phases = [], selectedPhaseId, selectedStepId, selectStep, isAnimating = false, isPreparingAnimation = false, setIsAnimating, setIsPreparingAnimation,
74797
+ // Navigation handlers from parent
74798
+ handleNext: parentHandleNext, handlePrevious: parentHandlePrevious, }) => {
74797
74799
  // Use the hook with parts passed as parameter
74798
74800
  const { containerRef, scriptsLoaded, initializeModel, controlFunctions, partOperations, handleShowAllParts, updateExplosion, updateDirectionalExplosion, setCameraSettings, contextMenu, setContextMenu, handleContextMenuHighlight, handleContextMenuRemoveHighlight, handleContextMenuHide, handleContextMenuShow, handleContextMenuIsolate, isPartHighlighted, isPartHidden, isPartIsolated, } = useModelViewCore(parts);
74799
74801
  const [lastStepId, setLastStepId] = React.useState(null);
@@ -74844,31 +74846,49 @@ parts, phases = [], selectedPhaseId, selectedStepId, selectStep, isAnimating = f
74844
74846
  });
74845
74847
  return allSteps;
74846
74848
  }, [phases]);
74847
- // Navigation handlers - work across all phases
74849
+ // Use parent navigation handlers if provided, otherwise create local ones as fallback
74848
74850
  const handlePrevious = React.useCallback(() => {
74849
- if (!selectStep || !selectedPhaseId || !selectedStepId)
74850
- return;
74851
- if (isAnimatingRef.current || isPreparingRef.current)
74852
- return;
74853
- const allSteps = getAllSteps();
74854
- const currentIndex = allSteps.findIndex((s) => s.phaseId === selectedPhaseId && s.stepId === selectedStepId);
74855
- if (currentIndex > 0) {
74856
- const prevStep = allSteps[currentIndex - 1];
74857
- selectStep(prevStep.phaseId, prevStep.stepId);
74851
+ if (parentHandlePrevious) {
74852
+ // Check animation state before calling parent handler
74853
+ if (isAnimatingRef.current || isPreparingRef.current)
74854
+ return;
74855
+ parentHandlePrevious();
74858
74856
  }
74859
- }, [selectStep, selectedPhaseId, selectedStepId, getAllSteps]);
74857
+ else {
74858
+ // Fallback to local implementation for backward compatibility
74859
+ if (!selectStep || !selectedPhaseId || !selectedStepId)
74860
+ return;
74861
+ if (isAnimatingRef.current || isPreparingRef.current)
74862
+ return;
74863
+ const allSteps = getAllSteps();
74864
+ const currentIndex = allSteps.findIndex((s) => s.phaseId === selectedPhaseId && s.stepId === selectedStepId);
74865
+ if (currentIndex > 0) {
74866
+ const prevStep = allSteps[currentIndex - 1];
74867
+ selectStep(prevStep.phaseId, prevStep.stepId);
74868
+ }
74869
+ }
74870
+ }, [parentHandlePrevious, selectStep, selectedPhaseId, selectedStepId, getAllSteps]);
74860
74871
  const handleNext = React.useCallback(() => {
74861
- if (!selectStep || !selectedPhaseId || !selectedStepId)
74862
- return;
74863
- if (isAnimatingRef.current || isPreparingRef.current)
74864
- return;
74865
- const allSteps = getAllSteps();
74866
- const currentIndex = allSteps.findIndex((s) => s.phaseId === selectedPhaseId && s.stepId === selectedStepId);
74867
- if (currentIndex >= 0 && currentIndex < allSteps.length - 1) {
74868
- const nextStep = allSteps[currentIndex + 1];
74869
- selectStep(nextStep.phaseId, nextStep.stepId);
74872
+ if (parentHandleNext) {
74873
+ // Check animation state before calling parent handler
74874
+ if (isAnimatingRef.current || isPreparingRef.current)
74875
+ return;
74876
+ parentHandleNext();
74877
+ }
74878
+ else {
74879
+ // Fallback to local implementation for backward compatibility
74880
+ if (!selectStep || !selectedPhaseId || !selectedStepId)
74881
+ return;
74882
+ if (isAnimatingRef.current || isPreparingRef.current)
74883
+ return;
74884
+ const allSteps = getAllSteps();
74885
+ const currentIndex = allSteps.findIndex((s) => s.phaseId === selectedPhaseId && s.stepId === selectedStepId);
74886
+ if (currentIndex >= 0 && currentIndex < allSteps.length - 1) {
74887
+ const nextStep = allSteps[currentIndex + 1];
74888
+ selectStep(nextStep.phaseId, nextStep.stepId);
74889
+ }
74870
74890
  }
74871
- }, [selectStep, selectedPhaseId, selectedStepId, getAllSteps]);
74891
+ }, [parentHandleNext, selectStep, selectedPhaseId, selectedStepId, getAllSteps]);
74872
74892
  // Keep refs in sync with state
74873
74893
  React.useEffect(() => {
74874
74894
  isAnimatingRef.current = isAnimating;
@@ -75329,8 +75349,7 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75329
75349
  finalX = dragPositionRef.current[annotation.id].x;
75330
75350
  finalY = dragPositionRef.current[annotation.id].y;
75331
75351
  }
75332
- else if (annotation.customOffset &&
75333
- !(annotation.customOffset.x === 0 && annotation.customOffset.y === 0)) {
75352
+ else if (annotation.customOffset && !(annotation.customOffset.x === 0 && annotation.customOffset.y === 0)) {
75334
75353
  // Use custom offset if dragged - but ignore (0,0) which means no real offset
75335
75354
  finalX = canvasPos[0] + annotation.customOffset.x;
75336
75355
  finalY = canvasPos[1] + annotation.customOffset.y;
@@ -75424,7 +75443,7 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75424
75443
  if (hitPoint && hitPoint.length >= 3) {
75425
75444
  const newAnnotation = Object.assign(Object.assign({}, currentAnnotation), { worldPos: [hitPoint[0], hitPoint[1], hitPoint[2]] });
75426
75445
  // Add to annotations list
75427
- setAnnotations(prev => {
75446
+ setAnnotations((prev) => {
75428
75447
  const updated = [...prev, newAnnotation];
75429
75448
  return updated;
75430
75449
  });
@@ -75437,7 +75456,14 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75437
75456
  updateAnnotationPositions();
75438
75457
  }, 100);
75439
75458
  }
75440
- }, [isPlacingAnnotation, currentAnnotation, updateAnnotationPositions, setAnnotations, setCurrentAnnotation, setIsPlacingAnnotation]);
75459
+ }, [
75460
+ isPlacingAnnotation,
75461
+ currentAnnotation,
75462
+ updateAnnotationPositions,
75463
+ setAnnotations,
75464
+ setCurrentAnnotation,
75465
+ setIsPlacingAnnotation,
75466
+ ]);
75441
75467
  // Set up enterFrame callback for position updates with better performance
75442
75468
  React.useEffect(() => {
75443
75469
  if (!runtimeRef.current || annotations.length === 0)
@@ -75521,14 +75547,27 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75521
75547
  return;
75522
75548
  e.preventDefault();
75523
75549
  e.stopPropagation();
75524
- const rect = e.currentTarget.getBoundingClientRect();
75525
75550
  const containerRect = (_a = overlayRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
75526
75551
  if (!containerRect)
75527
75552
  return;
75553
+ // Get the annotation element's current position from the DOM
75554
+ const element = document.getElementById(`assembly-annotation-${annotationId}`);
75555
+ if (!element)
75556
+ return;
75557
+ // Get the actual current position from the element's style (this is where it's visually positioned)
75558
+ const currentLeft = parseFloat(element.style.left) || 0;
75559
+ const currentTop = parseFloat(element.style.top) || 0;
75560
+ // Store the exact current position to prevent any jump
75561
+ dragPositionRef.current[annotationId] = {
75562
+ x: currentLeft,
75563
+ y: currentTop,
75564
+ };
75528
75565
  setIsDragging(annotationId);
75566
+ // Calculate offset from mouse to the element's current position
75567
+ // This maintains the grab point during dragging
75529
75568
  setDragOffset({
75530
- x: e.clientX - rect.left,
75531
- y: e.clientY - rect.top,
75569
+ x: e.clientX - containerRect.left - currentLeft,
75570
+ y: e.clientY - containerRect.top - currentTop,
75532
75571
  });
75533
75572
  // Notify parent that drag started
75534
75573
  onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart();
@@ -75545,7 +75584,7 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75545
75584
  const canvasPos = runtimeRef.current.calcCanvasPos(x, y, z);
75546
75585
  if (!canvasPos)
75547
75586
  return;
75548
- // Calculate new position with drag offset
75587
+ // Calculate new position: mouse position minus the offset gives us where the center should be
75549
75588
  const newX = e.clientX - containerRect.left - dragOffset.x;
75550
75589
  const newY = e.clientY - containerRect.top - dragOffset.y;
75551
75590
  // Calculate offset from 3D anchor point
@@ -75585,7 +75624,7 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75585
75624
  if (updatedAnnotation) {
75586
75625
  console.log('💾 Flushing pending update for annotation', updatedAnnotation.id, {
75587
75626
  customOffset: updatedAnnotation.customOffset,
75588
- scale: updatedAnnotation.scale
75627
+ scale: updatedAnnotation.scale,
75589
75628
  });
75590
75629
  // Update state with final position
75591
75630
  setAnnotations((prev) => prev.map((annotation) => (annotation.id === updatedAnnotation.id ? updatedAnnotation : annotation)));
@@ -75713,7 +75752,9 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75713
75752
  return null;
75714
75753
  }
75715
75754
  };
75716
- return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("svg", { className: 'absolute inset-0 w-full h-full pointer-events-none z-10 opacity-100 transition-opacity duration-300 ease-in-out', children: [jsxRuntimeExports.jsx("defs", { children: annotations.filter(a => a.type === 'arrow' && a.arrow).map((annotation) => {
75755
+ return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("svg", { className: 'absolute inset-0 w-full h-full pointer-events-none z-10 opacity-100 transition-opacity duration-300 ease-in-out', children: [jsxRuntimeExports.jsx("defs", { children: annotations
75756
+ .filter((a) => a.type === 'arrow' && a.arrow)
75757
+ .map((annotation) => {
75717
75758
  const lineColor = getColorCode(annotation.arrow.color);
75718
75759
  const uniqueId = annotation.id;
75719
75760
  return (jsxRuntimeExports.jsxs(React__namespace.default.Fragment, { children: [jsxRuntimeExports.jsx("marker", { id: `point-fill-${uniqueId}`, markerWidth: '10', markerHeight: '10', refX: '9', refY: '3', orient: 'auto', children: jsxRuntimeExports.jsx("polygon", { points: '0 0, 10 3, 0 6', fill: lineColor }) }), jsxRuntimeExports.jsx("marker", { id: `pointFill-${uniqueId}`, markerWidth: '10', markerHeight: '10', refX: '9', refY: '3', orient: 'auto', children: jsxRuntimeExports.jsx("polygon", { points: '0 0, 10 3, 0 6', fill: lineColor }) }), jsxRuntimeExports.jsx("marker", { id: `point-outline-${uniqueId}`, markerWidth: '10', markerHeight: '10', refX: '9', refY: '3', orient: 'auto', children: jsxRuntimeExports.jsx("polygon", { points: '0 0, 10 3, 0 6', fill: 'none', stroke: lineColor, strokeWidth: '1' }) }), jsxRuntimeExports.jsx("marker", { id: `pointOutline-${uniqueId}`, markerWidth: '10', markerHeight: '10', refX: '9', refY: '3', orient: 'auto', children: jsxRuntimeExports.jsx("polygon", { points: '0 0, 10 3, 0 6', fill: 'none', stroke: lineColor, strokeWidth: '1' }) }), jsxRuntimeExports.jsx("marker", { id: `inverse-point-${uniqueId}`, markerWidth: '10', markerHeight: '10', refX: '1', refY: '3', orient: 'auto', children: jsxRuntimeExports.jsx("polygon", { points: '10 0, 0 3, 10 6', fill: lineColor }) }), jsxRuntimeExports.jsx("marker", { id: `inversePointFill-${uniqueId}`, markerWidth: '10', markerHeight: '10', refX: '1', refY: '3', orient: 'auto', children: jsxRuntimeExports.jsx("polygon", { points: '10 0, 0 3, 10 6', fill: lineColor }) }), jsxRuntimeExports.jsx("marker", { id: `diamond-${uniqueId}`, markerWidth: '10', markerHeight: '10', refX: '5', refY: '5', orient: 'auto', children: jsxRuntimeExports.jsx("polygon", { points: '5 1, 9 5, 5 9, 1 5', fill: lineColor }) }), jsxRuntimeExports.jsx("marker", { id: `dot-${uniqueId}`, markerWidth: '8', markerHeight: '8', refX: '4', refY: '4', orient: 'auto', children: jsxRuntimeExports.jsx("circle", { cx: '4', cy: '4', r: '3', fill: lineColor }) }), jsxRuntimeExports.jsx("marker", { id: `dotFill-${uniqueId}`, markerWidth: '8', markerHeight: '8', refX: '4', refY: '4', orient: 'auto', children: jsxRuntimeExports.jsx("circle", { cx: '4', cy: '4', r: '3', fill: lineColor }) }), jsxRuntimeExports.jsx("marker", { id: `joint-${uniqueId}`, markerWidth: '8', markerHeight: '8', refX: '4', refY: '4', orient: 'auto', children: jsxRuntimeExports.jsx("circle", { cx: '4', cy: '4', r: '2', fill: 'none', stroke: lineColor, strokeWidth: '1' }) })] }, `markers-${uniqueId}`));
@@ -75747,8 +75788,8 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75747
75788
  const deltaY = pos.endY - pos.startY;
75748
75789
  // Calculate bend point (70% along the path with 10° offset for 100° angle)
75749
75790
  const bendRatio = 0.7; // How far along to place the bend
75750
- const midX = pos.startX + (deltaX * bendRatio);
75751
- const midY = pos.startY + (deltaY * bendRatio) + (deltaX * 0.1); // 10° offset for 100° angle
75791
+ const midX = pos.startX + deltaX * bendRatio;
75792
+ const midY = pos.startY + deltaY * bendRatio + deltaX * 0.1; // 10° offset for 100° angle
75752
75793
  const pathData = `M ${pos.startX} ${pos.startY} L ${midX} ${midY} L ${pos.endX} ${pos.endY}`;
75753
75794
  pathElement = (jsxRuntimeExports.jsx("path", { d: pathData, stroke: lineColor, strokeWidth: lineThickness, fill: 'none', markerStart: markerStart, markerEnd: markerEnd, opacity: '0.9', strokeLinecap: 'round', strokeLinejoin: 'round' }));
75754
75795
  }
@@ -75790,7 +75831,7 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75790
75831
  // Check if this annotation should be visible
75791
75832
  const isVisible = visibleAnnotationIds.includes(annotation.id);
75792
75833
  const ContainerClasses = `
75793
- ${annotation.type === 'label' ? 'transform -translate-x-1/2 -translate-y-full' : ''} ${isSelected ? 'ring-1 ring-blue-400' : isDragging === annotation.id ? 'opacity-70 ring-1 ring-red-400' : ''} ${!isVisible ? 'invisible' : ''}
75834
+ ${annotation.type === 'label' ? 'transform -translate-x-1/2 -translate-y-1/2' : ''} ${isSelected ? 'ring-1 ring-blue-400' : isDragging === annotation.id ? 'opacity-70 ring-1 ring-red-400' : ''} ${!isVisible ? 'invisible' : ''}
75794
75835
  `;
75795
75836
  const TextAreaClasses = `
75796
75837
  absolute top-1/2 -translate-y-1/2 ${fontFamilyClass} text-${annotation.align}
@@ -75833,17 +75874,17 @@ function AssemblyAnnotationOverlay({ annotations, setAnnotations, currentAnnotat
75833
75874
  return (jsxRuntimeExports.jsxs("div", { id: `assembly-annotation-${annotation.id}`, className: cn('w-max relative text-xs pointer-events-auto cursor-pointer flex items-center transition-all', ContainerClasses), onDoubleClick: handleDoubleClick, onMouseDown: handleSelect, children: [jsxRuntimeExports.jsx("div", { style: { height: scale, width: scale }, children: jsxRuntimeExports.jsx(ShapeSVG, { annotation: annotation }) }), jsxRuntimeExports.jsx(Textarea, { rows: 1, value: canContainText ? annotation.text.value : '', placeholder: canContainText ? 'Add Text' : '', readOnly: !canContainText || editingAnnotation !== annotation.id, className: cn(`absolute resize-none bg-transparent cursor-pointer leading-tight w-full !border-none !outline-none !ring-0 z-[2]`, TextAreaClasses), style: {
75834
75875
  color: textColor,
75835
75876
  fontSize: `${textSize}px`,
75836
- minHeight: `${textSize}px`
75877
+ minHeight: `${textSize}px`,
75837
75878
  }, autoFocus: editingAnnotation === annotation.id && canContainText, onChange: (e) => {
75838
75879
  // Update the annotation text immediately on change
75839
75880
  if (editingAnnotation === annotation.id) {
75840
75881
  // Find the current annotation with all its properties
75841
- const currentAnn = annotations.find(a => a.id === annotation.id);
75882
+ const currentAnn = annotations.find((a) => a.id === annotation.id);
75842
75883
  if (!currentAnn)
75843
75884
  return;
75844
75885
  const updatedAnnotation = Object.assign(Object.assign({}, currentAnn), { text: Object.assign(Object.assign({}, currentAnn.text), { value: e.target.value }) });
75845
75886
  // Update annotations array
75846
- setAnnotations((prev) => prev.map((a) => a.id === annotation.id ? updatedAnnotation : a));
75887
+ setAnnotations((prev) => prev.map((a) => (a.id === annotation.id ? updatedAnnotation : a)));
75847
75888
  // Also update currentAnnotation if this is the currently selected annotation
75848
75889
  if ((currentAnnotation === null || currentAnnotation === void 0 ? void 0 : currentAnnotation.id) === annotation.id) {
75849
75890
  setCurrentAnnotation(updatedAnnotation);
@@ -75956,11 +75997,41 @@ const Tag = ({ text, className = '' }) => {
75956
75997
  const backgroundColor = getColor(text);
75957
75998
  return (jsxRuntimeExports.jsx("span", { className: `px-3 py-1.5 rounded-md text-sm font-medium text-white ${className}`, style: { backgroundColor }, children: text }));
75958
75999
  };
75959
- const AssemblyViewMode = ({ phases, htmlContent, className = '', productTitle, parts, organizationId, productId, editMode = false, onUploadImage, onPhasesUpdate, }) => {
76000
+ const AssemblyViewMode = ({ phases, htmlContent, className = '', productTitle, parts, organizationId, productId, editMode = false, onUploadImage, onPhasesUpdate, routePhaseId, routeStepId, onAssemblyChange, }) => {
75960
76001
  var _a;
75961
- const [currentPhaseIndex, setCurrentPhaseIndex] = React.useState(0);
75962
- const [currentStepIndex, setCurrentStepIndex] = React.useState(0);
75963
- const [currentView, setCurrentView] = React.useState('overview');
76002
+ // Initialize state based on route props
76003
+ const getInitialPhaseIndex = () => {
76004
+ if (routePhaseId) {
76005
+ const index = phases.findIndex(p => p.id === routePhaseId);
76006
+ return index >= 0 ? index : 0;
76007
+ }
76008
+ return 0;
76009
+ };
76010
+ const getInitialStepIndex = () => {
76011
+ if (routePhaseId && routeStepId) {
76012
+ const phaseIndex = phases.findIndex(p => p.id === routePhaseId);
76013
+ if (phaseIndex >= 0) {
76014
+ const stepIndex = phases[phaseIndex].steps.findIndex(s => s.id === routeStepId);
76015
+ return stepIndex >= 0 ? stepIndex : 0;
76016
+ }
76017
+ }
76018
+ return 0;
76019
+ };
76020
+ const getInitialView = () => {
76021
+ if (routePhaseId && routeStepId) {
76022
+ const phaseIndex = phases.findIndex(p => p.id === routePhaseId);
76023
+ if (phaseIndex >= 0) {
76024
+ const stepIndex = phases[phaseIndex].steps.findIndex(s => s.id === routeStepId);
76025
+ if (stepIndex >= 0) {
76026
+ return 'step';
76027
+ }
76028
+ }
76029
+ }
76030
+ return 'overview';
76031
+ };
76032
+ const [currentPhaseIndex, setCurrentPhaseIndex] = React.useState(getInitialPhaseIndex);
76033
+ const [currentStepIndex, setCurrentStepIndex] = React.useState(getInitialStepIndex);
76034
+ const [currentView, setCurrentView] = React.useState(getInitialView);
75964
76035
  const [isAnimating, setIsAnimating] = React.useState(false);
75965
76036
  const [isPreparingAnimation, setIsPreparingAnimation] = React.useState(false);
75966
76037
  const containerRef = React__namespace.default.useRef(null);
@@ -76301,16 +76372,40 @@ const AssemblyViewMode = ({ phases, htmlContent, className = '', productTitle, p
76301
76372
  // Trigger debounced save for step description
76302
76373
  debouncedSave(stepId, content, 'step-description');
76303
76374
  }, [debouncedSave]);
76304
- // Load annotations when step changes - same logic as Editor3D
76305
- React__namespace.default.useEffect(() => {
76375
+ // Load annotations when step changes - same logic as Editor3D with migration
76376
+ React.useEffect(() => {
76306
76377
  // Only update if the step ID actually changed
76307
76378
  if (prevStepIdRef.current !== (currentStep === null || currentStep === void 0 ? void 0 : currentStep.id)) {
76308
76379
  prevStepIdRef.current = (currentStep === null || currentStep === void 0 ? void 0 : currentStep.id) || null;
76309
- const stepAnnotations = (currentStep === null || currentStep === void 0 ? void 0 : currentStep.annotations) || [];
76310
- setAssemblyAnnotations(stepAnnotations);
76380
+ if (currentStep === null || currentStep === void 0 ? void 0 : currentStep.annotations) {
76381
+ // MIGRATION LOGIC: Convert old pulse format to new format
76382
+ // Background: In commit 8e30c8a, pulse structure was changed from:
76383
+ // arrow.endPulse (boolean) and arrow.pulseColor (ColorLabel)
76384
+ // to:
76385
+ // pulse: { show: boolean, color: ColorLabel }
76386
+ // This migration ensures existing annotations don't lose their pulse settings
76387
+ const migratedAnnotations = currentStep.annotations.map((annotation) => {
76388
+ var _a;
76389
+ // Check if annotation has old pulse format but no new pulse property
76390
+ if (((_a = annotation.arrow) === null || _a === void 0 ? void 0 : _a.endPulse) && !annotation.pulse) {
76391
+ return Object.assign(Object.assign({}, annotation), { pulse: {
76392
+ show: annotation.arrow.endPulse,
76393
+ color: annotation.arrow.pulseColor || 'pulse orange'
76394
+ },
76395
+ // Clean up old properties from arrow object
76396
+ arrow: Object.assign(Object.assign({}, annotation.arrow), { endPulse: undefined, pulseColor: undefined }) });
76397
+ }
76398
+ // Return annotation as-is if already migrated or doesn't need migration
76399
+ return annotation;
76400
+ });
76401
+ setAssemblyAnnotations(migratedAnnotations);
76402
+ console.log('📝 View mode annotations loaded and migrated for step:', currentStep === null || currentStep === void 0 ? void 0 : currentStep.id, 'count:', migratedAnnotations.length);
76403
+ }
76404
+ else {
76405
+ setAssemblyAnnotations([]);
76406
+ }
76311
76407
  // Reset visible annotations (default to all hidden in view mode)
76312
76408
  setVisibleAnnotationIds([]);
76313
- console.log('📝 View mode annotations loaded for step:', currentStep === null || currentStep === void 0 ? void 0 : currentStep.id, 'count:', stepAnnotations.length);
76314
76409
  }
76315
76410
  }, [currentStep === null || currentStep === void 0 ? void 0 : currentStep.id, currentStep]);
76316
76411
  // Navigation functions
@@ -76327,33 +76422,115 @@ const AssemblyViewMode = ({ phases, htmlContent, className = '', productTitle, p
76327
76422
  }
76328
76423
  return false;
76329
76424
  }, [currentPhase, currentStepIndex, currentPhaseIndex, phases]);
76425
+ const canGoPrevious = React.useMemo(() => {
76426
+ if (!currentPhase)
76427
+ return false;
76428
+ // If not at first step of current phase, can go previous
76429
+ if (currentStepIndex > 0)
76430
+ return true;
76431
+ // If at first step of current phase, check if there's a previous phase with steps
76432
+ if (currentPhaseIndex > 0) {
76433
+ const previousPhase = phases[currentPhaseIndex - 1];
76434
+ return previousPhase.steps.length > 0;
76435
+ }
76436
+ return false;
76437
+ }, [currentPhase, currentStepIndex, currentPhaseIndex, phases]);
76330
76438
  const handleNext = () => {
76439
+ var _a, _b, _c;
76331
76440
  if (!currentPhase)
76332
76441
  return;
76442
+ let newPhaseIndex = currentPhaseIndex;
76443
+ let newStepIndex = currentStepIndex;
76333
76444
  if (currentStepIndex < currentPhase.steps.length - 1) {
76334
- setCurrentStepIndex(currentStepIndex + 1);
76445
+ newStepIndex = currentStepIndex + 1;
76446
+ setCurrentStepIndex(newStepIndex);
76335
76447
  }
76336
76448
  else if (currentPhaseIndex < phases.length - 1) {
76337
76449
  const nextPhaseIndex = currentPhaseIndex + 1;
76338
76450
  const nextPhase = phases[nextPhaseIndex];
76339
76451
  if (nextPhase.steps.length > 0) {
76340
- setCurrentPhaseIndex(nextPhaseIndex);
76341
- setCurrentStepIndex(0);
76452
+ newPhaseIndex = nextPhaseIndex;
76453
+ newStepIndex = 0;
76454
+ setCurrentPhaseIndex(newPhaseIndex);
76455
+ setCurrentStepIndex(newStepIndex);
76456
+ }
76457
+ }
76458
+ // Call onAssemblyChange if provided
76459
+ if (onAssemblyChange) {
76460
+ const phaseId = (_a = phases[newPhaseIndex]) === null || _a === void 0 ? void 0 : _a.id;
76461
+ const stepId = currentView === 'step' ? (_c = (_b = phases[newPhaseIndex]) === null || _b === void 0 ? void 0 : _b.steps[newStepIndex]) === null || _c === void 0 ? void 0 : _c.id : undefined;
76462
+ if (phaseId) {
76463
+ onAssemblyChange(phaseId, stepId);
76464
+ }
76465
+ }
76466
+ };
76467
+ const handlePrevious = () => {
76468
+ var _a, _b, _c;
76469
+ if (!currentPhase)
76470
+ return;
76471
+ let newPhaseIndex = currentPhaseIndex;
76472
+ let newStepIndex = currentStepIndex;
76473
+ if (currentStepIndex > 0) {
76474
+ newStepIndex = currentStepIndex - 1;
76475
+ setCurrentStepIndex(newStepIndex);
76476
+ }
76477
+ else if (currentPhaseIndex > 0) {
76478
+ const previousPhaseIndex = currentPhaseIndex - 1;
76479
+ const previousPhase = phases[previousPhaseIndex];
76480
+ if (previousPhase.steps.length > 0) {
76481
+ newPhaseIndex = previousPhaseIndex;
76482
+ newStepIndex = previousPhase.steps.length - 1;
76483
+ setCurrentPhaseIndex(newPhaseIndex);
76484
+ setCurrentStepIndex(newStepIndex);
76485
+ }
76486
+ }
76487
+ // Call onAssemblyChange if provided
76488
+ if (onAssemblyChange) {
76489
+ const phaseId = (_a = phases[newPhaseIndex]) === null || _a === void 0 ? void 0 : _a.id;
76490
+ const stepId = currentView === 'step' ? (_c = (_b = phases[newPhaseIndex]) === null || _b === void 0 ? void 0 : _b.steps[newStepIndex]) === null || _c === void 0 ? void 0 : _c.id : undefined;
76491
+ if (phaseId) {
76492
+ onAssemblyChange(phaseId, stepId);
76342
76493
  }
76343
76494
  }
76344
76495
  };
76345
76496
  const handlePhaseChange = (phaseIndex) => {
76497
+ var _a;
76346
76498
  setCurrentPhaseIndex(phaseIndex);
76347
76499
  setCurrentStepIndex(0);
76348
76500
  setCurrentView('overview');
76501
+ // Call onAssemblyChange if provided
76502
+ if (onAssemblyChange) {
76503
+ const phaseId = (_a = phases[phaseIndex]) === null || _a === void 0 ? void 0 : _a.id;
76504
+ if (phaseId) {
76505
+ onAssemblyChange(phaseId, undefined); // No stepId in overview mode
76506
+ }
76507
+ }
76349
76508
  };
76350
76509
  const handleStepClick = (stepIndex) => {
76510
+ var _a;
76351
76511
  setCurrentStepIndex(stepIndex);
76352
76512
  setCurrentView('step');
76513
+ // Call onAssemblyChange if provided
76514
+ if (onAssemblyChange) {
76515
+ const phaseId = currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.id;
76516
+ const stepId = (_a = currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps[stepIndex]) === null || _a === void 0 ? void 0 : _a.id;
76517
+ if (phaseId) {
76518
+ onAssemblyChange(phaseId, stepId);
76519
+ }
76520
+ }
76353
76521
  };
76354
76522
  const handleBeginPhase = () => {
76523
+ var _a;
76355
76524
  setCurrentStepIndex(0);
76356
76525
  setCurrentView('step');
76526
+ // Call onAssemblyChange if provided
76527
+ if (onAssemblyChange) {
76528
+ const phaseId = currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.id;
76529
+ const stepId = (_a = currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps[0]) === null || _a === void 0 ? void 0 : _a.id;
76530
+ if (phaseId) {
76531
+ onAssemblyChange(phaseId, stepId);
76532
+ }
76533
+ }
76357
76534
  };
76358
76535
  const handleToggleAnnotation = (annotationId) => {
76359
76536
  // Note: Camera settings functionality would require additional props if needed
@@ -76427,7 +76604,7 @@ const AssemblyViewMode = ({ phases, htmlContent, className = '', productTitle, p
76427
76604
  if (phases.length === 0) {
76428
76605
  return (jsxRuntimeExports.jsx("div", { className: `flex items-center justify-center h-full ${className}`, children: jsxRuntimeExports.jsxs("div", { className: 'text-center text-white/60 space-y-2', children: [jsxRuntimeExports.jsx("p", { className: 'text-lg', children: "No assembly phases available" }), jsxRuntimeExports.jsx("p", { className: 'text-sm', children: "Import assembly instructions to get started" })] }) }));
76429
76606
  }
76430
- return (jsxRuntimeExports.jsx("div", { className: `assembly-view-container w-full h-full relative rounded-3xl bg-[#161617] ${className}`, children: jsxRuntimeExports.jsxs("div", { className: 'grid grid-cols-1 lg:grid-cols-5 gap-4 px-4 py-4 items-stretch', children: [jsxRuntimeExports.jsxs("div", { className: 'lg:col-span-3 flex flex-col w-full relative bg-transparent border rounded-3xl border-[#313133]', children: [jsxRuntimeExports.jsxs("div", { className: 'rounded-lg p-6 flex-shrink-0', children: [jsxRuntimeExports.jsxs("div", { className: 'flex items-center justify-between mb-4', children: [jsxRuntimeExports.jsxs("div", { className: 'text-sm text-white/70', children: [productTitle, " Assembly"] }), jsxRuntimeExports.jsxs("div", { className: 'text-sm text-white/70', children: [completedStepsInCurrentPhase, "/", totalStepsInCurrentPhase, " Complete"] })] }), jsxRuntimeExports.jsx("div", { className: 'space-y-2', children: jsxRuntimeExports.jsx("div", { className: 'flex space-x-1', children: currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps.map((_, index) => (jsxRuntimeExports.jsx("div", { className: `h-1 rounded-sm flex-1 transition-all duration-300 ${index < completedStepsInCurrentPhase ? 'bg-white' : 'bg-[#313133]'}` }, index))) }) })] }), jsxRuntimeExports.jsxs("div", { ref: containerRef, className: 'w-full relative flex-1 min-h-[400px]', style: { backgroundColor: 'transparent' }, children: [currentView === 'step' && assemblyAnnotations.length > 0 && (jsxRuntimeExports.jsx("div", { className: 'absolute right-[4.5rem] z-20', children: jsxRuntimeExports.jsxs(DropdownMenu, { children: [jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: jsxRuntimeExports.jsxs(Button, { variant: 'outline', size: 'sm', className: 'flex items-center gap-2 px-3 py-1.5', children: [jsxRuntimeExports.jsxs("div", { className: 'relative', children: [jsxRuntimeExports.jsx(CiBellOn, { className: 'size-5 stroke-[0.7] text-[#AA423A]' }), jsxRuntimeExports.jsx("p", { className: 'absolute top-0 right-0 rounded-full text-[7px] bg-[#AA423A] text-white size-2.5 text-center', children: assemblyAnnotations.length })] }), "Annotations", jsxRuntimeExports.jsx(react$2.Icon, { icon: 'ph:caret-down', className: 'w-3 h-3 ml-1' })] }) }), jsxRuntimeExports.jsxs(DropdownMenuContent, { align: 'end', className: 'bg-[#232326] border-gray-700 min-w-[200px]', children: [jsxRuntimeExports.jsx(DropdownMenuLabel, { className: 'text-gray-400 text-xs', children: "Annotation Controls" }), jsxRuntimeExports.jsx(DropdownMenuSeparator, { className: 'bg-gray-700' }), jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: () => setVisibleAnnotationIds(assemblyAnnotations.map((a) => a.id)), className: 'text-white hover:bg-gray-800 cursor-pointer', children: [jsxRuntimeExports.jsx(react$2.Icon, { icon: 'ph:eye', className: 'w-4 h-4 mr-2' }), "Show All Annotations"] }), jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: () => setVisibleAnnotationIds([]), className: 'text-white hover:bg-gray-800 cursor-pointer', children: [jsxRuntimeExports.jsx(react$2.Icon, { icon: 'ph:eye-slash', className: 'w-4 h-4 mr-2' }), "Hide All Annotations"] }), jsxRuntimeExports.jsx(DropdownMenuSeparator, { className: 'bg-gray-700' }), jsxRuntimeExports.jsx(DropdownMenuLabel, { className: 'text-gray-400 text-xs', children: "Individual Annotations" }), assemblyAnnotations.map((annotation, index) => {
76607
+ return (jsxRuntimeExports.jsx("div", { className: `h-full max-h-screen w-full relative bg-[#161617] rounded-3xl ${className}`, children: jsxRuntimeExports.jsxs("div", { className: 'grid grid-cols-1 lg:grid-cols-5 gap-4 px-4 py-4 h-full', children: [jsxRuntimeExports.jsxs("div", { className: 'lg:col-span-3 flex flex-col w-full h-full relative bg-transparent border rounded-3xl border-[#313133] min-h-0', children: [jsxRuntimeExports.jsxs("div", { className: 'rounded-lg py-6 px-18 flex-shrink-0 h-[120px] flex flex-col justify-end', children: [jsxRuntimeExports.jsxs("div", { className: 'flex items-center justify-between mb-4', children: [jsxRuntimeExports.jsxs("div", { className: 'text-sm text-white/70', children: [productTitle, " Assembly"] }), jsxRuntimeExports.jsxs("div", { className: 'text-sm text-white/70', children: [completedStepsInCurrentPhase, "/", totalStepsInCurrentPhase, " Complete"] })] }), jsxRuntimeExports.jsx("div", { className: 'flex space-x-1', children: currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps.map((_, index) => (jsxRuntimeExports.jsx("div", { className: `h-1 rounded-sm flex-1 transition-all duration-300 ${index < completedStepsInCurrentPhase ? 'bg-white' : 'bg-[#313133]'}` }, index))) })] }), jsxRuntimeExports.jsxs("div", { ref: containerRef, className: 'w-full relative flex-1 min-h-[400px]', style: { backgroundColor: 'transparent' }, children: [currentView === 'step' && assemblyAnnotations.length > 0 && (jsxRuntimeExports.jsx("div", { className: 'absolute right-[4.5rem] z-20', children: jsxRuntimeExports.jsxs(DropdownMenu, { children: [jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: jsxRuntimeExports.jsxs(Button, { variant: 'outline', size: 'sm', className: 'flex items-center gap-2 px-3 py-1.5', children: [jsxRuntimeExports.jsxs("div", { className: 'relative', children: [jsxRuntimeExports.jsx(CiBellOn, { className: 'size-5 stroke-[0.7] text-[#AA423A]' }), jsxRuntimeExports.jsx("p", { className: 'absolute top-0 right-0 rounded-full text-[7px] bg-[#AA423A] text-white size-2.5 text-center', children: assemblyAnnotations.length })] }), "Annotations", jsxRuntimeExports.jsx(react$2.Icon, { icon: 'ph:caret-down', className: 'w-3 h-3 ml-1' })] }) }), jsxRuntimeExports.jsxs(DropdownMenuContent, { align: 'end', className: 'bg-[#232326] border-gray-700 min-w-[200px]', children: [jsxRuntimeExports.jsx(DropdownMenuLabel, { className: 'text-gray-400 text-xs', children: "Annotation Controls" }), jsxRuntimeExports.jsx(DropdownMenuSeparator, { className: 'bg-gray-700' }), jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: () => setVisibleAnnotationIds(assemblyAnnotations.map((a) => a.id)), className: 'text-white hover:bg-gray-800 cursor-pointer', children: [jsxRuntimeExports.jsx(react$2.Icon, { icon: 'ph:eye', className: 'w-4 h-4 mr-2' }), "Show All Annotations"] }), jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: () => setVisibleAnnotationIds([]), className: 'text-white hover:bg-gray-800 cursor-pointer', children: [jsxRuntimeExports.jsx(react$2.Icon, { icon: 'ph:eye-slash', className: 'w-4 h-4 mr-2' }), "Hide All Annotations"] }), jsxRuntimeExports.jsx(DropdownMenuSeparator, { className: 'bg-gray-700' }), jsxRuntimeExports.jsx(DropdownMenuLabel, { className: 'text-gray-400 text-xs', children: "Individual Annotations" }), assemblyAnnotations.map((annotation, index) => {
76431
76608
  const displayText = annotation.text.value || `${annotation.type === 'arrow' ? 'Arrow' : 'Label'} ${index + 1}`;
76432
76609
  const truncatedText = displayText.length > 30 ? displayText.substring(0, 30) + '...' : displayText;
76433
76610
  const isVisible = visibleAnnotationIds.includes(annotation.id);
@@ -76442,9 +76619,13 @@ const AssemblyViewMode = ({ phases, htmlContent, className = '', productTitle, p
76442
76619
  setCurrentPhaseIndex(targetPhaseIndex);
76443
76620
  setCurrentStepIndex(targetStepIndex);
76444
76621
  setCurrentView('step');
76622
+ // Call onAssemblyChange when navigation happens from 3D viewer
76623
+ if (onAssemblyChange) {
76624
+ onAssemblyChange(phaseId, stepId);
76625
+ }
76445
76626
  }
76446
76627
  }
76447
- }, isAnimating: isAnimating, isPreparingAnimation: isPreparingAnimation, setIsAnimating: setIsAnimating, setIsPreparingAnimation: setIsPreparingAnimation, onElementsReady: handleElementsReady })) : (jsxRuntimeExports.jsx("div", { className: 'flex items-center justify-center h-full text-gray-500', children: jsxRuntimeExports.jsx("p", { children: "3D Model Loading..." }) })), htmlContent && currentView === 'step' && assemblyAnnotations.length > 0 && (jsxRuntimeExports.jsx(AssemblyAnnotationOverlay, { annotations: assemblyAnnotations, setAnnotations: () => { }, currentAnnotation: null, setCurrentAnnotation: () => { }, isPlacingAnnotation: false, setIsPlacingAnnotation: () => { }, runtimeRef: runtimeRef, isPenToolActive: false, visibleAnnotationIds: visibleAnnotationIds, setVisibleAnnotationIds: setVisibleAnnotationIds, setCameraSettings: () => { }, onActivatePenTool: () => { }, onCloseTypeSelector: () => { } }))] })] })] }), jsxRuntimeExports.jsxs("div", { className: 'lg:col-span-2 bg-[#0D0D0D] rounded-3xl w-full px-6 pt-4 pb-6 flex flex-col min-h-[600px]', children: [jsxRuntimeExports.jsx("div", { className: 'mb-4 max-w-[12rem]', children: jsxRuntimeExports.jsx(TnkrSelect, { value: { value: currentPhaseIndex.toString(), label: ((_a = phases[currentPhaseIndex]) === null || _a === void 0 ? void 0 : _a.title) || '' }, options: phases.map((phase, index) => ({ value: index.toString(), label: phase.title })), onChange: (option) => handlePhaseChange(Number(option.value)) }) }), jsxRuntimeExports.jsx("div", { className: 'border-b border-[#313133] mb-6' }), jsxRuntimeExports.jsx("div", { className: 'flex-1 flex flex-col overflow-y-auto min-h-0', children: currentView === 'overview' ? (
76628
+ }, isAnimating: isAnimating, isPreparingAnimation: isPreparingAnimation, setIsAnimating: setIsAnimating, setIsPreparingAnimation: setIsPreparingAnimation, onElementsReady: handleElementsReady, handleNext: handleNext, handlePrevious: handlePrevious })) : (jsxRuntimeExports.jsx("div", { className: 'flex items-center justify-center h-full text-gray-500', children: jsxRuntimeExports.jsx("p", { children: "3D Model Loading..." }) })), htmlContent && currentView === 'step' && assemblyAnnotations.length > 0 && (jsxRuntimeExports.jsx(AssemblyAnnotationOverlay, { annotations: assemblyAnnotations, setAnnotations: () => { }, currentAnnotation: null, setCurrentAnnotation: () => { }, isPlacingAnnotation: false, setIsPlacingAnnotation: () => { }, runtimeRef: runtimeRef, isPenToolActive: false, visibleAnnotationIds: visibleAnnotationIds, setVisibleAnnotationIds: setVisibleAnnotationIds, setCameraSettings: () => { }, onActivatePenTool: () => { }, onCloseTypeSelector: () => { } }))] })] })] }), jsxRuntimeExports.jsxs("div", { className: 'lg:col-span-2 bg-[#0D0D0D] rounded-3xl w-full h-full px-6 pt-4 pb-6 flex flex-col min-h-0', children: [jsxRuntimeExports.jsx("div", { className: 'mb-4 max-w-[12rem]', children: jsxRuntimeExports.jsx(TnkrSelect, { value: { value: currentPhaseIndex.toString(), label: ((_a = phases[currentPhaseIndex]) === null || _a === void 0 ? void 0 : _a.title) || '' }, options: phases.map((phase, index) => ({ value: index.toString(), label: phase.title })), onChange: (option) => handlePhaseChange(Number(option.value)) }) }), jsxRuntimeExports.jsx("div", { className: 'border-b border-[#313133] mb-6' }), jsxRuntimeExports.jsx("div", { className: 'flex-1 flex flex-col overflow-y-auto min-h-0', children: currentView === 'overview' ? (
76448
76629
  // Phase Overview
76449
76630
  // Check if phase has "Add a title" and no content
76450
76631
  (currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.title) === 'Add a title' &&
@@ -76475,11 +76656,13 @@ const AssemblyViewMode = ({ phases, htmlContent, className = '', productTitle, p
76475
76656
  }, onUploadImage: onUploadImage, customExtensionSet: getBasicExtensions(), className: "text-white/70 leading-relaxed", minHeight: 20, readOnly: !editMode }, `step-description-${currentStep === null || currentStep === void 0 ? void 0 : currentStep.id}`) }), jsxRuntimeExports.jsxs("div", { className: 'space-y-6 flex-1', children: [jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("h3", { className: 'text-lg font-semibold mb-4 text-white', children: "Parts Needed" }), (currentStep === null || currentStep === void 0 ? void 0 : currentStep.parts) && currentStep.parts.length > 0 ? (jsxRuntimeExports.jsx("div", { className: 'flex flex-wrap gap-2', children: currentStep.parts.map((part, index) => {
76476
76657
  const displayName = part.name;
76477
76658
  return jsxRuntimeExports.jsx(Tag, { text: displayName }, part.id || index);
76478
- }) })) : (jsxRuntimeExports.jsx("p", { className: 'text-white/50 text-sm', children: "No parts required for this step" }))] }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("h3", { className: 'text-lg font-semibold mb-4 text-white', children: "Tools" }), (currentStep === null || currentStep === void 0 ? void 0 : currentStep.tools) && currentStep.tools.length > 0 ? (jsxRuntimeExports.jsx("div", { className: 'flex flex-wrap gap-2', children: currentStep.tools.map((tool, index) => (jsxRuntimeExports.jsx(Tag, { text: tool.title }, tool.id || index))) })) : (jsxRuntimeExports.jsx("p", { className: 'text-white/50 text-sm', children: "No tools required for this step" }))] })] }), jsxRuntimeExports.jsx(Button, { onClick: handleNext, disabled: !canGoNext, className: 'bg-[#AA423A] hover:bg-[#8A322E] disabled:opacity-50 disabled:cursor-not-allowed text-white px-6 py-2 rounded-lg font-medium max-w-[7rem] ml-auto h-11', children: currentStepIndex === (currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps.length) - 1
76479
- ? currentPhaseIndex < phases.length - 1
76480
- ? 'Next Phase'
76481
- : 'Complete'
76482
- : 'Next Step' })] })) })] })] }) }));
76659
+ }) })) : (jsxRuntimeExports.jsx("p", { className: 'text-white/50 text-sm', children: "No parts required for this step" }))] }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("h3", { className: 'text-lg font-semibold mb-4 text-white', children: "Tools" }), (currentStep === null || currentStep === void 0 ? void 0 : currentStep.tools) && currentStep.tools.length > 0 ? (jsxRuntimeExports.jsx("div", { className: 'flex flex-wrap gap-2', children: currentStep.tools.map((tool, index) => (jsxRuntimeExports.jsx(Tag, { text: tool.title }, tool.id || index))) })) : (jsxRuntimeExports.jsx("p", { className: 'text-white/50 text-sm', children: "No tools required for this step" }))] })] }), jsxRuntimeExports.jsxs("div", { className: 'flex items-center justify-between gap-4', children: [canGoPrevious && (jsxRuntimeExports.jsx(Button, { onClick: handlePrevious, className: 'bg-transparent border border-[#313133] hover:bg-[#232326] text-white/70 hover:text-white px-6 py-2.5 rounded-lg font-medium h-11', children: currentStepIndex === 0 && currentPhaseIndex > 0
76660
+ ? 'Previous Phase'
76661
+ : 'Previous Step' })), jsxRuntimeExports.jsx(Button, { onClick: handleNext, disabled: !canGoNext, className: 'bg-[#AA423A] hover:bg-[#8A322E] disabled:opacity-50 disabled:cursor-not-allowed text-white px-6 py-2.5 rounded-lg font-medium h-11 ml-auto', children: currentStepIndex === (currentPhase === null || currentPhase === void 0 ? void 0 : currentPhase.steps.length) - 1
76662
+ ? currentPhaseIndex < phases.length - 1
76663
+ ? 'Next Phase'
76664
+ : 'Complete'
76665
+ : 'Next Step' })] })] })) })] })] }) }));
76483
76666
  };
76484
76667
 
76485
76668
  /**