From e4386c17768af173c909b02dc0c107974c6a4c97 Mon Sep 17 00:00:00 2001 From: Jessica_Faro Date: Thu, 23 Oct 2025 14:18:36 -0300 Subject: [PATCH] tiptap3 --- package-lock.json | 258 +++++++------- package.json | 4 +- src/PagesMedico/DoctorRelatorioManager.jsx | 316 ++++++++---------- src/PagesMedico/EditPageRelatorio.jsx | 269 +++++++-------- src/PagesMedico/FormNovoRelatorio.jsx | 271 +++++++++++++-- src/PagesMedico/TiptapEditor.jsx | 87 ++--- .../utils/Functions-Endpoints/Doctor.js | 37 +- 7 files changed, 676 insertions(+), 566 deletions(-) diff --git a/package-lock.json b/package-lock.json index 26a38b0..51862dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,11 @@ "@testing-library/jest-dom": "^6.8.0", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^13.5.0", + "@tiptap/core": "^3.7.2", "@tiptap/extension-placeholder": "^3.7.1", + "@tiptap/pm": "^3.7.2", "@tiptap/react": "^3.7.1", - "@tiptap/starter-kit": "^3.7.1", + "@tiptap/starter-kit": "^3.7.2", "apexcharts": "^5.3.4", "bootstrap": "^5.3.8", "bootstrap-icons": "^1.13.1", @@ -17781,39 +17783,39 @@ } }, "node_modules/@tiptap/core": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.7.1.tgz", - "integrity": "sha512-jB6R8EGI34QUmV7EhtE+JVpjbZ6Wa0dcf0LNS36X9V7FtDQcnxl7ekRs/ftELt/6qOjubRdyhaID0wNdJVmFtw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.7.2.tgz", + "integrity": "sha512-fJwNpTx0aq4UU0HNkxPvPYfNBcTHQ/q5xBUdOB5Mgu6clwGES38jVsNNSudB8g53APUmJIS+2fJbkxl3V+0jww==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "^3.7.1" + "@tiptap/pm": "^3.7.2" } }, "node_modules/@tiptap/extension-blockquote": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.7.1.tgz", - "integrity": "sha512-UPIne4kD8hwhadPtapn0WfJCNiF+b3ftNYiC1BpNfti5NmM0sXuqOOC0WnVgGgsNuJp4hd+4PMp42InlD6/1aw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.7.2.tgz", + "integrity": "sha512-8rNDh1E1ratex9KicvNNnjJGtF313Kpf5hXHOUcIm8FQwvA/0Tu6jq7r6VgESMyo95R3EmzRpnCYQef+zDm6OQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-bold": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.7.1.tgz", - "integrity": "sha512-XZRt1blYGpqVlcBo+PKH1mlbsqdc5KsWi/ZsPBV3Ajg/Vx5d6SAY4wK6CW1SpotE1wWucUhfAmXddhBFvYzaUA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.7.2.tgz", + "integrity": "sha512-bwCn9lQEXnEi7LfIx3G/oaH4I0ZapAgrHzLCNJH/tNgRKVWym1H1Oa8PlkiFDbalWOdUkbgeAUqUaIB13k408Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-bubble-menu": { @@ -17834,64 +17836,64 @@ } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.7.1.tgz", - "integrity": "sha512-AO7EVAftvzSw7Sftp36P+HNedxjygMpobYNTBQzHfGljRZh8VDhIUzwyP1OsmlrcCbBxsrjMZLrmk/ozsALq0g==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.7.2.tgz", + "integrity": "sha512-OHYYXKjmxisLQws0tW8Dz14PcyIJmaed7eypZvIm/R3hxa/7lJY/2EM/Ti5g/w1U8WPBEH1hX3icRtiulserKw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "^3.7.1" + "@tiptap/extension-list": "^3.7.2" } }, "node_modules/@tiptap/extension-code": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.7.1.tgz", - "integrity": "sha512-ZRarYvgQ16ZrzKox/iW3bVr5IVNBsD0yjU5S7GVmlRgRQ8lhsTloLk9Gu05uuZ6dOoL3qApLA8+W7w8sxZJ35w==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.7.2.tgz", + "integrity": "sha512-J8FaCiKJJnHvQiPcbfbUtc5RNmGx/Gui/K5CDMPc17jhCiQ9JhR9idRPREV24Z2t7GujWX7LG6ZDDR82pSns+g==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-code-block": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.7.1.tgz", - "integrity": "sha512-/Ov81QXEn6AOiiSUFlM57a+YSye/Lkhvgy303+CEGtDuFVU/SJ0tDsgmSYzkP5q6DIVQLAXp5WkxEo02GnYHgQ==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.7.2.tgz", + "integrity": "sha512-TfixutvvbGCrSSCsfDK/PBm6A5FIzcPTSVDrmmsiAfqldj/Woy1T42dads+wv9SjKG06GlWDwYtDGAk2Uun8NA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1", - "@tiptap/pm": "^3.7.1" + "@tiptap/core": "^3.7.2", + "@tiptap/pm": "^3.7.2" } }, "node_modules/@tiptap/extension-document": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.7.1.tgz", - "integrity": "sha512-b7NHWseJSvhhbsiSWjQgiJcs6FUJiEJocfhazDiWAOk5ELQ6+oiIe7ecEgDqBmafk9oziV9r7u9OAgyeyP3JBA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.7.2.tgz", + "integrity": "sha512-OrHl402v2FWCUKR1Xi5MTNBAkKYQh7mtpw/WlJDFnk5z1qHLqz4UIcbGilDYzVPrNUZPhA1p3c+V5UUVUFzUfg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.7.1.tgz", - "integrity": "sha512-wZT3bPeNJAasOvNr6tUZAwXFeKlQEToSnVAjFiBzJwLDonuK8ZaAiBCDQgqEQSlP3HsEE4/qkERBNrdyAT26CQ==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.7.2.tgz", + "integrity": "sha512-79y6M9pJYwqcqBHIWoomfptJp0QB/TP3Y+2NOL09sMNeSdUgmz5pCVObA4H48YMkoB0EcUtux2IUOM66e4nsJA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extensions": "^3.7.1" + "@tiptap/extensions": "^3.7.2" } }, "node_modules/@tiptap/extension-floating-menu": { @@ -17910,70 +17912,70 @@ } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.7.1.tgz", - "integrity": "sha512-1UrZEaqruWPLdgYsAm4au7BAyTDjaNRP0E7UIoEoGsq+MAS2MM3g4suXMzu+l3ZIayrSy98N3T8DIUG+U6+mww==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.7.2.tgz", + "integrity": "sha512-vCLo2dL2SfeWjh/gJKDiu0/fz6OF7obGTJvHg/yStkoUqlAEiwKoyHP/NXeTGYJMzZzUi0kY9DtTEJdGFvphuQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extensions": "^3.7.1" + "@tiptap/extensions": "^3.7.2" } }, "node_modules/@tiptap/extension-hard-break": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.7.1.tgz", - "integrity": "sha512-pEvRjWexMNxXH5FOy3EhzyMFDFHrRTWOgZbWAxliKDg2dFEJ50e9KcCMDs87e7++V753lEKnFTmz/9WaH7cwcQ==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.7.2.tgz", + "integrity": "sha512-nNDo+5S1yRQ3JkBM+gwpEEVZ/Kw9qWoG/cpShyGYDHo1/y8MgO+VI0kSb/LuBTw7g+jmNXdf+ZaRRI/pXsUihg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-heading": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.7.1.tgz", - "integrity": "sha512-rOUou6b0+5E+DAmEMTC/mlKTLiOr4D0LKzBfqBLQ3zUyZPZabOKzN0L+4MaLNR2CkXy/Ae4du5ucHGrGOWzVrQ==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.7.2.tgz", + "integrity": "sha512-eH/G66FIRlTQz4MhEmlNNNQgVTxhoqlkyFzgeG5aipIplYOdYa5Y6Wl0NF4xqr1jAHGLAK6LaYS4FXp3TE7LyA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.7.1.tgz", - "integrity": "sha512-f4lXW/LHuJBF11PIrWdNAzTmlapV4fVujJ5eCsLAkpzhx3izVrDW/WlKRrkGUCy/qQT4v7BbHNa5JYlKDzDo0Q==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.7.2.tgz", + "integrity": "sha512-pN+1hJAVVP3uqtpZ5Rm7z5XUB/NGprK6wExJ04xG117E4rTVcaEb1FnMILY3J3A5XbdC3vHX+cblR8mOl1PAMw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1", - "@tiptap/pm": "^3.7.1" + "@tiptap/core": "^3.7.2", + "@tiptap/pm": "^3.7.2" } }, "node_modules/@tiptap/extension-italic": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.7.1.tgz", - "integrity": "sha512-Bm6eOtcafc5kjE357GlvIY2hNTRRAkb8D5SRm8zYlVB0fiLto+r15Ht+DTOmLiQKEGtEArQ/C8Rh2j09UdH2vA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.7.2.tgz", + "integrity": "sha512-1tfF37LvKgA5hg09UBgOjdMLNRb1C6keIOBF0r5oHKeWPYOf4z3j5IU9PsFUoOn53XRMb1aiD/TNbGPyoT3Fyw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-link": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.7.1.tgz", - "integrity": "sha512-6+0/mo+EKDiA1d1pDZSsf/51ZOwdFnN35yF/4celxdr/JL4aupvtttIjGAtWd37h50cadYSL4F1uacKs7yyh8Q==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.7.2.tgz", + "integrity": "sha512-9K54PxBiDSWAMfICqkb8jcQ6cL7vDAtjTk0zqBw4d+XuaUy0FC9QUdbx7r1Pkbf36K1/ApbvM9a7qpOirWk8Xw==", "dependencies": { "linkifyjs": "^4.3.2" }, @@ -17982,69 +17984,69 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1", - "@tiptap/pm": "^3.7.1" + "@tiptap/core": "^3.7.2", + "@tiptap/pm": "^3.7.2" } }, "node_modules/@tiptap/extension-list": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.7.1.tgz", - "integrity": "sha512-E93oXkV2vsZThsix0OA7RiHNLIMGi+w9ASKZ+8TGB69oy32yujnnZz6YVhTVVDPOw8rCP5CnOPhJbgdcqByr0A==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.7.2.tgz", + "integrity": "sha512-/tYHmEkOGcVweAc9ZgnAXkzua5aJfu7TjZcKTq5fmDt6x9MY1eY1+egS7D9hVR2sUSAC10VgXmYdYPDsKF3p2g==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1", - "@tiptap/pm": "^3.7.1" + "@tiptap/core": "^3.7.2", + "@tiptap/pm": "^3.7.2" } }, "node_modules/@tiptap/extension-list-item": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.7.1.tgz", - "integrity": "sha512-qkXfWRBusJCId9VhRo9vihcrmxvJ83fkzYWI0LiefJCT1LKfMaeInFNxIsFeUU4q9nR0mhZo7ES3E2+Tk0U3Mw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.7.2.tgz", + "integrity": "sha512-962TFsx4eF5NMyLVhGFGF/btt5j3MipPhDiUsxzBgnlW8o5OonVepb9cDrqpEDQ2/wLvheWnCKuvmG7umasldQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "^3.7.1" + "@tiptap/extension-list": "^3.7.2" } }, "node_modules/@tiptap/extension-list-keymap": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.7.1.tgz", - "integrity": "sha512-3WyzWge/g6FoxMTkoAARtMJyIYQbpclNX48HyAqdwjJXuLmz3qckEnJEXo47CvJlRsNAlcDJniRS9j5SVJupRw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.7.2.tgz", + "integrity": "sha512-1du9eo+NPIkuRT258yUn9bovhip556aJo/yDtRbswEVNScP1E8y/kFRWvw0HD7/YWcNqok1ZteoSwShWnKAXRQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "^3.7.1" + "@tiptap/extension-list": "^3.7.2" } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.7.1.tgz", - "integrity": "sha512-iX3DhTwFp84fiCNSF7+kl/sq6orXq2QFcV2AH+CvL+d0WW1STYmmVmE26gHEjyY82QfpvLZYUCEG6RSYpxFIZw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.7.2.tgz", + "integrity": "sha512-Tu61/JXh1RRd3Kb+s7A7jmpnB+w1pqGSRfMXBtYHDHDIGyXu255ru7soX44lJfHGq/zYcTFSHGSsi8o23QONJg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "^3.7.1" + "@tiptap/extension-list": "^3.7.2" } }, "node_modules/@tiptap/extension-paragraph": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.7.1.tgz", - "integrity": "sha512-L5dsppKKo46MN3Go5vzqqzjPX89pz1lIkIUN3IhU+KmAHg1TklfR7FQkiIFIIV2rb2ZLuLpD/JcNsZAUmJTW5Q==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.7.2.tgz", + "integrity": "sha512-HmDuAixTcvP4A/v6OLkh/C6nB86i7/DRNswBf/Udak8TgWUIcSUK0iActxxm5+B3MZTSf3U87JzyI6IeuElLIQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-placeholder": { @@ -18060,58 +18062,58 @@ } }, "node_modules/@tiptap/extension-strike": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.7.1.tgz", - "integrity": "sha512-Ctqk/SfmGd3hFCDr4/OH0Dnja19UWUrUEY62pwM7JCkbY/Y9QwPLSO32L6KyamwUDek9SL/ATjRPz6GLp0P7hg==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.7.2.tgz", + "integrity": "sha512-I1G+4vZbCBTpAMmyVwaO8cLBJgXEf1DyEzc0B+HhTJiBa9qA9OKgRQEGFgisxu1kggjbzB6+d0+taHfjsZC1SQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-text": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.7.1.tgz", - "integrity": "sha512-m+8FJrFAllJYuzLbEXJ9AztobxmWBTjWorkHcMHBLAbY2ytmAhIM1u3ExtOn9DjvnIT6MffCaq0i/KjhSBYJlA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.7.2.tgz", + "integrity": "sha512-sKaeGYNP1+bAe2rvmzWLW5qH9DsSFOJlOUEOFchR0OX0rC7bbGS6/KuyAq0w6UkL+cMJnDyAbv3KeD2WEA192w==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extension-underline": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.7.1.tgz", - "integrity": "sha512-tyx7ZM2ll8DclKe9Ea/vPyqaZBgnJfIbKBOpecpzawDaJ5ocjwywmYNduevOhw327X2/i8LIQBsPuIOJselcUQ==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.7.2.tgz", + "integrity": "sha512-GDpUZllTD7uIdHjTzYJ6i4jUgCeviW40SCpLVVv1xH0gj1t1xu0Rnxmk+bXkF2XNe8jPXkMCgYNr6DR6eO8roQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1" + "@tiptap/core": "^3.7.2" } }, "node_modules/@tiptap/extensions": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.7.1.tgz", - "integrity": "sha512-O7eq3frqh7kn/J2P+lpx8blBQrIQxt21J3NvlQJhW5nXIECdo2ox8SQcEfli0EqMSwZCZTdVufdFBkWfIRXhRg==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.7.2.tgz", + "integrity": "sha512-FaToSdU9fhQk2swkaXrAQNgdaE0dwLbUHcvilW5F4xTpQfZ3J535u5U2TUYf+f9KKSV5fTmD4QGNY9qxY7ihTg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.1", - "@tiptap/pm": "^3.7.1" + "@tiptap/core": "^3.7.2", + "@tiptap/pm": "^3.7.2" } }, "node_modules/@tiptap/pm": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.7.1.tgz", - "integrity": "sha512-t3n054kplRtRYn8pDnzF/prDUccF7QX7jPYLsYBpLn3+d59J5KKkBmOpPExUGE8kZkNoLfwffAFj6NBfqOu+Xg==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.7.2.tgz", + "integrity": "sha512-i2fvXDapwo/TWfHM6STYEbkYyF3qyfN6KEBKPrleX/Z80G5bLxom0gB79TsjLNxTLi6mdf0vTHgAcXMG1avc2g==", "dependencies": { "prosemirror-changeset": "^2.3.0", "prosemirror-collab": "^1.3.1", @@ -18164,34 +18166,34 @@ } }, "node_modules/@tiptap/starter-kit": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.7.1.tgz", - "integrity": "sha512-ZYgA3BkASQmHyoDlUYKFPEpCzIcn/FP/Sb+Ic2L7gt2gOC7zvWAVc/2yIbiFuq+48s+5U/KJqDiXn2hiLwXxpA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.7.2.tgz", + "integrity": "sha512-43GwI+2Mtc/ci7J4eJOE02wZxp5KIsDTMMb0peNksPcEGaURGdDhav9zbAW24NRjRxU7Auk/zaQu9O8+ZE0v0A==", "dependencies": { - "@tiptap/core": "^3.7.1", - "@tiptap/extension-blockquote": "^3.7.1", - "@tiptap/extension-bold": "^3.7.1", - "@tiptap/extension-bullet-list": "^3.7.1", - "@tiptap/extension-code": "^3.7.1", - "@tiptap/extension-code-block": "^3.7.1", - "@tiptap/extension-document": "^3.7.1", - "@tiptap/extension-dropcursor": "^3.7.1", - "@tiptap/extension-gapcursor": "^3.7.1", - "@tiptap/extension-hard-break": "^3.7.1", - "@tiptap/extension-heading": "^3.7.1", - "@tiptap/extension-horizontal-rule": "^3.7.1", - "@tiptap/extension-italic": "^3.7.1", - "@tiptap/extension-link": "^3.7.1", - "@tiptap/extension-list": "^3.7.1", - "@tiptap/extension-list-item": "^3.7.1", - "@tiptap/extension-list-keymap": "^3.7.1", - "@tiptap/extension-ordered-list": "^3.7.1", - "@tiptap/extension-paragraph": "^3.7.1", - "@tiptap/extension-strike": "^3.7.1", - "@tiptap/extension-text": "^3.7.1", - "@tiptap/extension-underline": "^3.7.1", - "@tiptap/extensions": "^3.7.1", - "@tiptap/pm": "^3.7.1" + "@tiptap/core": "^3.7.2", + "@tiptap/extension-blockquote": "^3.7.2", + "@tiptap/extension-bold": "^3.7.2", + "@tiptap/extension-bullet-list": "^3.7.2", + "@tiptap/extension-code": "^3.7.2", + "@tiptap/extension-code-block": "^3.7.2", + "@tiptap/extension-document": "^3.7.2", + "@tiptap/extension-dropcursor": "^3.7.2", + "@tiptap/extension-gapcursor": "^3.7.2", + "@tiptap/extension-hard-break": "^3.7.2", + "@tiptap/extension-heading": "^3.7.2", + "@tiptap/extension-horizontal-rule": "^3.7.2", + "@tiptap/extension-italic": "^3.7.2", + "@tiptap/extension-link": "^3.7.2", + "@tiptap/extension-list": "^3.7.2", + "@tiptap/extension-list-item": "^3.7.2", + "@tiptap/extension-list-keymap": "^3.7.2", + "@tiptap/extension-ordered-list": "^3.7.2", + "@tiptap/extension-paragraph": "^3.7.2", + "@tiptap/extension-strike": "^3.7.2", + "@tiptap/extension-text": "^3.7.2", + "@tiptap/extension-underline": "^3.7.2", + "@tiptap/extensions": "^3.7.2", + "@tiptap/pm": "^3.7.2" }, "funding": { "type": "github", diff --git a/package.json b/package.json index 728f80b..c368992 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,11 @@ "@testing-library/jest-dom": "^6.8.0", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^13.5.0", + "@tiptap/core": "^3.7.2", "@tiptap/extension-placeholder": "^3.7.1", + "@tiptap/pm": "^3.7.2", "@tiptap/react": "^3.7.1", - "@tiptap/starter-kit": "^3.7.1", + "@tiptap/starter-kit": "^3.7.2", "apexcharts": "^5.3.4", "bootstrap": "^5.3.8", "bootstrap-icons": "^1.13.1", diff --git a/src/PagesMedico/DoctorRelatorioManager.jsx b/src/PagesMedico/DoctorRelatorioManager.jsx index 22a79b2..cf5d2c4 100644 --- a/src/PagesMedico/DoctorRelatorioManager.jsx +++ b/src/PagesMedico/DoctorRelatorioManager.jsx @@ -1,130 +1,131 @@ +// src/PagesMedico/DoctorRelatorioManager.jsx import API_KEY from '../components/utils/apiKeys'; -import { Link } from 'react-router-dom'; -import {useState, useEffect} from 'react' +import { Link } from 'react-router-dom'; +import { useState, useEffect } from 'react'; import { useAuth } from '../components/utils/AuthProvider'; import { GetPatientByID } from '../components/utils/Functions-Endpoints/Patient'; +import { GetDoctorByID } from '../components/utils/Functions-Endpoints/Doctor'; import { useNavigate } from 'react-router-dom'; import html2pdf from 'html2pdf.js'; import TiptapViewer from './TiptapViewer'; - + const DoctorRelatorioManager = () => { - const navigate = useNavigate() - const {getAuthorizationHeader} = useAuth(); - let authHeader = getAuthorizationHeader() - const [RelatoriosFiltrados, setRelatorios] = useState([]) - const [PacientesComRelatorios, setPacientesComRelatorios] = useState([]) - const [showModal, setShowModal] = useState(false) - const [index, setIndex] = useState() - // 1º useEffect: Busca os dados dos pacientes após carregar os relatórios - useEffect( () => { - let pacientesDosRelatorios = [] - - const ListarPacientes = async () => { + const navigate = useNavigate(); + const { getAuthorizationHeader } = useAuth(); + const authHeader = getAuthorizationHeader(); + const [RelatoriosFiltrados, setRelatorios] = useState([]); + const [PacientesComRelatorios, setPacientesComRelatorios] = useState([]); + const [MedicosComRelatorios, setMedicosComRelatorios] = useState([]); + const [showModal, setShowModal] = useState(false); + const [index, setIndex] = useState(); + + // busca lista de relatórios + useEffect(() => { + const fetchReports = async () => { + try { + var myHeaders = new Headers(); + myHeaders.append('apikey', API_KEY); + myHeaders.append('Authorization', authHeader); + var requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; + + const res = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?select=*", requestOptions); + const data = await res.json(); + setRelatorios(data || []); + } catch (err) { + console.error('Erro listar relatórios', err); + setRelatorios([]); + } + }; + fetchReports(); + }, [authHeader]); + + // depois que RelatoriosFiltrados mudar, busca pacientes e médicos correspondentes + useEffect(() => { + const fetchRelData = async () => { + const pacientes = []; + const medicos = []; for (let i = 0; i < RelatoriosFiltrados.length; i++) { - let relatorio = RelatoriosFiltrados[i]; - let paciente_id = relatorio.patient_id; - const paciente = await GetPatientByID(paciente_id, authHeader); - console.log(paciente) - if (paciente.length > 0) { - pacientesDosRelatorios.push(paciente[0]); + const rel = RelatoriosFiltrados[i]; + // paciente + try { + const pacienteRes = await GetPatientByID(rel.patient_id, authHeader); + pacientes.push(Array.isArray(pacienteRes) ? pacienteRes[0] : pacienteRes); + } catch (err) { + pacientes.push(null); + } + // médico: tenta created_by ou requested_by id se existir + try { + const doctorId = rel.created_by || rel.requested_by || null; + if (doctorId) { + // se created_by é id (uuid) usamos GetDoctorByID, senão se requested_by for nome, guardamos nome + const docRes = await GetDoctorByID(doctorId, authHeader); + medicos.push(Array.isArray(docRes) ? docRes[0] : docRes); + } else { + medicos.push({ full_name: rel.requested_by || '' }); + } + } catch (err) { + medicos.push({ full_name: rel.requested_by || '' }); } } - setPacientesComRelatorios(pacientesDosRelatorios); + setPacientesComRelatorios(pacientes); + setMedicosComRelatorios(medicos); + }; + if (RelatoriosFiltrados.length > 0) fetchRelData(); + else { + setPacientesComRelatorios([]); + setMedicosComRelatorios([]); } - ListarPacientes() - - }, [RelatoriosFiltrados, authHeader]); - // NOVO: useEffect para logar PacientesComRelatorios após a atualização - useEffect(() => { - console.log(PacientesComRelatorios, 'aqui') - }, [PacientesComRelatorios]) - - // 2º useEffect: Busca a lista de relatórios - useEffect(() => { - var myHeaders = new Headers(); -myHeaders.append("apikey", API_KEY); -myHeaders.append("Authorization", authHeader); -var requestOptions = { - method: 'GET', - headers: myHeaders, - redirect: 'follow' -}; -fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&status", requestOptions) - .then(response => response.json()) - .then(data => { setRelatorios(data); console.log(data) }) - .catch(error => console.log('error', error)); - }, [authHeader]) - const BaixarPDFdoRelatorio = (nome_paciente) => { - const elemento = document.getElementById("folhaA4"); // tua div do relatório - const opt = { - margin: 0, - filename: `relatorio_${nome_paciente || "paciente"}.pdf`, - html2canvas: { scale: 2 }, - jsPDF: { unit: "mm", format: "a4", orientation: "portrait" }, + }, [RelatoriosFiltrados, authHeader]); + + const BaixarPDFdoRelatorio = (nome_paciente) => { + const elemento = document.getElementById("folhaA4"); + const opt = { margin: 0, filename: `relatorio_${nome_paciente || "paciente"}.pdf`, html2canvas: { scale: 2 }, jsPDF: { unit: "mm", format: "a4", orientation: "portrait" } }; + html2pdf().set(opt).from(elemento).save(); }; - html2pdf().set(opt).from(elemento).save(); - } - return ( + + return (
{showModal && ( -
-
-
-
-
Relatório de {PacientesComRelatorios[index]?.full_name}
- -
-
-
-
-

Clinica Rise up

-

Dr - CRM/SP 123456

-

Avenida - (79) 9 4444-4444

-
-
-

Paciente: {PacientesComRelatorios[index]?.full_name}

-

Data de nascimento: {PacientesComRelatorios[index]?.birth_date}

-

Data do exame: {}

-

Exame: {RelatoriosFiltrados[index]?.exam}

- {/* INÍCIO DA MUDANÇA (da resposta anterior) */} -

Conteúdo do Relatório:

- - {/* FIM DA MUDANÇA */} -
-
-

Dr {RelatoriosFiltrados[index]?.required_by}

-

Emitido em: 0

-
+
+
+
+
+
Relatório de {PacientesComRelatorios[index]?.full_name}
+ +
+
+
+
+

Clinica Rise up

+

Dr - CRM/SP 123456

+

Avenida - (79) 9 4444-4444

+
+ +
+

Paciente: {PacientesComRelatorios[index]?.full_name}

+

Data de nascimento: {PacientesComRelatorios[index]?.birth_date}

+

Data do exame: {RelatoriosFiltrados[index]?.due_at || ''}

+ {/* Exibe conteúdo salvo (content_html) */} +

Conteúdo do Relatório:

+ +
+ +
+

Dr {MedicosComRelatorios[index]?.full_name || RelatoriosFiltrados[index]?.requested_by}

+

Emitido em: {RelatoriosFiltrados[index]?.created_at || '—'}

-
- - -
+
+
+ +
+
)} -
-

Lista de Relatórios

-
+ +

Lista de Relatórios

@@ -132,114 +133,59 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&statu

Relatórios Cadastrados

- +
-
- {" "} - Filtros -
-
- +
Filtros
+
+
+
- - - - + {RelatoriosFiltrados.length > 0 ? ( - RelatoriosFiltrados.map((relatorio, index) => ( + RelatoriosFiltrados.map((relatorio, idx) => ( - - - - - - + + - )) ) : ( - - - + )}
PacienteCPFExameDoutor
{PacientesComRelatorios[index]?.full_name}{PacientesComRelatorios[index]?.cpf}{relatorio.exam}{PacientesComRelatorios[idx]?.full_name}{MedicosComRelatorios[idx]?.full_name || relatorio.requested_by || '-'}
- - - - - - -
- + + + +
- Nenhum paciente encontrado. -
Nenhum paciente encontrado.
+
- ) -} -export default DoctorRelatorioManager \ No newline at end of file + ); +}; + +export default DoctorRelatorioManager; diff --git a/src/PagesMedico/EditPageRelatorio.jsx b/src/PagesMedico/EditPageRelatorio.jsx index c83ed9f..741da1e 100644 --- a/src/PagesMedico/EditPageRelatorio.jsx +++ b/src/PagesMedico/EditPageRelatorio.jsx @@ -1,172 +1,153 @@ -import React, { useEffect, useState } from 'react' -import { useParams, useNavigate } from 'react-router-dom' -import API_KEY from '../components/utils/apiKeys' -import { useAuth } from '../components/utils/AuthProvider' -import TiptapEditor from '../PagesMedico/TiptapEditor' -import { GetPatientByID } from '../components/utils/Functions-Endpoints/Patient' +// EditPageRelatorio.jsx +import React, { useEffect, useState } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import API_KEY from '../components/utils/apiKeys'; +import { useAuth } from '../components/utils/AuthProvider'; +import TiptapEditor from '../PagesMedico/TiptapEditor'; +import { GetPatientByID } from '../components/utils/Functions-Endpoints/Patient'; +import { GetDoctorByID } from '../components/utils/Functions-Endpoints/Doctor'; const EditPageRelatorio = () => { - const params = useParams() - const navigate = useNavigate() - const {getAuthorizationHeader} = useAuth() - let authHeader = getAuthorizationHeader() - - const [relatorioData, setRelatorioData] = useState({ - patient_id: '', - exam: '', - // Mantemos apenas os campos necessários para o fetch, mas não para edição direta na UI - required_by: '', - address_line: '', - content: '', - }) - const [loading, setLoading] = useState(true) - const [patientData, setPatientData] = useState(null) // Armazena dados do paciente - const RelatorioID = params.id - - // Modelo HTML do relatório para ser carregado no Tiptap se o conteúdo for novo/vazio - const generateReportModel = (report, patient) => { - // Escapa as aspas se necessário, mas para HTML simples não é crucial - const patientName = patient?.full_name || 'Paciente não encontrado'; - const birthDate = patient?.birth_date || 'Data não informada'; - const exam = report?.exam || 'Exame não especificado'; + const params = useParams(); + const navigate = useNavigate(); + const { getAuthorizationHeader } = useAuth(); + const authHeader = getAuthorizationHeader(); + const [loading, setLoading] = useState(true); + const [report, setReport] = useState(null); + const [patient, setPatient] = useState(null); + const [doctor, setDoctor] = useState(null); + const [html, setHtml] = useState(''); + const generateTemplate = (r = {}, p = {}, d = {}) => { + const patientName = p?.full_name || '[NOME DO PACIENTE]'; + const birthDate = p?.birth_date || ''; + const exam = r?.exam || ''; + const doctorName = d?.full_name || r?.requested_by || ''; return `
-

Clinica Rise up

-

Dr - CRM/SP 123456

-

Avenida - (79) 9 4444-4444

-
+

Clinica Rise up

+

Dr - CRM/SP 123456

+

Avenida - (79) 9 4444-4444

+

Paciente: ${patientName}

Data de nascimento: ${birthDate}

-

Data do exame:

+

Data do exame:

Exame: ${exam}

-
-

Conteúdo do Relatório:

-

1

-
-

Dr

+
+

Diagnóstico:

+

${r?.diagnosis || ''}

+
+

Conclusão:

+

${r?.conclusion || ''}

+
+

Dr ${doctorName}

Emitido em: 0

`; }; - - // Função que será chamada ao salvar - const handleSave = () => { - setLoading(true) - var myHeaders = new Headers(); - myHeaders.append("apikey", API_KEY); - myHeaders.append("Authorization", authHeader); - myHeaders.append("Content-Type", "application/json"); - // Salva apenas o novo conteúdo do Tiptap (relatorioData.content) - const raw = JSON.stringify({ - content: relatorioData.content, - // Você pode manter order_number ou removê-lo se não for editável - order_number: relatorioData.order_number || 'REL-2025-4386' - }) - - var requestOptions = { - method: 'PATCH', - headers: myHeaders, - body: raw, - redirect: 'follow' - }; - fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?id=eq.${RelatorioID}`, requestOptions) - .then(response => response.text()) - .then(result => { - console.log(result); - alert('Relatório atualizado com sucesso!'); - setLoading(false) - // MANTIDO: Volta para a área de relatórios - navigate('/medico/relatorios') - }) - .catch(error => { - console.log('error', error); - alert('Erro ao atualizar o relatório.'); - setLoading(false) - }); - } - - // Busca os dados do Relatório e do Paciente useEffect(() => { - const fetchReportData = async () => { - var myHeaders = new Headers(); + const load = async () => { + setLoading(true); + try { + const myHeaders = new Headers(); myHeaders.append("apikey", API_KEY); myHeaders.append("Authorization", authHeader); - var requestOptions = { - method: 'GET', - headers: myHeaders, - redirect: 'follow' - }; - let report; - let patient; - try { - const response = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?id=eq.${RelatorioID}`, requestOptions); - const result = await response.json(); - - if (result.length > 0) { - report = result[0]; - - // Busca nome do paciente - const patientResult = await GetPatientByID(report.patient_id, authHeader); - if (patientResult.length > 0) { - patient = patientResult[0]; - setPatientData(patient); - } + const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; - // Determina o conteúdo inicial - let initialContent = report.content || report.diagnosis || report.conclusion || ''; - - // Se o conteúdo estiver vazio, carrega o modelo do relatório completo - if (!initialContent.trim()) { - initialContent = generateReportModel(report, patient); - } + // Pega relatório por id (supabase geralmente retorna array para ?id=eq.X) + const resp = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?id=eq.${params.id}`, requestOptions); + const data = await resp.json(); + const rep = Array.isArray(data) ? data[0] : data; + if (!rep) throw new Error('Relatório não encontrado'); - setRelatorioData({ - ...report, - content: initialContent, - }); - } - } catch (error) { - console.log('error', error); - } finally { - setLoading(false) + setReport(rep); + + // busca paciente + if (rep.patient_id) { + const p = await GetPatientByID(rep.patient_id, authHeader); + setPatient(Array.isArray(p) ? p[0] : p); } + + // busca doctor se tiver created_by/requested_by id (tentamos fallback) + if (rep.created_by) { + try { + const d = await GetDoctorByID(rep.created_by, authHeader); + setDoctor(Array.isArray(d) ? d[0] : d); + } catch (e) { + // ignore + } + } + + // content_html preferencial + let initial = rep.content_html || rep.content || rep.diagnosis || rep.conclusion || ''; + if (!initial || initial.trim() === '') { + initial = generateTemplate(rep, patient || {}, doctor || {}); + } + setHtml(initial); + } catch (err) { + console.error('Erro carregar relatório', err); + alert('Erro ao carregar relatório. Veja console.'); + } finally { + setLoading(false); + } + }; + load(); + // eslint-disable-next-line + }, [params.id, authHeader]); + + const handleSave = async () => { + setLoading(true); + try { + const myHeaders = new Headers(); + myHeaders.append('apikey', API_KEY); + myHeaders.append('Authorization', authHeader); + myHeaders.append('Content-Type', 'application/json'); + + const body = JSON.stringify({ content_html: html }); + + // supabase: PATCH via query id=eq. + const res = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?id=eq.${params.id}`, { + method: 'PATCH', + headers: myHeaders, + body + }); + + if (!res.ok) { + const txt = await res.text(); + console.error('Erro PATCH', res.status, txt); + throw new Error('Erro na API'); + } + + alert('Relatório atualizado com sucesso!'); + navigate('/medico/relatorios'); + } catch (err) { + console.error(err); + alert('Erro ao salvar. Veja console.'); + } finally { + setLoading(false); } - fetchReportData() - }, [RelatorioID, authHeader]) + }; - // Função para atualizar o HTML do editor - const handleEditorChange = (newHtml) => { - setRelatorioData(prev => ({ ...prev, content: newHtml })) - } - - if (loading) { - return
Carregando...
- } + if (loading) return
Carregando...
; return (
- {/* MANTIDO: Título limpo */} -

Editar Relatório do Paciente: {patientData?.full_name}

- - {/* MUDANÇA: Removidos todos os inputs de texto avulsos */} +

Editar Relatório do Paciente: {patient?.full_name || '...'}

- {/* Campo do Tiptap Editor */}
- {/* MUDANÇA: Título ajustado */} -
Conteúdo do Relatório
- +
Conteúdo do Relatório
+ setHtml(newHtml)} />
- - -
- ) -} -export default EditPageRelatorio \ No newline at end of file +
+ +
+
+ ); +}; + +export default EditPageRelatorio; + diff --git a/src/PagesMedico/FormNovoRelatorio.jsx b/src/PagesMedico/FormNovoRelatorio.jsx index 3691793..44bff89 100644 --- a/src/PagesMedico/FormNovoRelatorio.jsx +++ b/src/PagesMedico/FormNovoRelatorio.jsx @@ -1,44 +1,243 @@ +import React, { useEffect, useState, useRef } from 'react'; +import { useNavigate } from 'react-router-dom'; +import API_KEY from '../components/utils/apiKeys'; +import { useAuth } from '../components/utils/AuthProvider'; +import TiptapEditor from './TiptapEditor'; +import { GetAllPatients, GetPatientByID } from '../components/utils/Functions-Endpoints/Patient'; +import { GetAllDoctors, GetDoctorByID } from '../components/utils/Functions-Endpoints/Doctor'; +import './styleMedico/FormNovoRelatorio.css'; -import '../PagesMedico/styleMedico/FormNovoRelatorio.css' -import API_KEY from '../components/utils/apiKeys' -import FormRelatorio from '../components/FormRelatorio' -import { useState } from 'react' -import { useAuth } from '../components/utils/AuthProvider' const FormNovoRelatorio = () => { - const [DictInfo, setDictInfo] = useState({}) + const { getAuthorizationHeader } = useAuth(); + const authHeader = getAuthorizationHeader(); + const navigate = useNavigate(); - const {getAuthorizationHeader} = useAuth() - let authHeader = getAuthorizationHeader() + const [patients, setPatients] = useState([]); + const [doctors, setDoctors] = useState([]); + const [loadingPatients, setLoadingPatients] = useState(true); + const [loadingDoctors, setLoadingDoctors] = useState(true); - const handleSave = (data) => { - console.log("Relatório salvo:", data); - - var myHeaders = new Headers(); -myHeaders.append("apikey", API_KEY); -myHeaders.append("Authorization", authHeader); -myHeaders.append("Content-Type", "application/json"); + // formulário + const [form, setForm] = useState({ + patient_id: '', + patient_name: '', + patient_birth: '', + doctor_id: '', + doctor_name: '', + contentHtml: '', + }); -var raw = JSON.stringify({...data}); + // campos de busca (texto) + const [patientQuery, setPatientQuery] = useState(''); + const [doctorQuery, setDoctorQuery] = useState(''); -var requestOptions = { - method: 'POST', - headers: myHeaders, - body: raw, - redirect: 'follow' + // dropdown control + const [showPatientDropdown, setShowPatientDropdown] = useState(false); + const [showDoctorDropdown, setShowDoctorDropdown] = useState(false); + + const patientRef = useRef(); + const doctorRef = useRef(); + + useEffect(() => { + // carregar pacientes + let mounted = true; + const loadPatients = async () => { + setLoadingPatients(true); + try { + const list = await GetAllPatients(authHeader); + if (mounted && Array.isArray(list)) setPatients(list); + } catch (err) { + console.error('Erro GetAllPatients:', err); + } finally { + if (mounted) setLoadingPatients(false); + } + }; + const loadDoctors = async () => { + setLoadingDoctors(true); + try { + const list = await GetAllDoctors(authHeader); + if (mounted && Array.isArray(list)) setDoctors(list); + } catch (err) { + console.error('Erro GetAllDoctors:', err); + } finally { + if (mounted) setLoadingDoctors(false); + } + }; + loadPatients(); + loadDoctors(); + return () => { mounted = false; }; + }, [authHeader]); + + // fechar dropdowns quando clicar fora + useEffect(() => { + const handleClick = (e) => { + if (patientRef.current && !patientRef.current.contains(e.target)) setShowPatientDropdown(false); + if (doctorRef.current && !doctorRef.current.contains(e.target)) setShowDoctorDropdown(false); + }; + document.addEventListener('click', handleClick); + return () => document.removeEventListener('click', handleClick); + }, []); + + const generateTemplate = (patientName = '', birthDate = '', doctorName = '') => { + return ` +
+

Clinica Rise up

+

Dr - CRM/SP 123456

+

Avenida - (79) 9 4444-4444

+
+

Paciente: ${patientName}

+

Data de nascimento: ${birthDate}

+

Data do exame:

+

Exame:

+
+

Diagnóstico:

+

+
+

Conclusão:

+

+
+

Dr ${doctorName}

+

Emitido em: 0

+
+ `; + }; + + // escolher paciente (clicando na lista) + const choosePatient = async (patient) => { + setForm(prev => ({ + ...prev, + patient_id: patient.id, + patient_name: patient.full_name || '', + patient_birth: patient.birth_date || '', + contentHtml: generateTemplate(patient.full_name || '', patient.birth_date || '', form.doctor_name) + })); + setPatientQuery(''); + setShowPatientDropdown(false); + }; + + const chooseDoctor = (doctor) => { + setForm(prev => ({ + ...prev, + doctor_id: doctor.id, + doctor_name: doctor.full_name || '', + contentHtml: generateTemplate(form.patient_name, form.patient_birth, doctor.full_name || '') + })); + setDoctorQuery(''); + setShowDoctorDropdown(false); + }; + + // filtrar pela query (startsWith) + const filteredPatients = patientQuery + ? patients.filter(p => (p.full_name || '').toLowerCase().startsWith(patientQuery.toLowerCase())).slice(0, 40) + : []; + + const filteredDoctors = doctorQuery + ? doctors.filter(d => (d.full_name || '').toLowerCase().startsWith(doctorQuery.toLowerCase())).slice(0, 40) + : []; + + const handleEditorChange = (html) => setForm(prev => ({ ...prev, contentHtml: html })); + + // salvar novo relatório + const handleSubmit = async (e) => { + e.preventDefault(); + if (!form.patient_id) return alert('Selecione o paciente (clicando no item) antes de salvar.'); + if (!form.doctor_id) return alert('Selecione o médico (clicando no item) antes de salvar.'); + + try { + const myHeaders = new Headers(); + myHeaders.append('apikey', API_KEY); + myHeaders.append('Authorization', authHeader); + myHeaders.append('Content-Type', 'application/json'); + + const body = JSON.stringify({ + patient_id: form.patient_id, + content: form.contentHtml, + content_html: form.contentHtml, + requested_by: form.doctor_name || '', + created_by: form.doctor_id || null, + status: 'draft' + }); + + const res = await fetch('https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports', { + method: 'POST', + headers: myHeaders, + body, + }); + + if (!res.ok) { + const txt = await res.text(); + console.error('Erro POST criar relatório:', res.status, txt); + // mostra mensagem mais útil + return alert(`Erro ao criar relatório (ver console). Status ${res.status}`); + } + + alert('Relatório criado com sucesso!'); + navigate('/medico/relatorios'); + } catch (err) { + console.error('Erro salvar relatório:', err); + alert('Erro ao salvar relatório. Veja console.'); + } + }; + + return ( +
+

Criar Novo Relatório

+ +
+
+
+ + { setPatientQuery(e.target.value); setShowPatientDropdown(true); }} + onFocus={() => setShowPatientDropdown(true)} + /> + {showPatientDropdown && patientQuery && ( +
    + {filteredPatients.length > 0 ? filteredPatients.map(p => ( +
  • choosePatient(p)}> + {p.full_name} {p.cpf ? `- ${p.cpf}` : ''} +
  • + )) :
  • Nenhum paciente começando com "{patientQuery}"
  • } +
+ )} +
Clique no paciente desejado para selecioná-lo e preencher o template.
+
+ +
+ + { setDoctorQuery(e.target.value); setShowDoctorDropdown(true); }} + onFocus={() => setShowDoctorDropdown(true)} + /> + {showDoctorDropdown && doctorQuery && ( +
    + {filteredDoctors.length > 0 ? filteredDoctors.map(d => ( +
  • chooseDoctor(d)}> + {d.full_name} {d.crm ? `- CRM ${d.crm}` : ''} +
  • + )) :
  • Nenhum médico começando com "{doctorQuery}"
  • } +
+ )} +
Clique no médico desejado para selecioná-lo.
+
+ +
+ +
+
+ +
+
Conteúdo do Relatório (edite tudo aqui)
+ + +
+ ); }; -fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports", requestOptions) - .then(response => response.text()) - .then(result => console.log(result)) - .catch(error => console.log('error', error)); - } - - return ( -
-

Criar Novo Relatorio

- -
- ) -} - -export default FormNovoRelatorio \ No newline at end of file +export default FormNovoRelatorio; diff --git a/src/PagesMedico/TiptapEditor.jsx b/src/PagesMedico/TiptapEditor.jsx index 7194562..6983e40 100644 --- a/src/PagesMedico/TiptapEditor.jsx +++ b/src/PagesMedico/TiptapEditor.jsx @@ -1,74 +1,55 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useEditor, EditorContent } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import Link from '@tiptap/extension-link'; -// Componente da barra de menu (Menu Bar) + +// MenuBar simples const MenuBar = ({ editor }) => { - if (!editor) { - return null; - } - // Estilos simples para os botões. Você pode e deve estilizar melhor com CSS/Bootstrap. - const buttonStyle = { - marginRight: '4px', - padding: '4px 8px', - cursor: 'pointer', - border: '1px solid #ccc', - borderRadius: '4px', - backgroundColor: editor.isActive('bold') || editor.isActive('italic') ? '#ddd' : 'white', - }; + if (!editor) return null; + const btn = { marginRight: '6px', padding: '4px 8px', cursor: 'pointer', border: '1px solid #ccc', borderRadius: 4 }; return ( -
- - - - - {/* Adicione mais botões conforme a necessidade (link, código, etc.) */} +
+ + + + +
); }; -// Componente principal do Editor + const TiptapEditor = ({ content, onChange }) => { const editor = useEditor({ extensions: [ - StarterKit.configure({ - // Desativa 'hardBreak' e 'blockquote' se não forem necessários para simplificar - hardBreak: false, - }), - Link, // Adiciona suporte para links + StarterKit.configure({ hardBreak: false }), + Link, ], content: content || '

Inicie o relatório aqui...

', onUpdate: ({ editor }) => { - // Quando o conteúdo muda, chama a função onChange com o HTML - onChange(editor.getHTML()); + onChange && onChange(editor.getHTML()); }, }); + + // Se o pai mudar 'content', atualizamos o editor + useEffect(() => { + if (!editor) return; + // Só setContent se for diferente para evitar perda de edição + try { + const current = editor.getHTML(); + if ((content || '').trim() && content !== current) { + editor.commands.setContent(content); + } + } catch (e) { + // ignore + } + }, [editor, content]); + return ( -
+
- +
); }; -export default TiptapEditor; \ No newline at end of file + +export default TiptapEditor; diff --git a/src/components/utils/Functions-Endpoints/Doctor.js b/src/components/utils/Functions-Endpoints/Doctor.js index 2d6046f..1fd4b42 100644 --- a/src/components/utils/Functions-Endpoints/Doctor.js +++ b/src/components/utils/Functions-Endpoints/Doctor.js @@ -1,26 +1,25 @@ -import API_KEY from "../apiKeys"; - - - -const GetDoctorByID = async (ID,authHeader) => { - - console.log(authHeader, 'mostrando autorização dentro da função') +import API_KEY from '../apiKeys'; +const GetDoctorByID = async (ID, authHeader) => { var myHeaders = new Headers(); - myHeaders.append('apikey', API_KEY) - myHeaders.append('Authorization', authHeader) + myHeaders.append('apikey', API_KEY); + if (authHeader) myHeaders.append('Authorization', authHeader); - var requestOptions = { - method: 'GET', - redirect: 'follow', - headers:myHeaders + const requestOptions = { method: 'GET', redirect: 'follow', headers: myHeaders }; + const res = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors?id=eq.${ID}`, requestOptions); + const DictMedico = await res.json(); + return DictMedico; }; +const GetAllDoctors = async (authHeader) => { + var myHeaders = new Headers(); + myHeaders.append('apikey', API_KEY); + if (authHeader) myHeaders.append('Authorization', authHeader); -const result = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors?id=eq.${ID}`, requestOptions) -const DictMedico = await result.json() -return DictMedico + const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; + const res = await fetch('https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors?select=id,full_name,crm&limit=500', requestOptions); + const DictMedicos = await res.json(); + return DictMedicos; +}; -} - -export {GetDoctorByID} \ No newline at end of file +export { GetDoctorByID, GetAllDoctors };