BedControls.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { useMutation } from '@tanstack/react-query';
  2. import { api, isConfirmationRequired } from '../../api/client';
  3. import type { PrinterStatus } from '../../api/client';
  4. import { useState } from 'react';
  5. import { ConfirmModal } from '../ConfirmModal';
  6. interface BedControlsProps {
  7. printerId: number;
  8. status: PrinterStatus | null | undefined;
  9. disabled?: boolean;
  10. }
  11. export function BedControls({ printerId, status, disabled = false }: BedControlsProps) {
  12. const isConnected = (status?.connected ?? false) && !disabled;
  13. const [confirmModal, setConfirmModal] = useState<{
  14. token: string;
  15. warning: string;
  16. distance: number;
  17. } | null>(null);
  18. const moveMutation = useMutation({
  19. mutationFn: ({ distance, token }: { distance: number; token?: string }) =>
  20. api.moveAxis(printerId, 'Z', distance, 1000, token),
  21. onSuccess: (result, variables) => {
  22. if (isConfirmationRequired(result)) {
  23. setConfirmModal({
  24. token: result.token,
  25. warning: result.warning,
  26. distance: variables.distance,
  27. });
  28. }
  29. },
  30. });
  31. const handleMove = (distance: number) => {
  32. moveMutation.mutate({ distance });
  33. };
  34. const handleConfirm = () => {
  35. if (confirmModal) {
  36. moveMutation.mutate({ distance: confirmModal.distance, token: confirmModal.token });
  37. setConfirmModal(null);
  38. }
  39. };
  40. const isDisabled = !isConnected || moveMutation.isPending;
  41. return (
  42. <>
  43. <div className="flex items-center gap-2">
  44. <button
  45. onClick={() => handleMove(-10)}
  46. disabled={isDisabled}
  47. className="px-3.5 py-2 rounded-md bg-bambu-dark-secondary hover:bg-bambu-dark-tertiary border border-bambu-dark-tertiary text-sm text-bambu-gray disabled:opacity-50 disabled:cursor-not-allowed"
  48. title="Bed up 10mm"
  49. >
  50. ↑10
  51. </button>
  52. <button
  53. onClick={() => handleMove(-1)}
  54. disabled={isDisabled}
  55. className="px-3.5 py-2 rounded-md bg-bambu-dark-secondary hover:bg-bambu-dark-tertiary border border-bambu-dark-tertiary text-sm text-bambu-gray disabled:opacity-50 disabled:cursor-not-allowed"
  56. title="Bed up 1mm"
  57. >
  58. ↑1
  59. </button>
  60. <span className="px-2 py-2 text-sm text-bambu-gray">Bed</span>
  61. <button
  62. onClick={() => handleMove(1)}
  63. disabled={isDisabled}
  64. className="px-3.5 py-2 rounded-md bg-bambu-dark-secondary hover:bg-bambu-dark-tertiary border border-bambu-dark-tertiary text-sm text-bambu-gray disabled:opacity-50 disabled:cursor-not-allowed"
  65. title="Bed down 1mm"
  66. >
  67. ↓1
  68. </button>
  69. <button
  70. onClick={() => handleMove(10)}
  71. disabled={isDisabled}
  72. className="px-3.5 py-2 rounded-md bg-bambu-dark-secondary hover:bg-bambu-dark-tertiary border border-bambu-dark-tertiary text-sm text-bambu-gray disabled:opacity-50 disabled:cursor-not-allowed"
  73. title="Bed down 10mm"
  74. >
  75. ↓10
  76. </button>
  77. </div>
  78. {/* Confirmation Modal */}
  79. {confirmModal && (
  80. <ConfirmModal
  81. title="Confirm Bed Movement"
  82. message={confirmModal.warning}
  83. confirmText="Continue"
  84. variant="warning"
  85. onConfirm={handleConfirm}
  86. onCancel={() => setConfirmModal(null)}
  87. />
  88. )}
  89. </>
  90. );
  91. }