From 60d6474b25a1635234997bedb14fef9700a44f73 Mon Sep 17 00:00:00 2001 From: VPS 4 Deploy Agent Date: Sat, 30 May 2026 20:14:56 +0200 Subject: [PATCH] =?UTF-8?q?feat(transform):=20passo=20de=20escolha=20entre?= =?UTF-8?q?=204=20posi=C3=A7=C3=B5es=20(0/90/180/270)=20antes=20do=20ajust?= =?UTF-8?q?e=20fino?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ao clicar em Orientar, primeiro mostra 4 rotações da imagem para escolher a orientação grossa; ao clicar numa, abre o ajuste fino (escolhida + original) com botão para voltar. Rotação salva = orientação escolhida + ajuste fino. --- .../src/components/TransformModal.jsx | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/dental-server/dental-client/src/components/TransformModal.jsx b/dental-server/dental-client/src/components/TransformModal.jsx index af83cd9..4002b1c 100644 --- a/dental-server/dental-client/src/components/TransformModal.jsx +++ b/dental-server/dental-client/src/components/TransformModal.jsx @@ -14,6 +14,8 @@ function formatDate(dateString) { export default function TransformModal({ isOpen, onClose, image, onSaved }) { const { showToast } = useToast(); const [activeView, setActiveView] = useState('transform'); // 'transform' | 'gto' + const [step, setStep] = useState('choose'); // 'choose' (4 posições) | 'finetune' + const [baseRotation, setBaseRotation] = useState(0); // 0 | 90 | 180 | 270 const [showInfo, setShowInfo] = useState(false); const [fineTuneAngle, setFineTuneAngle] = useState(0); const [remark, setRemark] = useState(''); @@ -29,6 +31,8 @@ export default function TransformModal({ isOpen, onClose, image, onSaved }) { useEffect(() => { if (!image) return; setFineTuneAngle(0); + setBaseRotation(0); + setStep('choose'); setRemark(''); setShowInfo(false); setActiveView('transform'); @@ -70,15 +74,17 @@ export default function TransformModal({ isOpen, onClose, image, onSaved }) { const resetAngle = () => setFineTuneAngle(0); + const totalRotation = ((baseRotation + fineTuneAngle) % 360 + 360) % 360; + const saveTransform = async () => { - if (fineTuneAngle === 0) { + if (totalRotation === 0) { showToast('Nenhuma edição aplicada.', 'error'); return; } setSaving(true); try { await api.post(`/images/${image.id}/transform`, { - rotation: fineTuneAngle, + rotation: totalRotation, flipH: false, flipV: false, remark @@ -180,8 +186,44 @@ export default function TransformModal({ isOpen, onClose, image, onSaved }) { )} - {/* View: Transformação */} - {activeView === 'transform' && ( + {/* View: Transformação — PASSO 1: escolher entre 4 posições */} + {activeView === 'transform' && step === 'choose' && ( +
+

+ Escolha a melhor orientação. Depois você faz o ajuste fino. +

+
+ {[0, 90, 180, 270].map((deg) => ( + + ))} +
+
+ )} + + {/* View: Transformação — PASSO 2: ajuste fino (escolhida + original) */} + {activeView === 'transform' && step === 'finetune' && (
{/* Original */} @@ -192,20 +234,27 @@ export default function TransformModal({ isOpen, onClose, image, onSaved }) {
- {/* Preview (com rotação aplicada) */} + {/* Preview (orientação escolhida + ajuste fino) */}
-

Preview

+

Preview ({totalRotation}°)

Preview
{/* Controles de rotação */}
+

Ajuste

{[