fix: reorganize files into components

This commit is contained in:
M-Gabrielly 2025-11-05 00:28:16 -03:00
parent 21636401b3
commit 34e2f4d05b
34 changed files with 135 additions and 898 deletions

773
package-lock.json generated
View File

@ -1,773 +0,0 @@
{
"name": "riseup-squad20",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@headlessui/react": "^2.2.7",
"@heroicons/react": "^2.2.0",
"@supabase/supabase-js": "^2.75.0",
"date-fns": "^4.1.0",
"react-big-calendar": "^1.19.4",
"react-signature-canvas": "^1.1.0-alpha.2"
}
},
"node_modules/@babel/runtime": {
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@floating-ui/core": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
"integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.7.3",
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/react": {
"version": "0.26.28",
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz",
"integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==",
"license": "MIT",
"dependencies": {
"@floating-ui/react-dom": "^2.1.2",
"@floating-ui/utils": "^0.2.8",
"tabbable": "^6.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@floating-ui/react-dom": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
"integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.7.4"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
"license": "MIT"
},
"node_modules/@headlessui/react": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.7.tgz",
"integrity": "sha512-WKdTymY8Y49H8/gUc/lIyYK1M+/6dq0Iywh4zTZVAaiTDprRfioxSgD0wnXTQTBpjpGJuTL1NO/mqEvc//5SSg==",
"license": "MIT",
"dependencies": {
"@floating-ui/react": "^0.26.16",
"@react-aria/focus": "^3.20.2",
"@react-aria/interactions": "^3.25.0",
"@tanstack/react-virtual": "^3.13.9",
"use-sync-external-store": "^1.5.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": "^18 || ^19 || ^19.0.0-rc",
"react-dom": "^18 || ^19 || ^19.0.0-rc"
}
},
"node_modules/@heroicons/react": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz",
"integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
"license": "MIT",
"peerDependencies": {
"react": ">= 16 || ^19.0.0-rc"
}
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@react-aria/focus": {
"version": "3.21.1",
"resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.21.1.tgz",
"integrity": "sha512-hmH1IhHlcQ2lSIxmki1biWzMbGgnhdxJUM0MFfzc71Rv6YAzhlx4kX3GYn4VNcjCeb6cdPv4RZ5vunV4kgMZYQ==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/interactions": "^3.25.5",
"@react-aria/utils": "^3.30.1",
"@react-types/shared": "^3.32.0",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/interactions": {
"version": "3.25.5",
"resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.5.tgz",
"integrity": "sha512-EweYHOEvMwef/wsiEqV73KurX/OqnmbzKQa2fLxdULbec5+yDj6wVGaRHIzM4NiijIDe+bldEl5DG05CAKOAHA==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/ssr": "^3.9.10",
"@react-aria/utils": "^3.30.1",
"@react-stately/flags": "^3.1.2",
"@react-types/shared": "^3.32.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/ssr": {
"version": "3.9.10",
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz",
"integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"engines": {
"node": ">= 12"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/utils": {
"version": "3.30.1",
"resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.30.1.tgz",
"integrity": "sha512-zETcbDd6Vf9GbLndO6RiWJadIZsBU2MMm23rBACXLmpRztkrIqPEb2RVdlLaq1+GklDx0Ii6PfveVjx+8S5U6A==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/ssr": "^3.9.10",
"@react-stately/flags": "^3.1.2",
"@react-stately/utils": "^3.10.8",
"@react-types/shared": "^3.32.0",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/flags": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.1.2.tgz",
"integrity": "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@react-stately/utils": {
"version": "3.10.8",
"resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz",
"integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/shared": {
"version": "3.32.0",
"resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz",
"integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==",
"license": "Apache-2.0",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@restart/hooks": {
"version": "0.4.16",
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
"integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
"license": "MIT",
"dependencies": {
"dequal": "^2.0.3"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@supabase/auth-js": {
"version": "2.75.0",
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.75.0.tgz",
"integrity": "sha512-J8TkeqCOMCV4KwGKVoxmEBuDdHRwoInML2vJilthOo7awVCro2SM+tOcpljORwuBQ1vHUtV62Leit+5wlxrNtw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "2.6.15"
}
},
"node_modules/@supabase/functions-js": {
"version": "2.75.0",
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.75.0.tgz",
"integrity": "sha512-18yk07Moj/xtQ28zkqswxDavXC3vbOwt1hDuYM3/7xPnwwpKnsmPyZ7bQ5th4uqiJzQ135t74La9tuaxBR6e7w==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "2.6.15"
}
},
"node_modules/@supabase/node-fetch": {
"version": "2.6.15",
"resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
"integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/@supabase/postgrest-js": {
"version": "2.75.0",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.75.0.tgz",
"integrity": "sha512-YfBz4W/z7eYCFyuvHhfjOTTzRrQIvsMG2bVwJAKEVVUqGdzqfvyidXssLBG0Fqlql1zJFgtsPpK1n4meHrI7tg==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "2.6.15"
}
},
"node_modules/@supabase/realtime-js": {
"version": "2.75.0",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.75.0.tgz",
"integrity": "sha512-B4Xxsf2NHd5cEnM6MGswOSPSsZKljkYXpvzKKmNxoUmNQOfB7D8HOa6NwHcUBSlxcjV+vIrYKcYXtavGJqeGrw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "2.6.15",
"@types/phoenix": "^1.6.6",
"@types/ws": "^8.18.1",
"ws": "^8.18.2"
}
},
"node_modules/@supabase/storage-js": {
"version": "2.75.0",
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.75.0.tgz",
"integrity": "sha512-wpJMYdfFDckDiHQaTpK+Ib14N/O2o0AAWWhguKvmmMurB6Unx17GGmYp5rrrqCTf8S1qq4IfIxTXxS4hzrUySg==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "2.6.15"
}
},
"node_modules/@supabase/supabase-js": {
"version": "2.75.0",
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.75.0.tgz",
"integrity": "sha512-8UN/vATSgS2JFuJlMVr51L3eUDz+j1m7Ww63wlvHLKULzCDaVWYzvacCjBTLW/lX/vedI2LBI4Vg+01G9ufsJQ==",
"license": "MIT",
"dependencies": {
"@supabase/auth-js": "2.75.0",
"@supabase/functions-js": "2.75.0",
"@supabase/node-fetch": "2.6.15",
"@supabase/postgrest-js": "2.75.0",
"@supabase/realtime-js": "2.75.0",
"@supabase/storage-js": "2.75.0"
}
},
"node_modules/@swc/helpers": {
"version": "0.5.17",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
"integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.8.0"
}
},
"node_modules/@tanstack/react-virtual": {
"version": "3.13.12",
"resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz",
"integrity": "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==",
"license": "MIT",
"dependencies": {
"@tanstack/virtual-core": "3.13.12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@tanstack/virtual-core": {
"version": "3.13.12",
"resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.12.tgz",
"integrity": "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@types/node": {
"version": "24.7.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.7.1.tgz",
"integrity": "sha512-CmyhGZanP88uuC5GpWU9q+fI61j2SkhO3UGMUdfYRE6Bcy0ccyzn1Rqj9YAB/ZY4kOXmNf0ocah5GtphmLMP6Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.14.0"
}
},
"node_modules/@types/phoenix": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz",
"integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==",
"license": "MIT"
},
"node_modules/@types/react": {
"version": "19.1.12",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz",
"integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==",
"license": "MIT",
"dependencies": {
"csstype": "^3.0.2"
}
},
"node_modules/@types/signature_pad": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/@types/signature_pad/-/signature_pad-2.3.6.tgz",
"integrity": "sha512-v3j92gCQJoxomHhd+yaG4Vsf8tRS/XbzWKqDv85UsqjMGy4zhokuwKe4b6vhbgncKkh+thF+gpz6+fypTtnFqQ==",
"license": "MIT"
},
"node_modules/@types/warning": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
"integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==",
"license": "MIT"
},
"node_modules/@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
"node_modules/date-arithmetic": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/date-arithmetic/-/date-arithmetic-4.1.0.tgz",
"integrity": "sha512-QWxYLR5P/6GStZcdem+V1xoto6DMadYWpMXU82ES3/RfR3Wdwr3D0+be7mgOJ+Ov0G9D5Dmb9T17sNLQYj9XOg==",
"license": "MIT"
},
"node_modules/date-fns": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/dayjs": {
"version": "1.11.18",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz",
"integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==",
"license": "MIT"
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/dom-helpers": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
}
},
"node_modules/globalize": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/globalize/-/globalize-0.1.1.tgz",
"integrity": "sha512-5e01v8eLGfuQSOvx2MsDMOWS0GFtCx1wPzQSmcHw4hkxFzrQDBO3Xwg/m8Hr/7qXMrHeOIE29qWVzyv06u1TZA=="
},
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT"
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/luxon": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
"integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
"license": "MIT"
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/moment-timezone": {
"version": "0.5.48",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz",
"integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
"license": "MIT",
"dependencies": {
"moment": "^2.29.4"
},
"engines": {
"node": "*"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
}
},
"node_modules/react": {
"version": "19.1.1",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-big-calendar": {
"version": "1.19.4",
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.19.4.tgz",
"integrity": "sha512-FrvbDx2LF6JAWFD96LU1jjloppC5OgIvMYUYIPzAw5Aq+ArYFPxAjLqXc4DyxfsQDN0TJTMuS/BIbcSB7Pg0YA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.20.7",
"clsx": "^1.2.1",
"date-arithmetic": "^4.1.0",
"dayjs": "^1.11.7",
"dom-helpers": "^5.2.1",
"globalize": "^0.1.1",
"invariant": "^2.2.4",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"luxon": "^3.2.1",
"memoize-one": "^6.0.0",
"moment": "^2.29.4",
"moment-timezone": "^0.5.40",
"prop-types": "^15.8.1",
"react-overlays": "^5.2.1",
"uncontrollable": "^7.2.1"
},
"peerDependencies": {
"react": "^16.14.0 || ^17 || ^18 || ^19",
"react-dom": "^16.14.0 || ^17 || ^18 || ^19"
}
},
"node_modules/react-big-calendar/node_modules/clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/react-dom": {
"version": "19.1.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.26.0"
},
"peerDependencies": {
"react": "^19.1.1"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"license": "MIT"
},
"node_modules/react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
"license": "MIT"
},
"node_modules/react-overlays": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz",
"integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.8",
"@popperjs/core": "^2.11.6",
"@restart/hooks": "^0.4.7",
"@types/warning": "^3.0.0",
"dom-helpers": "^5.2.0",
"prop-types": "^15.7.2",
"uncontrollable": "^7.2.1",
"warning": "^4.0.3"
},
"peerDependencies": {
"react": ">=16.3.0",
"react-dom": ">=16.3.0"
}
},
"node_modules/react-signature-canvas": {
"version": "1.1.0-alpha.2",
"resolved": "https://registry.npmjs.org/react-signature-canvas/-/react-signature-canvas-1.1.0-alpha.2.tgz",
"integrity": "sha512-tKUNk3Gmh04Ug4K8p5g8Is08BFUKvbXxi0PyetQ/f8OgCBzcx4vqNf9+OArY/TdNdfHtswXQNRwZD6tyELjkjQ==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.17.9",
"@types/signature_pad": "^2.3.0",
"signature_pad": "^2.3.2",
"trim-canvas": "^0.1.0"
},
"funding": {
"url": "https://github.com/sponsors/agilgur5"
},
"peerDependencies": {
"@types/prop-types": "^15.7.3",
"@types/react": "0.14 - 19",
"prop-types": "^15.5.8",
"react": "0.14 - 19",
"react-dom": "0.14 - 19"
},
"peerDependenciesMeta": {
"@types/prop-types": {
"optional": true
},
"@types/react": {
"optional": true
}
}
},
"node_modules/scheduler": {
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
"license": "MIT",
"peer": true
},
"node_modules/signature_pad": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-2.3.2.tgz",
"integrity": "sha512-peYXLxOsIY6MES2TrRLDiNg2T++8gGbpP2yaC+6Ohtxr+a2dzoaqWosWDY9sWqTAAk6E/TyQO+LJw9zQwyu5kA==",
"license": "MIT"
},
"node_modules/tabbable": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
"license": "MIT"
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/trim-canvas": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/trim-canvas/-/trim-canvas-0.1.2.tgz",
"integrity": "sha512-nd4Ga3iLFV94mdhW9JFMLpQbHUyCQuhFOD71PEAt1NjtMD5wbZctzhX8c3agHNybMR5zXD1XTGoIEWk995E6pQ==",
"license": "Apache-2.0"
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/uncontrollable": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
"integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.6.3",
"@types/react": ">=16.9.11",
"invariant": "^2.2.4",
"react-lifecycles-compat": "^3.0.4"
},
"peerDependencies": {
"react": ">=15.0.0"
}
},
"node_modules/undici-types": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz",
"integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==",
"license": "MIT"
},
"node_modules/use-sync-external-store": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/ws": {
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
}
}

View File

@ -1,9 +1,9 @@
"use client";
import { useRouter } from "next/navigation";
import { CalendarRegistrationForm } from "@/components/forms/calendar-registration-form";
import HeaderAgenda from "@/components/agenda/HeaderAgenda";
import FooterAgenda from "@/components/agenda/FooterAgenda";
import { CalendarRegistrationForm } from "@/components/features/forms/calendar-registration-form";
import HeaderAgenda from "@/components/features/agenda/HeaderAgenda";
import FooterAgenda from "@/components/features/agenda/FooterAgenda";
import { useState } from "react";
import { criarAgendamento } from '@/lib/api';
import { toast } from '@/hooks/use-toast';

View File

@ -10,8 +10,8 @@ import { EventManager, type Event } from "@/components/event-manager";
import { v4 as uuidv4 } from 'uuid'; // Usado para IDs de fallback
// Imports mantidos
import { Sidebar } from "@/components/dashboard/sidebar";
import { PagesHeader } from "@/components/dashboard/header";
import { Sidebar } from "@/components/layout/sidebar";
import { PagesHeader } from "@/components/features/dashboard/header";
import { Button } from "@/components/ui/button";
import { mockWaitingList } from "@/lib/mocks/appointment-mocks";
import "./index.css";
@ -24,7 +24,7 @@ import {
import { ThreeDWallCalendar, CalendarEvent } from "@/components/ui/three-dwall-calendar"; // Calendário 3D mantido
const ListaEspera = dynamic(
() => import("@/components/agendamento/ListaEspera"),
() => import("@/components/features/agendamento/ListaEspera"),
{ ssr: false }
);

View File

@ -56,7 +56,7 @@ import {
import { mockProfessionals } from "@/lib/mocks/appointment-mocks";
import { listarAgendamentos, buscarPacientesPorIds, buscarMedicosPorIds, atualizarAgendamento, buscarAgendamentoPorId, deletarAgendamento } from "@/lib/api";
import { CalendarRegistrationForm } from "@/components/forms/calendar-registration-form";
import { CalendarRegistrationForm } from "@/components/features/forms/calendar-registration-form";
const formatDate = (date: string | Date) => {
if (!date) return "";

View File

@ -20,8 +20,8 @@ import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { AlertCircle, Calendar, Users, Stethoscope, Clock, FileText, AlertTriangle, Plus, ArrowLeft } from 'lucide-react';
import Link from 'next/link';
import { PatientRegistrationForm } from '@/components/forms/patient-registration-form';
import { DoctorRegistrationForm } from '@/components/forms/doctor-registration-form';
import { PatientRegistrationForm } from '@/components/features/forms/patient-registration-form';
import { DoctorRegistrationForm } from '@/components/features/forms/doctor-registration-form';
interface DashboardStats {
totalPatients: number;

View File

@ -9,9 +9,9 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Di
import { Label } from "@/components/ui/label";
import { MoreHorizontal, Plus, Search, Edit, Trash2, ArrowLeft, Eye, Users } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { DoctorRegistrationForm } from "@/components/forms/doctor-registration-form";
import AvailabilityForm from '@/components/forms/availability-form'
import ExceptionForm from '@/components/forms/exception-form'
import { DoctorRegistrationForm } from "@/components/features/forms/doctor-registration-form";
import AvailabilityForm from '@/components/features/forms/availability-form'
import ExceptionForm from '@/components/features/forms/exception-form'
import { listarDisponibilidades, DoctorAvailability, deletarDisponibilidade, listarExcecoes, DoctorException, deletarExcecao } from '@/lib/api'

View File

@ -5,8 +5,8 @@ import { useState } from "react";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Calculator, DollarSign } from "lucide-react";
import HeaderAgenda from "@/components/agenda/HeaderAgenda";
import FooterAgenda from "@/components/agenda/FooterAgenda";
import HeaderAgenda from "@/components/features/agenda/HeaderAgenda";
import FooterAgenda from "@/components/features/agenda/FooterAgenda";
export default function FinanceiroPage() {
const router = useRouter();

View File

@ -1,8 +1,8 @@
import type React from "react";
import ProtectedRoute from "@/components/ProtectedRoute";
import { Sidebar } from "@/components/dashboard/sidebar";
import { Sidebar } from "@/components/layout/sidebar";
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import { PagesHeader } from "@/components/dashboard/header";
import { PagesHeader } from "@/components/features/dashboard/header";
export default function MainRoutesLayout({
children,

View File

@ -11,8 +11,8 @@ import { Label } from "@/components/ui/label";
import { MoreHorizontal, Plus, Search, Eye, Edit, Trash2, ArrowLeft } from "lucide-react";
import { Paciente, Endereco, listarPacientes, buscarPacientes, buscarPacientePorId, excluirPaciente } from "@/lib/api";
import { PatientRegistrationForm } from "@/components/forms/patient-registration-form";
import AssignmentForm from "@/components/admin/AssignmentForm";
import { PatientRegistrationForm } from "@/components/features/forms/patient-registration-form";
import AssignmentForm from "@/components/features/admin/AssignmentForm";
function normalizePaciente(p: any): Paciente {

View File

@ -7,8 +7,8 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Search, ChevronDown } from "lucide-react";
import { Plus } from "lucide-react";
import HeaderAgenda from "@/components/agenda/HeaderAgenda";
import FooterAgenda from "@/components/agenda/FooterAgenda";
import HeaderAgenda from "@/components/features/agenda/HeaderAgenda";
import FooterAgenda from "@/components/features/agenda/FooterAgenda";
export default function ProcedimentoPage() {
const router = useRouter();

View File

@ -1491,3 +1491,5 @@ function ListView({
</Card>
)
}
export default EventManager;

View File

@ -3,6 +3,7 @@
import type { ReactNode } from 'react'
import { useState, useEffect, useMemo } from 'react'
import { useRouter } from 'next/navigation'
import Image from 'next/image'
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
@ -908,7 +909,7 @@ export default function PacientePage() {
setSearchingRemote(true)
setRemoteMatch(null)
if (looksLikeId) {
if (looksLikeId && q) { // Adicionada verificação para q não ser vazio
const r = await buscarRelatorioPorId(q).catch(() => null)
if (!mounted) return
if (r) setRemoteMatch(r)
@ -1336,64 +1337,62 @@ export default function PacientePage() {
<Dialog open={!!selectedReport} onOpenChange={open => !open && setSelectedReport(null)}>
<DialogContent>
<DialogHeader>
<DialogTitle>Laudo Médico</DialogTitle>
<DialogDescription>
<DialogTitle>
{selectedReport && (
(() => {
const looksLikeIdStr = (s: any) => {
try {
const hexOnly = String(s || '').replace(/[^0-9a-fA-F]/g, '');
const len = (typeof hexOnly === 'string') ? hexOnly.length : (Number(hexOnly) || 0);
return len >= 8;
} catch { return false; }
};
const maybeId = selectedReport?.doctor_id || selectedReport?.created_by || selectedReport?.doctor || null;
const derived = reportDoctorName ? reportTitle(selectedReport, reportDoctorName) : reportTitle(selectedReport);
if (looksLikeIdStr(derived)) {
return <span className="font-semibold text-xl md:text-2xl text-muted-foreground">{strings.carregando}</span>;
}
if (resolvingDoctors && maybeId && !doctorsMap[String(maybeId)]) {
return <span className="font-semibold text-xl md:text-2xl text-muted-foreground">{strings.carregando}</span>;
}
return <span className="font-semibold text-xl md:text-2xl">{derived}</span>;
})()
)}
</DialogTitle>
<DialogDescription className="sr-only">Detalhes do laudo</DialogDescription>
<div className="mt-4 space-y-3 max-h-96 overflow-y-auto">
{selectedReport && (
<>
<div className="mb-2">
{
// prefer the resolved doctor name; while resolving, show a loading indicator instead of raw IDs
(() => {
const looksLikeIdStr = (s: any) => {
try {
const hexOnly = String(s || '').replace(/[^0-9a-fA-F]/g, '')
const len = (typeof hexOnly === 'string') ? hexOnly.length : (Number(hexOnly) || 0)
return len >= 8
} catch { return false }
}
const maybeId = selectedReport?.doctor_id || selectedReport?.created_by || selectedReport?.doctor || null
// derive the title text
const derived = reportDoctorName ? reportTitle(selectedReport, reportDoctorName) : reportTitle(selectedReport)
// if the derived title looks like an id (UUID/hex) avoid showing it — show loading instead
if (looksLikeIdStr(derived)) return <div className="font-semibold text-xl md:text-2xl text-muted-foreground">{strings.carregando}</div>
if (resolvingDoctors && maybeId && !doctorsMap[String(maybeId)]) return <div className="font-semibold text-xl md:text-2xl text-muted-foreground">{strings.carregando}</div>
return <div className="font-semibold text-xl md:text-2xl">{derived}</div>
})()
}
<div className="text-sm text-muted-foreground">Data: {new Date(selectedReport.report_date || selectedReport.created_at || Date.now()).toLocaleDateString('pt-BR')}</div>
{reportDoctorName && <div className="text-sm text-muted-foreground">Profissional: <strong className="text-foreground">{reportDoctorName}</strong></div>}
</div>
<div className="text-sm text-muted-foreground">Data: {new Date(selectedReport.report_date || selectedReport.created_at || Date.now()).toLocaleDateString('pt-BR')}</div>
{reportDoctorName && <div className="text-sm text-muted-foreground">Profissional: <strong className="text-foreground">{reportDoctorName}</strong></div>}
{/* Standardized laudo sections: CID, Exame, Diagnóstico, Conclusão, Notas (prefer HTML when available) */}
{/* Standardized laudo sections */}
{(() => {
const cid = selectedReport.cid ?? selectedReport.cid_code ?? selectedReport.cidCode ?? selectedReport.cie ?? '-'
const exam = selectedReport.exam ?? selectedReport.exame ?? selectedReport.especialidade ?? selectedReport.report_type ?? '-'
const diagnosis = selectedReport.diagnosis ?? selectedReport.diagnostico ?? selectedReport.diagnosis_text ?? selectedReport.diagnostico_text ?? ''
const conclusion = selectedReport.conclusion ?? selectedReport.conclusao ?? selectedReport.conclusion_text ?? selectedReport.conclusao_text ?? ''
const notesHtml = selectedReport.content_html ?? selectedReport.conteudo_html ?? selectedReport.contentHtml ?? null
const notesText = selectedReport.content ?? selectedReport.body ?? selectedReport.conteudo ?? selectedReport.notes ?? selectedReport.observacoes ?? ''
const cid = selectedReport.cid ?? selectedReport.cid_code ?? selectedReport.cidCode ?? selectedReport.cie ?? '-';
const exam = selectedReport.exam ?? selectedReport.exame ?? selectedReport.especialidade ?? selectedReport.report_type ?? '-';
const diagnosis = selectedReport.diagnosis ?? selectedReport.diagnostico ?? selectedReport.diagnosis_text ?? selectedReport.diagnostico_text ?? '';
const conclusion = selectedReport.conclusion ?? selectedReport.conclusao ?? selectedReport.conclusion_text ?? selectedReport.conclusao_text ?? '';
const notesHtml = selectedReport.content_html ?? selectedReport.conteudo_html ?? selectedReport.contentHtml ?? null;
const notesText = selectedReport.content ?? selectedReport.body ?? selectedReport.conteudo ?? selectedReport.notes ?? selectedReport.observacoes ?? '';
return (
<div className="space-y-3 mb-4">
<div className="space-y-3">
<div>
<div className="text-xs text-muted-foreground">CID</div>
<div className="text-foreground">{cid || '-'}</div>
</div>
<div>
<div className="text-xs text-muted-foreground">Exame</div>
<div className="text-foreground">{exam || '-'}</div>
</div>
<div>
<div className="text-xs text-muted-foreground">Diagnóstico</div>
<div className="whitespace-pre-line text-foreground">{diagnosis || '-'}</div>
</div>
<div>
<div className="text-xs text-muted-foreground">Conclusão</div>
<div className="whitespace-pre-line text-foreground">{conclusion || '-'}</div>
</div>
<div>
<div className="text-xs text-muted-foreground">Notas do Profissional</div>
{notesHtml ? (
@ -1403,15 +1402,14 @@ export default function PacientePage() {
)}
</div>
</div>
)
);
})()}
{/* Optional: doctor signature or footer */}
{selectedReport.doctor_signature && (
<div className="mt-4 text-sm text-muted-foreground">Assinatura: <img src={selectedReport.doctor_signature} alt="assinatura" className="inline-block h-10" /></div>
<div className="mt-4 text-sm text-muted-foreground">Assinatura: <Image src={selectedReport.doctor_signature} alt="assinatura" width={40} height={40} className="inline-block h-10 w-auto" /></div>
)}
</>
)}
</DialogDescription>
</div>
</DialogHeader>
<DialogFooter>
<Button

View File

@ -1,6 +1,6 @@
import { Header } from "@/components/header"
import { Header } from "@/components/layout/header"
import { HeroSection } from "@/components/hero-section"
import { Footer } from "@/components/footer"
import { Footer } from "@/components/layout/footer"
export default function HomePage() {
return (

View File

@ -1,6 +1,6 @@
import { Header } from "@/components/header"
import { Header } from "@/components/layout/header"
import { AboutSection } from "@/components/about-section"
import { Footer } from "@/components/footer"
import { Footer } from "@/components/layout/footer"
export default function AboutPage() {
return (

View File

@ -1,9 +1,9 @@
"use client";
import { Save } from "lucide-react";
import { Button } from "../ui/button";
import { Label } from "../ui/label";
import { Switch } from "../ui/switch";
import { Button } from "../../ui/button";
import { Label } from "../../ui/label";
import { Switch } from "../../ui/switch";
import { useState } from "react";
interface FooterAgendaProps {

View File

@ -7,7 +7,7 @@ import { Input } from "@/components/ui/input"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { useState, useEffect, useRef } from "react"
import { useRouter } from "next/navigation"
import { SidebarTrigger } from "../ui/sidebar"
import { SidebarTrigger } from "../../ui/sidebar"
import { SimpleThemeToggle } from "@/components/simple-theme-toggle";
export function PagesHeader({ title = "", subtitle = "" }: { title?: string, subtitle?: string }) {

View File

@ -1,3 +1,5 @@
"use client"
import { ChevronUp } from "lucide-react"

View File

@ -34,18 +34,15 @@ function useChart() {
return context
}
function ChartContainer({
id,
className,
children,
config,
...props
}: React.ComponentProps<"div"> & {
config: ChartConfig
children: React.ComponentProps<
typeof RechartsPrimitive.ResponsiveContainer
>["children"]
}) {
const ChartContainer = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> & {
config: ChartConfig
children: React.ComponentProps<
typeof RechartsPrimitive.ResponsiveContainer
>["children"]
}
>(({ id, className, children, config, ...props }, ref) => {
const uniqueId = React.useId()
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
@ -55,9 +52,10 @@ function ChartContainer({
data-slot="chart"
data-chart={chartId}
className={cn(
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-sector]:outline-none [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-none",
className
)}
ref={ref}
{...props}
>
<ChartStyle id={chartId} config={config} />
@ -67,7 +65,8 @@ function ChartContainer({
</div>
</ChartContext.Provider>
)
}
})
ChartContainer.displayName = "Chart"
const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
const colorConfig = Object.entries(config).filter(
@ -104,28 +103,33 @@ ${colorConfig
const ChartTooltip = RechartsPrimitive.Tooltip
function ChartTooltipContent({
active,
payload,
className,
indicator = "dot",
hideLabel = false,
hideIndicator = false,
label,
labelFormatter,
labelClassName,
formatter,
color,
nameKey,
labelKey,
}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
const ChartTooltipContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
React.ComponentProps<"div"> & {
hideLabel?: boolean
hideIndicator?: boolean
indicator?: "line" | "dot" | "dashed"
nameKey?: string
labelKey?: string
}) {
payload?: any[]
label?: any
}
>(({
active,
payload,
className,
indicator = "dot",
hideLabel = false,
hideIndicator = false,
label,
labelFormatter,
labelClassName,
formatter,
color,
nameKey,
labelKey
}, ref) => {
const { config } = useChart()
const tooltipLabel = React.useMemo(() => {
@ -134,14 +138,14 @@ function ChartTooltipContent({
}
const [item] = payload
const key = `${labelKey || item?.dataKey || item?.name || "value"}`
const key = `${labelKey || item.dataKey || item.name || "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
const value =
let value =
!labelKey && typeof label === "string"
? config[label as keyof typeof config]?.label || label
: itemConfig?.label
if (labelFormatter) {
if (labelFormatter && value) {
return (
<div className={cn("font-medium", labelClassName)}>
{labelFormatter(value, payload)}
@ -172,27 +176,30 @@ function ChartTooltipContent({
return (
<div
ref={ref}
className={cn(
"border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl",
"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
className
)}
>
{!nestLabel ? tooltipLabel : null}
<div className="grid gap-1.5">
{payload.map((item, index) => {
{payload.map((item: any, index: number) => {
const key = `${nameKey || item.name || item.dataKey || "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
const indicatorColor = color || item.payload.fill || item.color
const indicatorColor = color || item.color
return (
<div
key={item.dataKey}
className={cn(
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
indicator === "dot" && "items-center"
)}
>
{formatter && item?.value !== undefined && item.name ? (
{formatter &&
item.value !== undefined &&
item.name !== undefined ? (
formatter(item.value, item.name, item, index, item.payload)
) : (
<>
@ -202,7 +209,7 @@ function ChartTooltipContent({
!hideIndicator && (
<div
className={cn(
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
"shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",
{
"h-2.5 w-2.5": indicator === "dot",
"w-1": indicator === "line",
@ -233,7 +240,7 @@ function ChartTooltipContent({
</span>
</div>
{item.value && (
<span className="text-foreground font-mono font-medium tabular-nums">
<span className="font-mono font-medium tabular-nums text-foreground">
{item.value.toLocaleString()}
</span>
)}
@ -246,21 +253,20 @@ function ChartTooltipContent({
</div>
</div>
)
}
})
ChartTooltipContent.displayName = "ChartTooltip"
const ChartLegend = RechartsPrimitive.Legend
function ChartLegendContent({
className,
hideIcon = false,
payload,
verticalAlign = "bottom",
nameKey,
}: React.ComponentProps<"div"> &
Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
const ChartLegendContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> & {
hideIcon?: boolean
payload?: any[]
verticalAlign?: RechartsPrimitive.LegendProps["verticalAlign"]
nameKey?: string
}) {
}
>(({ className, hideIcon = false, payload, verticalAlign, nameKey }, ref) => {
const { config } = useChart()
if (!payload?.length) {
@ -269,13 +275,14 @@ function ChartLegendContent({
return (
<div
ref={ref}
className={cn(
"flex items-center justify-center gap-4",
verticalAlign === "top" ? "pb-3" : "pt-3",
className
)}
>
{payload.map((item) => {
{payload.map((item: any) => {
const key = `${nameKey || item.dataKey || "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
@ -283,7 +290,7 @@ function ChartLegendContent({
<div
key={item.value}
className={cn(
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
)}
>
{itemConfig?.icon && !hideIcon ? (
@ -302,12 +309,13 @@ function ChartLegendContent({
})}
</div>
)
}
})
ChartLegendContent.displayName = "ChartLegend"
// Helper to extract item config from a payload.
function getPayloadConfigFromPayload(
config: ChartConfig,
payload: unknown,
payload: any,
key: string
) {
if (typeof payload !== "object" || payload === null) {

View File

@ -2806,7 +2806,7 @@ export async function uploadFotoPaciente(_id: string | number, _file: File): Pro
form.append('file', _file, `avatar.${ext}`);
const headers: Record<string, string> = {
// Supabase requires the anon key in 'apikey' header for client-side uploads
// Supabase requires the anon key in 'apikey' header for client-side uploads
apikey: ENV_CONFIG.SUPABASE_ANON_KEY,
// Accept json
Accept: 'application/json',