feat: implement remote CRUD for patients and update version
continuous-integration/webhook Deploy concluído (VPS4)
continuous-integration/webhook Deploy concluído (VPS4)
This commit is contained in:
@@ -1 +1 @@
|
||||
2.1.53
|
||||
2.1.63
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function CreatePatientModal({ isOpen, onClose, onCreated }) {
|
||||
e.preventDefault();
|
||||
setSaving(true);
|
||||
try {
|
||||
await api.post('/patients', form);
|
||||
await api.post('/images/patients', form);
|
||||
showToast('Paciente criado com sucesso!', 'success');
|
||||
setForm({ firstName: '', lastName: '', doctor: '', birthday: '', gender: '0', phone: '', remark: '' });
|
||||
onClose();
|
||||
|
||||
@@ -85,7 +85,7 @@ export default function SyncModal({ isOpen, onClose, defaultTab = 'devices' }) {
|
||||
// Criar novo paciente se necessário
|
||||
if (newPatientMode) {
|
||||
const fullName = `${newFirstName.trim()} ${newLastName.trim()}`;
|
||||
await api.post('/patients', {
|
||||
await api.post('/images/patients', {
|
||||
firstName: newFirstName.trim(),
|
||||
lastName: newLastName.trim(),
|
||||
doctor: newDoctor.trim()
|
||||
|
||||
@@ -75,9 +75,9 @@ function GtoDetailModal({ isOpen, onClose, gto, onUpdated }) {
|
||||
const response = await fetch(url);
|
||||
const blob = await response.blob();
|
||||
|
||||
const ext = getExtension(img.filename);
|
||||
const pName = (img.patient_name || 'paciente').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '_');
|
||||
const obs = (img.image_remark || '').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '_');
|
||||
const ext = getExtension(img.filename) || 'jpg';
|
||||
const pName = (img.patient_name || 'paciente').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
const obs = (img.image_remark || '').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
|
||||
const fileName = obs ? `${pName}-${obs}.${ext}` : `${pName}.${ext}`;
|
||||
|
||||
@@ -136,17 +136,33 @@ function GtoDetailModal({ isOpen, onClose, gto, onUpdated }) {
|
||||
};
|
||||
|
||||
const handleCopyFilename = async (img) => {
|
||||
let fileName = 'imagem.jpg';
|
||||
try {
|
||||
const ext = getExtension(img.filename);
|
||||
const pName = (img.patient_name || 'paciente').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '_');
|
||||
const obs = (img.image_remark || '').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '_');
|
||||
const ext = getExtension(img.filename) || 'jpg';
|
||||
const pName = (img.patient_name || 'paciente').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
const obs = (img.image_remark || '').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
|
||||
const fileName = obs ? `${pName}-${obs}.${ext}` : `${pName}.${ext}`;
|
||||
fileName = obs ? `${pName}-${obs}.${ext}` : `${pName}.${ext}`;
|
||||
|
||||
await navigator.clipboard.writeText(fileName);
|
||||
showToast('Nome do arquivo copiado para a área de transferência!', 'success');
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
await navigator.clipboard.writeText(fileName);
|
||||
} else {
|
||||
throw new Error('Fallback');
|
||||
}
|
||||
showToast('Nome copiado: ' + fileName, 'success');
|
||||
} catch (err) {
|
||||
showToast('Erro ao copiar nome do arquivo.', 'error');
|
||||
try {
|
||||
const textArea = document.createElement("textarea");
|
||||
textArea.value = fileName;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
document.execCommand('copy');
|
||||
textArea.remove();
|
||||
showToast('Nome copiado: ' + fileName, 'success');
|
||||
} catch (e) {
|
||||
showToast('Erro ao copiar nome.', 'error');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -226,6 +226,9 @@ export default function ImageDetailsPage() {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = cw; canvas.height = ch;
|
||||
const ctx = canvas.getContext('2d');
|
||||
// Preencher com branco para JPEG
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.fillRect(0, 0, cw, ch);
|
||||
ctx.translate(cw / 2, ch / 2);
|
||||
ctx.scale(fH ? -1 : 1, fV ? -1 : 1);
|
||||
ctx.rotate(rad);
|
||||
@@ -233,13 +236,12 @@ export default function ImageDetailsPage() {
|
||||
canvas.toBlob((blob) => {
|
||||
const a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(blob);
|
||||
const pName = (image.patient_name || 'paciente').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '_');
|
||||
const obs = (image.image_remark || '').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '_');
|
||||
const suffix = applyTransform ? `${deg}deg` : 'original';
|
||||
a.download = obs ? `${pName}-${obs}_${suffix}.png` : `${pName}_${suffix}.png`;
|
||||
const pName = (image.patient_name || 'paciente').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
const obs = (image.image_remark || '').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
a.download = obs ? `${pName}-${obs}.jpg` : `${pName}.jpg`;
|
||||
document.body.appendChild(a); a.click(); a.remove();
|
||||
setTimeout(() => URL.revokeObjectURL(a.href), 4000);
|
||||
}, 'image/png');
|
||||
}, 'image/jpeg', 0.95);
|
||||
} catch (e) {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
@@ -248,6 +250,19 @@ export default function ImageDetailsPage() {
|
||||
img.src = url;
|
||||
};
|
||||
|
||||
const copyFileNameToClipboard = async () => {
|
||||
try {
|
||||
const pName = (image.patient_name || 'paciente').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
const obs = (image.image_remark || '').trim().replace(/[\/\\:*?"<>|]/g, '').replace(/\s+/g, '-');
|
||||
const filename = obs ? `${pName}-${obs}.jpg` : `${pName}.jpg`;
|
||||
|
||||
await navigator.clipboard.writeText(filename);
|
||||
showToast('Nome copiado para a área de transferência!', 'success');
|
||||
} catch (e) {
|
||||
showToast('Erro ao copiar nome: ' + e.message, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
const copyImageToClipboard = async () => {
|
||||
const url = imageUrl;
|
||||
|
||||
@@ -560,7 +575,15 @@ export default function ImageDetailsPage() {
|
||||
onClick={copyImageToClipboard}
|
||||
style={{ width: '100%', height: 44, marginTop: 12, fontSize: '1rem', fontWeight: 600, display: 'flex', gap: 8, alignItems: 'center', justifyContent: 'center' }}
|
||||
>
|
||||
📋 Copiar Imagem (Área de Transferência)
|
||||
🖼️ Copiar Imagem
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={copyFileNameToClipboard}
|
||||
style={{ width: '100%', height: 44, marginTop: 12, fontSize: '1rem', fontWeight: 600, display: 'flex', gap: 8, alignItems: 'center', justifyContent: 'center' }}
|
||||
>
|
||||
📋 Copiar Nome
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user