exister 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend-project/hospital.sql +59 -0
- package/backend-project/node_modules/.bin/bcrypt +16 -0
- package/backend-project/node_modules/.bin/bcrypt.cmd +17 -0
- package/backend-project/node_modules/.bin/bcrypt.ps1 +28 -0
- package/backend-project/node_modules/.bin/nodemon +16 -0
- package/backend-project/node_modules/.bin/nodemon.cmd +17 -0
- package/backend-project/node_modules/.bin/nodemon.ps1 +28 -0
- package/backend-project/node_modules/.bin/nodetouch +16 -0
- package/backend-project/node_modules/.bin/nodetouch.cmd +17 -0
- package/backend-project/node_modules/.bin/nodetouch.ps1 +28 -0
- package/backend-project/node_modules/.bin/semver +16 -0
- package/backend-project/node_modules/.bin/semver.cmd +17 -0
- package/backend-project/node_modules/.bin/semver.ps1 +28 -0
- package/backend-project/node_modules/.package-lock.json +1297 -0
- package/backend-project/node_modules/@types/node/LICENSE +21 -0
- package/backend-project/node_modules/@types/node/README.md +15 -0
- package/backend-project/node_modules/@types/node/assert/strict.d.ts +59 -0
- package/backend-project/node_modules/@types/node/assert.d.ts +950 -0
- package/backend-project/node_modules/@types/node/async_hooks.d.ts +603 -0
- package/backend-project/node_modules/@types/node/buffer.buffer.d.ts +466 -0
- package/backend-project/node_modules/@types/node/buffer.d.ts +1765 -0
- package/backend-project/node_modules/@types/node/child_process.d.ts +1366 -0
- package/backend-project/node_modules/@types/node/cluster.d.ts +432 -0
- package/backend-project/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
- package/backend-project/node_modules/@types/node/console.d.ts +93 -0
- package/backend-project/node_modules/@types/node/constants.d.ts +14 -0
- package/backend-project/node_modules/@types/node/crypto.d.ts +4047 -0
- package/backend-project/node_modules/@types/node/dgram.d.ts +537 -0
- package/backend-project/node_modules/@types/node/diagnostics_channel.d.ts +552 -0
- package/backend-project/node_modules/@types/node/dns/promises.d.ts +497 -0
- package/backend-project/node_modules/@types/node/dns.d.ts +876 -0
- package/backend-project/node_modules/@types/node/domain.d.ts +150 -0
- package/backend-project/node_modules/@types/node/events.d.ts +1008 -0
- package/backend-project/node_modules/@types/node/fs/promises.d.ts +1342 -0
- package/backend-project/node_modules/@types/node/fs.d.ts +4778 -0
- package/backend-project/node_modules/@types/node/globals.d.ts +150 -0
- package/backend-project/node_modules/@types/node/globals.typedarray.d.ts +101 -0
- package/backend-project/node_modules/@types/node/http.d.ts +2147 -0
- package/backend-project/node_modules/@types/node/http2.d.ts +2485 -0
- package/backend-project/node_modules/@types/node/https.d.ts +400 -0
- package/backend-project/node_modules/@types/node/index.d.ts +115 -0
- package/backend-project/node_modules/@types/node/inspector/promises.d.ts +35 -0
- package/backend-project/node_modules/@types/node/inspector.d.ts +264 -0
- package/backend-project/node_modules/@types/node/inspector.generated.d.ts +4401 -0
- package/backend-project/node_modules/@types/node/module.d.ts +754 -0
- package/backend-project/node_modules/@types/node/net.d.ts +970 -0
- package/backend-project/node_modules/@types/node/os.d.ts +498 -0
- package/backend-project/node_modules/@types/node/package.json +155 -0
- package/backend-project/node_modules/@types/node/path/posix.d.ts +8 -0
- package/backend-project/node_modules/@types/node/path/win32.d.ts +8 -0
- package/backend-project/node_modules/@types/node/path.d.ts +178 -0
- package/backend-project/node_modules/@types/node/perf_hooks.d.ts +612 -0
- package/backend-project/node_modules/@types/node/process.d.ts +2180 -0
- package/backend-project/node_modules/@types/node/punycode.d.ts +89 -0
- package/backend-project/node_modules/@types/node/querystring.d.ts +139 -0
- package/backend-project/node_modules/@types/node/quic.d.ts +897 -0
- package/backend-project/node_modules/@types/node/readline/promises.d.ts +158 -0
- package/backend-project/node_modules/@types/node/readline.d.ts +507 -0
- package/backend-project/node_modules/@types/node/repl.d.ts +405 -0
- package/backend-project/node_modules/@types/node/sea.d.ts +47 -0
- package/backend-project/node_modules/@types/node/sqlite.d.ts +1021 -0
- package/backend-project/node_modules/@types/node/stream/consumers.d.ts +114 -0
- package/backend-project/node_modules/@types/node/stream/promises.d.ts +211 -0
- package/backend-project/node_modules/@types/node/stream/web.d.ts +300 -0
- package/backend-project/node_modules/@types/node/stream.d.ts +1774 -0
- package/backend-project/node_modules/@types/node/string_decoder.d.ts +27 -0
- package/backend-project/node_modules/@types/node/test/reporters.d.ts +59 -0
- package/backend-project/node_modules/@types/node/test.d.ts +2211 -0
- package/backend-project/node_modules/@types/node/timers/promises.d.ts +93 -0
- package/backend-project/node_modules/@types/node/timers.d.ts +149 -0
- package/backend-project/node_modules/@types/node/tls.d.ts +1193 -0
- package/backend-project/node_modules/@types/node/trace_events.d.ts +103 -0
- package/backend-project/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +462 -0
- package/backend-project/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
- package/backend-project/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
- package/backend-project/node_modules/@types/node/ts5.6/index.d.ts +117 -0
- package/backend-project/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
- package/backend-project/node_modules/@types/node/ts5.7/index.d.ts +117 -0
- package/backend-project/node_modules/@types/node/tty.d.ts +225 -0
- package/backend-project/node_modules/@types/node/url.d.ts +554 -0
- package/backend-project/node_modules/@types/node/util/types.d.ts +558 -0
- package/backend-project/node_modules/@types/node/util.d.ts +1677 -0
- package/backend-project/node_modules/@types/node/v8.d.ts +980 -0
- package/backend-project/node_modules/@types/node/vm.d.ts +1135 -0
- package/backend-project/node_modules/@types/node/wasi.d.ts +131 -0
- package/backend-project/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
- package/backend-project/node_modules/@types/node/web-globals/blob.d.ts +23 -0
- package/backend-project/node_modules/@types/node/web-globals/console.d.ts +9 -0
- package/backend-project/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
- package/backend-project/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
- package/backend-project/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
- package/backend-project/node_modules/@types/node/web-globals/events.d.ts +106 -0
- package/backend-project/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
- package/backend-project/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
- package/backend-project/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
- package/backend-project/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
- package/backend-project/node_modules/@types/node/web-globals/performance.d.ts +45 -0
- package/backend-project/node_modules/@types/node/web-globals/storage.d.ts +24 -0
- package/backend-project/node_modules/@types/node/web-globals/streams.d.ts +115 -0
- package/backend-project/node_modules/@types/node/web-globals/timers.d.ts +44 -0
- package/backend-project/node_modules/@types/node/web-globals/url.d.ts +24 -0
- package/backend-project/node_modules/@types/node/worker_threads.d.ts +671 -0
- package/backend-project/node_modules/@types/node/zlib.d.ts +589 -0
- package/backend-project/node_modules/accepts/HISTORY.md +250 -0
- package/backend-project/node_modules/accepts/LICENSE +23 -0
- package/backend-project/node_modules/accepts/README.md +140 -0
- package/backend-project/node_modules/accepts/index.js +238 -0
- package/backend-project/node_modules/accepts/package.json +47 -0
- package/backend-project/node_modules/anymatch/LICENSE +15 -0
- package/backend-project/node_modules/anymatch/README.md +87 -0
- package/backend-project/node_modules/anymatch/index.d.ts +20 -0
- package/backend-project/node_modules/anymatch/index.js +104 -0
- package/backend-project/node_modules/anymatch/package.json +48 -0
- package/backend-project/node_modules/aws-ssl-profiles/LICENSE +19 -0
- package/backend-project/node_modules/aws-ssl-profiles/README.md +146 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/@types/profiles.d.ts +4 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/@types/profiles.js +2 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/index.d.ts +8 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/index.js +13 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/profiles/ca/defaults.d.ts +9 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/profiles/ca/defaults.js +2888 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/profiles/ca/proxies.d.ts +8 -0
- package/backend-project/node_modules/aws-ssl-profiles/lib/profiles/ca/proxies.js +111 -0
- package/backend-project/node_modules/aws-ssl-profiles/package.json +52 -0
- package/backend-project/node_modules/balanced-match/LICENSE.md +23 -0
- package/backend-project/node_modules/balanced-match/README.md +57 -0
- package/backend-project/node_modules/balanced-match/dist/commonjs/index.d.ts +9 -0
- package/backend-project/node_modules/balanced-match/dist/commonjs/index.d.ts.map +1 -0
- package/backend-project/node_modules/balanced-match/dist/commonjs/index.js +59 -0
- package/backend-project/node_modules/balanced-match/dist/commonjs/index.js.map +1 -0
- package/backend-project/node_modules/balanced-match/dist/commonjs/package.json +3 -0
- package/backend-project/node_modules/balanced-match/dist/esm/index.d.ts +9 -0
- package/backend-project/node_modules/balanced-match/dist/esm/index.d.ts.map +1 -0
- package/backend-project/node_modules/balanced-match/dist/esm/index.js +54 -0
- package/backend-project/node_modules/balanced-match/dist/esm/index.js.map +1 -0
- package/backend-project/node_modules/balanced-match/dist/esm/package.json +3 -0
- package/backend-project/node_modules/balanced-match/package.json +68 -0
- package/backend-project/node_modules/bcryptjs/LICENSE +27 -0
- package/backend-project/node_modules/bcryptjs/README.md +201 -0
- package/backend-project/node_modules/bcryptjs/bin/bcrypt +23 -0
- package/backend-project/node_modules/bcryptjs/index.d.ts +3 -0
- package/backend-project/node_modules/bcryptjs/index.js +1159 -0
- package/backend-project/node_modules/bcryptjs/package.json +76 -0
- package/backend-project/node_modules/bcryptjs/types.d.ts +157 -0
- package/backend-project/node_modules/bcryptjs/umd/index.d.ts +3 -0
- package/backend-project/node_modules/bcryptjs/umd/index.js +1220 -0
- package/backend-project/node_modules/bcryptjs/umd/package.json +3 -0
- package/backend-project/node_modules/bcryptjs/umd/types.d.ts +157 -0
- package/backend-project/node_modules/binary-extensions/binary-extensions.json +263 -0
- package/backend-project/node_modules/binary-extensions/binary-extensions.json.d.ts +3 -0
- package/backend-project/node_modules/binary-extensions/index.d.ts +14 -0
- package/backend-project/node_modules/binary-extensions/index.js +1 -0
- package/backend-project/node_modules/binary-extensions/license +10 -0
- package/backend-project/node_modules/binary-extensions/package.json +40 -0
- package/backend-project/node_modules/binary-extensions/readme.md +25 -0
- package/backend-project/node_modules/body-parser/LICENSE +23 -0
- package/backend-project/node_modules/body-parser/README.md +494 -0
- package/backend-project/node_modules/body-parser/index.js +71 -0
- package/backend-project/node_modules/body-parser/lib/read.js +247 -0
- package/backend-project/node_modules/body-parser/lib/types/json.js +158 -0
- package/backend-project/node_modules/body-parser/lib/types/raw.js +42 -0
- package/backend-project/node_modules/body-parser/lib/types/text.js +36 -0
- package/backend-project/node_modules/body-parser/lib/types/urlencoded.js +142 -0
- package/backend-project/node_modules/body-parser/lib/utils.js +98 -0
- package/backend-project/node_modules/body-parser/package.json +52 -0
- package/backend-project/node_modules/brace-expansion/LICENSE +23 -0
- package/backend-project/node_modules/brace-expansion/README.md +94 -0
- package/backend-project/node_modules/brace-expansion/dist/commonjs/index.d.ts +6 -0
- package/backend-project/node_modules/brace-expansion/dist/commonjs/index.d.ts.map +1 -0
- package/backend-project/node_modules/brace-expansion/dist/commonjs/index.js +201 -0
- package/backend-project/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -0
- package/backend-project/node_modules/brace-expansion/dist/commonjs/package.json +3 -0
- package/backend-project/node_modules/brace-expansion/dist/esm/index.d.ts +6 -0
- package/backend-project/node_modules/brace-expansion/dist/esm/index.d.ts.map +1 -0
- package/backend-project/node_modules/brace-expansion/dist/esm/index.js +197 -0
- package/backend-project/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
- package/backend-project/node_modules/brace-expansion/dist/esm/package.json +3 -0
- package/backend-project/node_modules/brace-expansion/package.json +64 -0
- package/backend-project/node_modules/braces/LICENSE +21 -0
- package/backend-project/node_modules/braces/README.md +586 -0
- package/backend-project/node_modules/braces/index.js +170 -0
- package/backend-project/node_modules/braces/lib/compile.js +60 -0
- package/backend-project/node_modules/braces/lib/constants.js +57 -0
- package/backend-project/node_modules/braces/lib/expand.js +113 -0
- package/backend-project/node_modules/braces/lib/parse.js +331 -0
- package/backend-project/node_modules/braces/lib/stringify.js +32 -0
- package/backend-project/node_modules/braces/lib/utils.js +122 -0
- package/backend-project/node_modules/braces/package.json +77 -0
- package/backend-project/node_modules/bytes/History.md +97 -0
- package/backend-project/node_modules/bytes/LICENSE +23 -0
- package/backend-project/node_modules/bytes/Readme.md +152 -0
- package/backend-project/node_modules/bytes/index.js +170 -0
- package/backend-project/node_modules/bytes/package.json +42 -0
- package/backend-project/node_modules/call-bind-apply-helpers/.eslintrc +17 -0
- package/backend-project/node_modules/call-bind-apply-helpers/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/call-bind-apply-helpers/.nycrc +9 -0
- package/backend-project/node_modules/call-bind-apply-helpers/CHANGELOG.md +30 -0
- package/backend-project/node_modules/call-bind-apply-helpers/LICENSE +21 -0
- package/backend-project/node_modules/call-bind-apply-helpers/README.md +62 -0
- package/backend-project/node_modules/call-bind-apply-helpers/actualApply.d.ts +1 -0
- package/backend-project/node_modules/call-bind-apply-helpers/actualApply.js +10 -0
- package/backend-project/node_modules/call-bind-apply-helpers/applyBind.d.ts +19 -0
- package/backend-project/node_modules/call-bind-apply-helpers/applyBind.js +10 -0
- package/backend-project/node_modules/call-bind-apply-helpers/functionApply.d.ts +1 -0
- package/backend-project/node_modules/call-bind-apply-helpers/functionApply.js +4 -0
- package/backend-project/node_modules/call-bind-apply-helpers/functionCall.d.ts +1 -0
- package/backend-project/node_modules/call-bind-apply-helpers/functionCall.js +4 -0
- package/backend-project/node_modules/call-bind-apply-helpers/index.d.ts +64 -0
- package/backend-project/node_modules/call-bind-apply-helpers/index.js +15 -0
- package/backend-project/node_modules/call-bind-apply-helpers/package.json +85 -0
- package/backend-project/node_modules/call-bind-apply-helpers/reflectApply.d.ts +3 -0
- package/backend-project/node_modules/call-bind-apply-helpers/reflectApply.js +4 -0
- package/backend-project/node_modules/call-bind-apply-helpers/test/index.js +63 -0
- package/backend-project/node_modules/call-bind-apply-helpers/tsconfig.json +9 -0
- package/backend-project/node_modules/call-bound/.eslintrc +13 -0
- package/backend-project/node_modules/call-bound/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/call-bound/.nycrc +9 -0
- package/backend-project/node_modules/call-bound/CHANGELOG.md +42 -0
- package/backend-project/node_modules/call-bound/LICENSE +21 -0
- package/backend-project/node_modules/call-bound/README.md +53 -0
- package/backend-project/node_modules/call-bound/index.d.ts +94 -0
- package/backend-project/node_modules/call-bound/index.js +19 -0
- package/backend-project/node_modules/call-bound/package.json +99 -0
- package/backend-project/node_modules/call-bound/test/index.js +61 -0
- package/backend-project/node_modules/call-bound/tsconfig.json +10 -0
- package/backend-project/node_modules/chokidar/LICENSE +21 -0
- package/backend-project/node_modules/chokidar/README.md +308 -0
- package/backend-project/node_modules/chokidar/index.js +973 -0
- package/backend-project/node_modules/chokidar/lib/constants.js +66 -0
- package/backend-project/node_modules/chokidar/lib/fsevents-handler.js +526 -0
- package/backend-project/node_modules/chokidar/lib/nodefs-handler.js +654 -0
- package/backend-project/node_modules/chokidar/package.json +70 -0
- package/backend-project/node_modules/chokidar/types/index.d.ts +192 -0
- package/backend-project/node_modules/content-disposition/LICENSE +22 -0
- package/backend-project/node_modules/content-disposition/README.md +141 -0
- package/backend-project/node_modules/content-disposition/index.js +536 -0
- package/backend-project/node_modules/content-disposition/package.json +40 -0
- package/backend-project/node_modules/content-type/HISTORY.md +29 -0
- package/backend-project/node_modules/content-type/LICENSE +22 -0
- package/backend-project/node_modules/content-type/README.md +94 -0
- package/backend-project/node_modules/content-type/index.js +225 -0
- package/backend-project/node_modules/content-type/package.json +42 -0
- package/backend-project/node_modules/cookie/LICENSE +24 -0
- package/backend-project/node_modules/cookie/README.md +317 -0
- package/backend-project/node_modules/cookie/SECURITY.md +25 -0
- package/backend-project/node_modules/cookie/index.js +335 -0
- package/backend-project/node_modules/cookie/package.json +44 -0
- package/backend-project/node_modules/cookie-signature/History.md +70 -0
- package/backend-project/node_modules/cookie-signature/LICENSE +22 -0
- package/backend-project/node_modules/cookie-signature/Readme.md +23 -0
- package/backend-project/node_modules/cookie-signature/index.js +47 -0
- package/backend-project/node_modules/cookie-signature/package.json +24 -0
- package/backend-project/node_modules/cors/LICENSE +22 -0
- package/backend-project/node_modules/cors/README.md +277 -0
- package/backend-project/node_modules/cors/lib/index.js +238 -0
- package/backend-project/node_modules/cors/package.json +42 -0
- package/backend-project/node_modules/debug/LICENSE +20 -0
- package/backend-project/node_modules/debug/README.md +481 -0
- package/backend-project/node_modules/debug/package.json +64 -0
- package/backend-project/node_modules/debug/src/browser.js +272 -0
- package/backend-project/node_modules/debug/src/common.js +292 -0
- package/backend-project/node_modules/debug/src/index.js +10 -0
- package/backend-project/node_modules/debug/src/node.js +263 -0
- package/backend-project/node_modules/denque/CHANGELOG.md +29 -0
- package/backend-project/node_modules/denque/LICENSE +201 -0
- package/backend-project/node_modules/denque/README.md +77 -0
- package/backend-project/node_modules/denque/index.d.ts +47 -0
- package/backend-project/node_modules/denque/index.js +481 -0
- package/backend-project/node_modules/denque/package.json +58 -0
- package/backend-project/node_modules/depd/History.md +103 -0
- package/backend-project/node_modules/depd/LICENSE +22 -0
- package/backend-project/node_modules/depd/Readme.md +280 -0
- package/backend-project/node_modules/depd/index.js +538 -0
- package/backend-project/node_modules/depd/lib/browser/index.js +77 -0
- package/backend-project/node_modules/depd/package.json +45 -0
- package/backend-project/node_modules/dunder-proto/.eslintrc +5 -0
- package/backend-project/node_modules/dunder-proto/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/dunder-proto/.nycrc +13 -0
- package/backend-project/node_modules/dunder-proto/CHANGELOG.md +24 -0
- package/backend-project/node_modules/dunder-proto/LICENSE +21 -0
- package/backend-project/node_modules/dunder-proto/README.md +54 -0
- package/backend-project/node_modules/dunder-proto/get.d.ts +5 -0
- package/backend-project/node_modules/dunder-proto/get.js +30 -0
- package/backend-project/node_modules/dunder-proto/package.json +76 -0
- package/backend-project/node_modules/dunder-proto/set.d.ts +5 -0
- package/backend-project/node_modules/dunder-proto/set.js +35 -0
- package/backend-project/node_modules/dunder-proto/test/get.js +34 -0
- package/backend-project/node_modules/dunder-proto/test/index.js +4 -0
- package/backend-project/node_modules/dunder-proto/test/set.js +50 -0
- package/backend-project/node_modules/dunder-proto/tsconfig.json +9 -0
- package/backend-project/node_modules/ee-first/LICENSE +22 -0
- package/backend-project/node_modules/ee-first/README.md +80 -0
- package/backend-project/node_modules/ee-first/index.js +95 -0
- package/backend-project/node_modules/ee-first/package.json +29 -0
- package/backend-project/node_modules/encodeurl/LICENSE +22 -0
- package/backend-project/node_modules/encodeurl/README.md +109 -0
- package/backend-project/node_modules/encodeurl/index.js +60 -0
- package/backend-project/node_modules/encodeurl/package.json +40 -0
- package/backend-project/node_modules/es-define-property/.eslintrc +13 -0
- package/backend-project/node_modules/es-define-property/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/es-define-property/.nycrc +9 -0
- package/backend-project/node_modules/es-define-property/CHANGELOG.md +29 -0
- package/backend-project/node_modules/es-define-property/LICENSE +21 -0
- package/backend-project/node_modules/es-define-property/README.md +49 -0
- package/backend-project/node_modules/es-define-property/index.d.ts +3 -0
- package/backend-project/node_modules/es-define-property/index.js +14 -0
- package/backend-project/node_modules/es-define-property/package.json +81 -0
- package/backend-project/node_modules/es-define-property/test/index.js +56 -0
- package/backend-project/node_modules/es-define-property/tsconfig.json +10 -0
- package/backend-project/node_modules/es-errors/.eslintrc +5 -0
- package/backend-project/node_modules/es-errors/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/es-errors/CHANGELOG.md +40 -0
- package/backend-project/node_modules/es-errors/LICENSE +21 -0
- package/backend-project/node_modules/es-errors/README.md +55 -0
- package/backend-project/node_modules/es-errors/eval.d.ts +3 -0
- package/backend-project/node_modules/es-errors/eval.js +4 -0
- package/backend-project/node_modules/es-errors/index.d.ts +3 -0
- package/backend-project/node_modules/es-errors/index.js +4 -0
- package/backend-project/node_modules/es-errors/package.json +80 -0
- package/backend-project/node_modules/es-errors/range.d.ts +3 -0
- package/backend-project/node_modules/es-errors/range.js +4 -0
- package/backend-project/node_modules/es-errors/ref.d.ts +3 -0
- package/backend-project/node_modules/es-errors/ref.js +4 -0
- package/backend-project/node_modules/es-errors/syntax.d.ts +3 -0
- package/backend-project/node_modules/es-errors/syntax.js +4 -0
- package/backend-project/node_modules/es-errors/test/index.js +19 -0
- package/backend-project/node_modules/es-errors/tsconfig.json +49 -0
- package/backend-project/node_modules/es-errors/type.d.ts +3 -0
- package/backend-project/node_modules/es-errors/type.js +4 -0
- package/backend-project/node_modules/es-errors/uri.d.ts +3 -0
- package/backend-project/node_modules/es-errors/uri.js +4 -0
- package/backend-project/node_modules/es-object-atoms/.eslintrc +16 -0
- package/backend-project/node_modules/es-object-atoms/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/es-object-atoms/CHANGELOG.md +37 -0
- package/backend-project/node_modules/es-object-atoms/LICENSE +21 -0
- package/backend-project/node_modules/es-object-atoms/README.md +63 -0
- package/backend-project/node_modules/es-object-atoms/RequireObjectCoercible.d.ts +3 -0
- package/backend-project/node_modules/es-object-atoms/RequireObjectCoercible.js +11 -0
- package/backend-project/node_modules/es-object-atoms/ToObject.d.ts +7 -0
- package/backend-project/node_modules/es-object-atoms/ToObject.js +10 -0
- package/backend-project/node_modules/es-object-atoms/index.d.ts +3 -0
- package/backend-project/node_modules/es-object-atoms/index.js +4 -0
- package/backend-project/node_modules/es-object-atoms/isObject.d.ts +3 -0
- package/backend-project/node_modules/es-object-atoms/isObject.js +6 -0
- package/backend-project/node_modules/es-object-atoms/package.json +80 -0
- package/backend-project/node_modules/es-object-atoms/test/index.js +38 -0
- package/backend-project/node_modules/es-object-atoms/tsconfig.json +6 -0
- package/backend-project/node_modules/escape-html/LICENSE +24 -0
- package/backend-project/node_modules/escape-html/Readme.md +43 -0
- package/backend-project/node_modules/escape-html/index.js +78 -0
- package/backend-project/node_modules/escape-html/package.json +24 -0
- package/backend-project/node_modules/etag/HISTORY.md +83 -0
- package/backend-project/node_modules/etag/LICENSE +22 -0
- package/backend-project/node_modules/etag/README.md +159 -0
- package/backend-project/node_modules/etag/index.js +131 -0
- package/backend-project/node_modules/etag/package.json +47 -0
- package/backend-project/node_modules/express/LICENSE +24 -0
- package/backend-project/node_modules/express/Readme.md +276 -0
- package/backend-project/node_modules/express/index.js +11 -0
- package/backend-project/node_modules/express/lib/application.js +631 -0
- package/backend-project/node_modules/express/lib/express.js +81 -0
- package/backend-project/node_modules/express/lib/request.js +514 -0
- package/backend-project/node_modules/express/lib/response.js +1053 -0
- package/backend-project/node_modules/express/lib/utils.js +271 -0
- package/backend-project/node_modules/express/lib/view.js +205 -0
- package/backend-project/node_modules/express/package.json +99 -0
- package/backend-project/node_modules/fill-range/LICENSE +21 -0
- package/backend-project/node_modules/fill-range/README.md +237 -0
- package/backend-project/node_modules/fill-range/index.js +248 -0
- package/backend-project/node_modules/fill-range/package.json +74 -0
- package/backend-project/node_modules/finalhandler/HISTORY.md +239 -0
- package/backend-project/node_modules/finalhandler/LICENSE +22 -0
- package/backend-project/node_modules/finalhandler/README.md +150 -0
- package/backend-project/node_modules/finalhandler/index.js +293 -0
- package/backend-project/node_modules/finalhandler/package.json +47 -0
- package/backend-project/node_modules/forwarded/HISTORY.md +21 -0
- package/backend-project/node_modules/forwarded/LICENSE +22 -0
- package/backend-project/node_modules/forwarded/README.md +57 -0
- package/backend-project/node_modules/forwarded/index.js +90 -0
- package/backend-project/node_modules/forwarded/package.json +45 -0
- package/backend-project/node_modules/fresh/HISTORY.md +80 -0
- package/backend-project/node_modules/fresh/LICENSE +23 -0
- package/backend-project/node_modules/fresh/README.md +117 -0
- package/backend-project/node_modules/fresh/index.js +136 -0
- package/backend-project/node_modules/fresh/package.json +46 -0
- package/backend-project/node_modules/function-bind/.eslintrc +21 -0
- package/backend-project/node_modules/function-bind/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/function-bind/.github/SECURITY.md +3 -0
- package/backend-project/node_modules/function-bind/.nycrc +13 -0
- package/backend-project/node_modules/function-bind/CHANGELOG.md +136 -0
- package/backend-project/node_modules/function-bind/LICENSE +20 -0
- package/backend-project/node_modules/function-bind/README.md +46 -0
- package/backend-project/node_modules/function-bind/implementation.js +84 -0
- package/backend-project/node_modules/function-bind/index.js +5 -0
- package/backend-project/node_modules/function-bind/package.json +87 -0
- package/backend-project/node_modules/function-bind/test/.eslintrc +9 -0
- package/backend-project/node_modules/function-bind/test/index.js +252 -0
- package/backend-project/node_modules/generate-function/.travis.yml +3 -0
- package/backend-project/node_modules/generate-function/LICENSE +21 -0
- package/backend-project/node_modules/generate-function/README.md +89 -0
- package/backend-project/node_modules/generate-function/example.js +27 -0
- package/backend-project/node_modules/generate-function/index.js +181 -0
- package/backend-project/node_modules/generate-function/package.json +32 -0
- package/backend-project/node_modules/generate-function/test.js +49 -0
- package/backend-project/node_modules/get-intrinsic/.eslintrc +42 -0
- package/backend-project/node_modules/get-intrinsic/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/get-intrinsic/.nycrc +9 -0
- package/backend-project/node_modules/get-intrinsic/CHANGELOG.md +186 -0
- package/backend-project/node_modules/get-intrinsic/LICENSE +21 -0
- package/backend-project/node_modules/get-intrinsic/README.md +71 -0
- package/backend-project/node_modules/get-intrinsic/index.js +378 -0
- package/backend-project/node_modules/get-intrinsic/package.json +97 -0
- package/backend-project/node_modules/get-intrinsic/test/GetIntrinsic.js +274 -0
- package/backend-project/node_modules/get-proto/.eslintrc +10 -0
- package/backend-project/node_modules/get-proto/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/get-proto/.nycrc +9 -0
- package/backend-project/node_modules/get-proto/CHANGELOG.md +21 -0
- package/backend-project/node_modules/get-proto/LICENSE +21 -0
- package/backend-project/node_modules/get-proto/Object.getPrototypeOf.d.ts +5 -0
- package/backend-project/node_modules/get-proto/Object.getPrototypeOf.js +6 -0
- package/backend-project/node_modules/get-proto/README.md +50 -0
- package/backend-project/node_modules/get-proto/Reflect.getPrototypeOf.d.ts +3 -0
- package/backend-project/node_modules/get-proto/Reflect.getPrototypeOf.js +4 -0
- package/backend-project/node_modules/get-proto/index.d.ts +5 -0
- package/backend-project/node_modules/get-proto/index.js +27 -0
- package/backend-project/node_modules/get-proto/package.json +81 -0
- package/backend-project/node_modules/get-proto/test/index.js +68 -0
- package/backend-project/node_modules/get-proto/tsconfig.json +9 -0
- package/backend-project/node_modules/glob-parent/CHANGELOG.md +110 -0
- package/backend-project/node_modules/glob-parent/LICENSE +15 -0
- package/backend-project/node_modules/glob-parent/README.md +137 -0
- package/backend-project/node_modules/glob-parent/index.js +42 -0
- package/backend-project/node_modules/glob-parent/package.json +48 -0
- package/backend-project/node_modules/gopd/.eslintrc +16 -0
- package/backend-project/node_modules/gopd/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/gopd/CHANGELOG.md +45 -0
- package/backend-project/node_modules/gopd/LICENSE +21 -0
- package/backend-project/node_modules/gopd/README.md +40 -0
- package/backend-project/node_modules/gopd/gOPD.d.ts +1 -0
- package/backend-project/node_modules/gopd/gOPD.js +4 -0
- package/backend-project/node_modules/gopd/index.d.ts +5 -0
- package/backend-project/node_modules/gopd/index.js +15 -0
- package/backend-project/node_modules/gopd/package.json +77 -0
- package/backend-project/node_modules/gopd/test/index.js +36 -0
- package/backend-project/node_modules/gopd/tsconfig.json +9 -0
- package/backend-project/node_modules/has-flag/index.js +8 -0
- package/backend-project/node_modules/has-flag/license +9 -0
- package/backend-project/node_modules/has-flag/package.json +44 -0
- package/backend-project/node_modules/has-flag/readme.md +70 -0
- package/backend-project/node_modules/has-symbols/.eslintrc +11 -0
- package/backend-project/node_modules/has-symbols/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/has-symbols/.nycrc +9 -0
- package/backend-project/node_modules/has-symbols/CHANGELOG.md +91 -0
- package/backend-project/node_modules/has-symbols/LICENSE +21 -0
- package/backend-project/node_modules/has-symbols/README.md +46 -0
- package/backend-project/node_modules/has-symbols/index.d.ts +3 -0
- package/backend-project/node_modules/has-symbols/index.js +14 -0
- package/backend-project/node_modules/has-symbols/package.json +111 -0
- package/backend-project/node_modules/has-symbols/shams.d.ts +3 -0
- package/backend-project/node_modules/has-symbols/shams.js +45 -0
- package/backend-project/node_modules/has-symbols/test/index.js +22 -0
- package/backend-project/node_modules/has-symbols/test/shams/core-js.js +29 -0
- package/backend-project/node_modules/has-symbols/test/shams/get-own-property-symbols.js +29 -0
- package/backend-project/node_modules/has-symbols/test/tests.js +58 -0
- package/backend-project/node_modules/has-symbols/tsconfig.json +10 -0
- package/backend-project/node_modules/hasown/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/hasown/.nycrc +13 -0
- package/backend-project/node_modules/hasown/CHANGELOG.md +51 -0
- package/backend-project/node_modules/hasown/LICENSE +21 -0
- package/backend-project/node_modules/hasown/README.md +40 -0
- package/backend-project/node_modules/hasown/eslint.config.mjs +6 -0
- package/backend-project/node_modules/hasown/index.d.ts +4 -0
- package/backend-project/node_modules/hasown/index.js +8 -0
- package/backend-project/node_modules/hasown/package.json +92 -0
- package/backend-project/node_modules/hasown/tsconfig.json +6 -0
- package/backend-project/node_modules/http-errors/HISTORY.md +186 -0
- package/backend-project/node_modules/http-errors/LICENSE +23 -0
- package/backend-project/node_modules/http-errors/README.md +169 -0
- package/backend-project/node_modules/http-errors/index.js +290 -0
- package/backend-project/node_modules/http-errors/package.json +54 -0
- package/backend-project/node_modules/iconv-lite/LICENSE +21 -0
- package/backend-project/node_modules/iconv-lite/README.md +138 -0
- package/backend-project/node_modules/iconv-lite/encodings/dbcs-codec.js +532 -0
- package/backend-project/node_modules/iconv-lite/encodings/dbcs-data.js +185 -0
- package/backend-project/node_modules/iconv-lite/encodings/index.js +23 -0
- package/backend-project/node_modules/iconv-lite/encodings/internal.js +218 -0
- package/backend-project/node_modules/iconv-lite/encodings/sbcs-codec.js +75 -0
- package/backend-project/node_modules/iconv-lite/encodings/sbcs-data-generated.js +451 -0
- package/backend-project/node_modules/iconv-lite/encodings/sbcs-data.js +178 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/big5-added.json +122 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/cp936.json +264 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/cp949.json +273 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/cp950.json +177 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/eucjp.json +182 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +1 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/gbk-added.json +56 -0
- package/backend-project/node_modules/iconv-lite/encodings/tables/shiftjis.json +125 -0
- package/backend-project/node_modules/iconv-lite/encodings/utf16.js +187 -0
- package/backend-project/node_modules/iconv-lite/encodings/utf32.js +307 -0
- package/backend-project/node_modules/iconv-lite/encodings/utf7.js +283 -0
- package/backend-project/node_modules/iconv-lite/lib/bom-handling.js +48 -0
- package/backend-project/node_modules/iconv-lite/lib/helpers/merge-exports.js +13 -0
- package/backend-project/node_modules/iconv-lite/lib/index.d.ts +129 -0
- package/backend-project/node_modules/iconv-lite/lib/index.js +182 -0
- package/backend-project/node_modules/iconv-lite/lib/streams.js +105 -0
- package/backend-project/node_modules/iconv-lite/package.json +70 -0
- package/backend-project/node_modules/iconv-lite/types/encodings.d.ts +423 -0
- package/backend-project/node_modules/ignore-by-default/LICENSE +14 -0
- package/backend-project/node_modules/ignore-by-default/README.md +26 -0
- package/backend-project/node_modules/ignore-by-default/index.js +12 -0
- package/backend-project/node_modules/ignore-by-default/package.json +34 -0
- package/backend-project/node_modules/inherits/LICENSE +16 -0
- package/backend-project/node_modules/inherits/README.md +42 -0
- package/backend-project/node_modules/inherits/inherits.js +9 -0
- package/backend-project/node_modules/inherits/inherits_browser.js +27 -0
- package/backend-project/node_modules/inherits/package.json +29 -0
- package/backend-project/node_modules/ipaddr.js/LICENSE +19 -0
- package/backend-project/node_modules/ipaddr.js/README.md +233 -0
- package/backend-project/node_modules/ipaddr.js/ipaddr.min.js +1 -0
- package/backend-project/node_modules/ipaddr.js/lib/ipaddr.js +673 -0
- package/backend-project/node_modules/ipaddr.js/lib/ipaddr.js.d.ts +68 -0
- package/backend-project/node_modules/ipaddr.js/package.json +35 -0
- package/backend-project/node_modules/is-binary-path/index.d.ts +17 -0
- package/backend-project/node_modules/is-binary-path/index.js +7 -0
- package/backend-project/node_modules/is-binary-path/license +9 -0
- package/backend-project/node_modules/is-binary-path/package.json +40 -0
- package/backend-project/node_modules/is-binary-path/readme.md +34 -0
- package/backend-project/node_modules/is-extglob/LICENSE +21 -0
- package/backend-project/node_modules/is-extglob/README.md +107 -0
- package/backend-project/node_modules/is-extglob/index.js +20 -0
- package/backend-project/node_modules/is-extglob/package.json +69 -0
- package/backend-project/node_modules/is-glob/LICENSE +21 -0
- package/backend-project/node_modules/is-glob/README.md +206 -0
- package/backend-project/node_modules/is-glob/index.js +150 -0
- package/backend-project/node_modules/is-glob/package.json +81 -0
- package/backend-project/node_modules/is-number/LICENSE +21 -0
- package/backend-project/node_modules/is-number/README.md +187 -0
- package/backend-project/node_modules/is-number/index.js +18 -0
- package/backend-project/node_modules/is-number/package.json +82 -0
- package/backend-project/node_modules/is-promise/LICENSE +19 -0
- package/backend-project/node_modules/is-promise/index.d.ts +2 -0
- package/backend-project/node_modules/is-promise/index.js +6 -0
- package/backend-project/node_modules/is-promise/index.mjs +3 -0
- package/backend-project/node_modules/is-promise/package.json +30 -0
- package/backend-project/node_modules/is-promise/readme.md +33 -0
- package/backend-project/node_modules/is-property/LICENSE +22 -0
- package/backend-project/node_modules/is-property/README.md +28 -0
- package/backend-project/node_modules/is-property/is-property.js +5 -0
- package/backend-project/node_modules/is-property/package.json +36 -0
- package/backend-project/node_modules/long/LICENSE +202 -0
- package/backend-project/node_modules/long/README.md +286 -0
- package/backend-project/node_modules/long/index.d.ts +2 -0
- package/backend-project/node_modules/long/index.js +1581 -0
- package/backend-project/node_modules/long/package.json +58 -0
- package/backend-project/node_modules/long/types.d.ts +474 -0
- package/backend-project/node_modules/long/umd/index.d.ts +3 -0
- package/backend-project/node_modules/long/umd/index.js +1622 -0
- package/backend-project/node_modules/long/umd/package.json +3 -0
- package/backend-project/node_modules/long/umd/types.d.ts +474 -0
- package/backend-project/node_modules/lru.min/LICENSE +21 -0
- package/backend-project/node_modules/lru.min/README.md +392 -0
- package/backend-project/node_modules/lru.min/browser/lru.min.js +1 -0
- package/backend-project/node_modules/lru.min/lib/index.d.ts +38 -0
- package/backend-project/node_modules/lru.min/lib/index.js +248 -0
- package/backend-project/node_modules/lru.min/lib/index.mjs +227 -0
- package/backend-project/node_modules/lru.min/package.json +87 -0
- package/backend-project/node_modules/math-intrinsics/.eslintrc +16 -0
- package/backend-project/node_modules/math-intrinsics/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/math-intrinsics/CHANGELOG.md +24 -0
- package/backend-project/node_modules/math-intrinsics/LICENSE +21 -0
- package/backend-project/node_modules/math-intrinsics/README.md +50 -0
- package/backend-project/node_modules/math-intrinsics/abs.d.ts +1 -0
- package/backend-project/node_modules/math-intrinsics/abs.js +4 -0
- package/backend-project/node_modules/math-intrinsics/constants/maxArrayLength.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/constants/maxArrayLength.js +4 -0
- package/backend-project/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/constants/maxSafeInteger.js +5 -0
- package/backend-project/node_modules/math-intrinsics/constants/maxValue.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/constants/maxValue.js +5 -0
- package/backend-project/node_modules/math-intrinsics/floor.d.ts +1 -0
- package/backend-project/node_modules/math-intrinsics/floor.js +4 -0
- package/backend-project/node_modules/math-intrinsics/isFinite.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/isFinite.js +12 -0
- package/backend-project/node_modules/math-intrinsics/isInteger.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/isInteger.js +16 -0
- package/backend-project/node_modules/math-intrinsics/isNaN.d.ts +1 -0
- package/backend-project/node_modules/math-intrinsics/isNaN.js +6 -0
- package/backend-project/node_modules/math-intrinsics/isNegativeZero.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/isNegativeZero.js +6 -0
- package/backend-project/node_modules/math-intrinsics/max.d.ts +1 -0
- package/backend-project/node_modules/math-intrinsics/max.js +4 -0
- package/backend-project/node_modules/math-intrinsics/min.d.ts +1 -0
- package/backend-project/node_modules/math-intrinsics/min.js +4 -0
- package/backend-project/node_modules/math-intrinsics/mod.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/mod.js +9 -0
- package/backend-project/node_modules/math-intrinsics/package.json +86 -0
- package/backend-project/node_modules/math-intrinsics/pow.d.ts +1 -0
- package/backend-project/node_modules/math-intrinsics/pow.js +4 -0
- package/backend-project/node_modules/math-intrinsics/round.d.ts +1 -0
- package/backend-project/node_modules/math-intrinsics/round.js +4 -0
- package/backend-project/node_modules/math-intrinsics/sign.d.ts +3 -0
- package/backend-project/node_modules/math-intrinsics/sign.js +11 -0
- package/backend-project/node_modules/math-intrinsics/test/index.js +192 -0
- package/backend-project/node_modules/math-intrinsics/tsconfig.json +3 -0
- package/backend-project/node_modules/media-typer/HISTORY.md +50 -0
- package/backend-project/node_modules/media-typer/LICENSE +22 -0
- package/backend-project/node_modules/media-typer/README.md +93 -0
- package/backend-project/node_modules/media-typer/index.js +143 -0
- package/backend-project/node_modules/media-typer/package.json +33 -0
- package/backend-project/node_modules/merge-descriptors/index.d.ts +11 -0
- package/backend-project/node_modules/merge-descriptors/index.js +26 -0
- package/backend-project/node_modules/merge-descriptors/license +11 -0
- package/backend-project/node_modules/merge-descriptors/package.json +50 -0
- package/backend-project/node_modules/merge-descriptors/readme.md +55 -0
- package/backend-project/node_modules/mime-db/HISTORY.md +541 -0
- package/backend-project/node_modules/mime-db/LICENSE +23 -0
- package/backend-project/node_modules/mime-db/README.md +109 -0
- package/backend-project/node_modules/mime-db/db.json +9342 -0
- package/backend-project/node_modules/mime-db/index.js +12 -0
- package/backend-project/node_modules/mime-db/package.json +56 -0
- package/backend-project/node_modules/mime-types/HISTORY.md +428 -0
- package/backend-project/node_modules/mime-types/LICENSE +23 -0
- package/backend-project/node_modules/mime-types/README.md +126 -0
- package/backend-project/node_modules/mime-types/index.js +211 -0
- package/backend-project/node_modules/mime-types/mimeScore.js +57 -0
- package/backend-project/node_modules/mime-types/package.json +49 -0
- package/backend-project/node_modules/minimatch/LICENSE.md +55 -0
- package/backend-project/node_modules/minimatch/README.md +528 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +2 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +14 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/ast.d.ts +22 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/ast.js +845 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/ast.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts +8 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/brace-expressions.js +150 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/escape.d.ts +15 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/escape.js +30 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/escape.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/index.d.ts +174 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/index.js +1127 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/index.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/package.json +3 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/unescape.d.ts +22 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/unescape.js +38 -0
- package/backend-project/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +2 -0
- package/backend-project/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/assert-valid-pattern.js +10 -0
- package/backend-project/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/ast.d.ts +22 -0
- package/backend-project/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/ast.js +841 -0
- package/backend-project/node_modules/minimatch/dist/esm/ast.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/brace-expressions.d.ts +8 -0
- package/backend-project/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/brace-expressions.js +146 -0
- package/backend-project/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/escape.d.ts +15 -0
- package/backend-project/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/escape.js +26 -0
- package/backend-project/node_modules/minimatch/dist/esm/escape.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/index.d.ts +174 -0
- package/backend-project/node_modules/minimatch/dist/esm/index.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/index.js +1114 -0
- package/backend-project/node_modules/minimatch/dist/esm/index.js.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/package.json +3 -0
- package/backend-project/node_modules/minimatch/dist/esm/unescape.d.ts +22 -0
- package/backend-project/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -0
- package/backend-project/node_modules/minimatch/dist/esm/unescape.js +34 -0
- package/backend-project/node_modules/minimatch/dist/esm/unescape.js.map +1 -0
- package/backend-project/node_modules/minimatch/package.json +73 -0
- package/backend-project/node_modules/ms/index.js +162 -0
- package/backend-project/node_modules/ms/license.md +21 -0
- package/backend-project/node_modules/ms/package.json +38 -0
- package/backend-project/node_modules/ms/readme.md +59 -0
- package/backend-project/node_modules/mysql2/License +19 -0
- package/backend-project/node_modules/mysql2/README.md +114 -0
- package/backend-project/node_modules/mysql2/index.d.ts +1 -0
- package/backend-project/node_modules/mysql2/index.js +77 -0
- package/backend-project/node_modules/mysql2/lib/auth_41.js +95 -0
- package/backend-project/node_modules/mysql2/lib/auth_plugins/caching_sha2_password.js +115 -0
- package/backend-project/node_modules/mysql2/lib/auth_plugins/caching_sha2_password.md +18 -0
- package/backend-project/node_modules/mysql2/lib/auth_plugins/index.js +8 -0
- package/backend-project/node_modules/mysql2/lib/auth_plugins/mysql_clear_password.js +17 -0
- package/backend-project/node_modules/mysql2/lib/auth_plugins/mysql_native_password.js +34 -0
- package/backend-project/node_modules/mysql2/lib/auth_plugins/sha256_password.js +74 -0
- package/backend-project/node_modules/mysql2/lib/base/connection.js +1139 -0
- package/backend-project/node_modules/mysql2/lib/base/pool.js +343 -0
- package/backend-project/node_modules/mysql2/lib/commands/auth_switch.js +151 -0
- package/backend-project/node_modules/mysql2/lib/commands/binlog_dump.js +109 -0
- package/backend-project/node_modules/mysql2/lib/commands/change_user.js +68 -0
- package/backend-project/node_modules/mysql2/lib/commands/client_handshake.js +386 -0
- package/backend-project/node_modules/mysql2/lib/commands/close_statement.js +18 -0
- package/backend-project/node_modules/mysql2/lib/commands/command.js +54 -0
- package/backend-project/node_modules/mysql2/lib/commands/execute.js +116 -0
- package/backend-project/node_modules/mysql2/lib/commands/index.js +29 -0
- package/backend-project/node_modules/mysql2/lib/commands/ping.js +36 -0
- package/backend-project/node_modules/mysql2/lib/commands/prepare.js +143 -0
- package/backend-project/node_modules/mysql2/lib/commands/query.js +365 -0
- package/backend-project/node_modules/mysql2/lib/commands/quit.js +29 -0
- package/backend-project/node_modules/mysql2/lib/commands/register_slave.js +27 -0
- package/backend-project/node_modules/mysql2/lib/commands/reset_connection.js +29 -0
- package/backend-project/node_modules/mysql2/lib/commands/server_handshake.js +205 -0
- package/backend-project/node_modules/mysql2/lib/compressed_protocol.js +153 -0
- package/backend-project/node_modules/mysql2/lib/connection.js +12 -0
- package/backend-project/node_modules/mysql2/lib/connection_config.js +300 -0
- package/backend-project/node_modules/mysql2/lib/constants/charset_encodings.js +317 -0
- package/backend-project/node_modules/mysql2/lib/constants/charsets.js +317 -0
- package/backend-project/node_modules/mysql2/lib/constants/client.js +39 -0
- package/backend-project/node_modules/mysql2/lib/constants/commands.js +37 -0
- package/backend-project/node_modules/mysql2/lib/constants/cursor.js +9 -0
- package/backend-project/node_modules/mysql2/lib/constants/encoding_charset.js +50 -0
- package/backend-project/node_modules/mysql2/lib/constants/errors.js +3973 -0
- package/backend-project/node_modules/mysql2/lib/constants/field_flags.js +20 -0
- package/backend-project/node_modules/mysql2/lib/constants/server_status.js +44 -0
- package/backend-project/node_modules/mysql2/lib/constants/session_track.js +11 -0
- package/backend-project/node_modules/mysql2/lib/constants/ssl_profiles.js +11 -0
- package/backend-project/node_modules/mysql2/lib/constants/types.js +64 -0
- package/backend-project/node_modules/mysql2/lib/create_connection.js +10 -0
- package/backend-project/node_modules/mysql2/lib/create_pool.js +10 -0
- package/backend-project/node_modules/mysql2/lib/create_pool_cluster.js +9 -0
- package/backend-project/node_modules/mysql2/lib/helpers.js +83 -0
- package/backend-project/node_modules/mysql2/lib/packet_parser.js +195 -0
- package/backend-project/node_modules/mysql2/lib/packets/auth_next_factor.js +35 -0
- package/backend-project/node_modules/mysql2/lib/packets/auth_switch_request.js +38 -0
- package/backend-project/node_modules/mysql2/lib/packets/auth_switch_request_more_data.js +33 -0
- package/backend-project/node_modules/mysql2/lib/packets/auth_switch_response.js +30 -0
- package/backend-project/node_modules/mysql2/lib/packets/binary_row.js +95 -0
- package/backend-project/node_modules/mysql2/lib/packets/binlog_dump.js +33 -0
- package/backend-project/node_modules/mysql2/lib/packets/binlog_query_statusvars.js +115 -0
- package/backend-project/node_modules/mysql2/lib/packets/change_user.js +97 -0
- package/backend-project/node_modules/mysql2/lib/packets/close_statement.js +21 -0
- package/backend-project/node_modules/mysql2/lib/packets/column_definition.js +291 -0
- package/backend-project/node_modules/mysql2/lib/packets/encode_parameter.js +69 -0
- package/backend-project/node_modules/mysql2/lib/packets/execute.js +177 -0
- package/backend-project/node_modules/mysql2/lib/packets/handshake.js +112 -0
- package/backend-project/node_modules/mysql2/lib/packets/handshake_response.js +173 -0
- package/backend-project/node_modules/mysql2/lib/packets/index.js +154 -0
- package/backend-project/node_modules/mysql2/lib/packets/packet.js +978 -0
- package/backend-project/node_modules/mysql2/lib/packets/prepare_statement.js +27 -0
- package/backend-project/node_modules/mysql2/lib/packets/prepared_statement_header.js +16 -0
- package/backend-project/node_modules/mysql2/lib/packets/query.js +102 -0
- package/backend-project/node_modules/mysql2/lib/packets/register_slave.js +46 -0
- package/backend-project/node_modules/mysql2/lib/packets/reset_connection.js +17 -0
- package/backend-project/node_modules/mysql2/lib/packets/resultset_header.js +124 -0
- package/backend-project/node_modules/mysql2/lib/packets/ssl_request.js +25 -0
- package/backend-project/node_modules/mysql2/lib/packets/text_row.js +47 -0
- package/backend-project/node_modules/mysql2/lib/parsers/binary_parser.js +235 -0
- package/backend-project/node_modules/mysql2/lib/parsers/parser_cache.js +68 -0
- package/backend-project/node_modules/mysql2/lib/parsers/static_binary_parser.js +213 -0
- package/backend-project/node_modules/mysql2/lib/parsers/static_text_parser.js +152 -0
- package/backend-project/node_modules/mysql2/lib/parsers/string.js +50 -0
- package/backend-project/node_modules/mysql2/lib/parsers/text_parser.js +214 -0
- package/backend-project/node_modules/mysql2/lib/pool.js +12 -0
- package/backend-project/node_modules/mysql2/lib/pool_cluster.js +375 -0
- package/backend-project/node_modules/mysql2/lib/pool_config.js +34 -0
- package/backend-project/node_modules/mysql2/lib/pool_connection.js +81 -0
- package/backend-project/node_modules/mysql2/lib/promise/capture_local_err.js +25 -0
- package/backend-project/node_modules/mysql2/lib/promise/connection.js +237 -0
- package/backend-project/node_modules/mysql2/lib/promise/inherit_events.js +27 -0
- package/backend-project/node_modules/mysql2/lib/promise/make_done_cb.js +16 -0
- package/backend-project/node_modules/mysql2/lib/promise/pool.js +118 -0
- package/backend-project/node_modules/mysql2/lib/promise/pool_cluster.js +59 -0
- package/backend-project/node_modules/mysql2/lib/promise/pool_connection.js +19 -0
- package/backend-project/node_modules/mysql2/lib/promise/prepared_statement_info.js +35 -0
- package/backend-project/node_modules/mysql2/lib/results_stream.js +38 -0
- package/backend-project/node_modules/mysql2/lib/server.js +37 -0
- package/backend-project/node_modules/mysql2/lib/tracing.js +81 -0
- package/backend-project/node_modules/mysql2/package.json +95 -0
- package/backend-project/node_modules/mysql2/promise.d.ts +141 -0
- package/backend-project/node_modules/mysql2/promise.js +209 -0
- package/backend-project/node_modules/mysql2/typings/mysql/LICENSE.txt +15 -0
- package/backend-project/node_modules/mysql2/typings/mysql/index.d.ts +93 -0
- package/backend-project/node_modules/mysql2/typings/mysql/info.txt +1 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/Auth.d.ts +30 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/Connection.d.ts +456 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/Pool.d.ts +78 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/PoolCluster.d.ts +92 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/PoolConnection.d.ts +11 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/Server.d.ts +11 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/Tracing.d.ts +71 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/constants/CharsetToEncoding.d.ts +8 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/constants/Charsets.d.ts +326 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/constants/Types.d.ts +70 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/constants/index.d.ts +5 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/parsers/ParserCache.d.ts +4 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/parsers/index.d.ts +18 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/parsers/typeCast.d.ts +54 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/Field.d.ts +10 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/FieldPacket.d.ts +27 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/OkPacket.d.ts +23 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/ProcedurePacket.d.ts +13 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/ResultSetHeader.d.ts +18 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/RowDataPacket.d.ts +9 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/index.d.ts +28 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/params/ErrorPacketParams.d.ts +6 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/packets/params/OkPacketParams.d.ts +9 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts +41 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/sequences/Prepare.d.ts +65 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/sequences/Query.d.ts +235 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/sequences/QueryableBase.d.ts +41 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/sequences/Sequence.d.ts +5 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts +17 -0
- package/backend-project/node_modules/mysql2/typings/mysql/lib/protocol/sequences/promise/QueryableBase.d.ts +18 -0
- package/backend-project/node_modules/named-placeholders/LICENSE +21 -0
- package/backend-project/node_modules/named-placeholders/README.md +27 -0
- package/backend-project/node_modules/named-placeholders/index.js +179 -0
- package/backend-project/node_modules/named-placeholders/package.json +36 -0
- package/backend-project/node_modules/negotiator/HISTORY.md +114 -0
- package/backend-project/node_modules/negotiator/LICENSE +24 -0
- package/backend-project/node_modules/negotiator/README.md +212 -0
- package/backend-project/node_modules/negotiator/index.js +83 -0
- package/backend-project/node_modules/negotiator/lib/charset.js +169 -0
- package/backend-project/node_modules/negotiator/lib/encoding.js +205 -0
- package/backend-project/node_modules/negotiator/lib/language.js +179 -0
- package/backend-project/node_modules/negotiator/lib/mediaType.js +294 -0
- package/backend-project/node_modules/negotiator/package.json +43 -0
- package/backend-project/node_modules/nodemon/.prettierrc.json +3 -0
- package/backend-project/node_modules/nodemon/LICENSE +21 -0
- package/backend-project/node_modules/nodemon/README.md +439 -0
- package/backend-project/node_modules/nodemon/bin/nodemon.js +16 -0
- package/backend-project/node_modules/nodemon/bin/windows-kill.exe +0 -0
- package/backend-project/node_modules/nodemon/doc/cli/authors.txt +8 -0
- package/backend-project/node_modules/nodemon/doc/cli/config.txt +44 -0
- package/backend-project/node_modules/nodemon/doc/cli/help.txt +29 -0
- package/backend-project/node_modules/nodemon/doc/cli/logo.txt +20 -0
- package/backend-project/node_modules/nodemon/doc/cli/options.txt +36 -0
- package/backend-project/node_modules/nodemon/doc/cli/topics.txt +8 -0
- package/backend-project/node_modules/nodemon/doc/cli/usage.txt +3 -0
- package/backend-project/node_modules/nodemon/doc/cli/whoami.txt +9 -0
- package/backend-project/node_modules/nodemon/index.d.ts +124 -0
- package/backend-project/node_modules/nodemon/jsconfig.json +7 -0
- package/backend-project/node_modules/nodemon/lib/cli/index.js +49 -0
- package/backend-project/node_modules/nodemon/lib/cli/parse.js +230 -0
- package/backend-project/node_modules/nodemon/lib/config/command.js +43 -0
- package/backend-project/node_modules/nodemon/lib/config/defaults.js +34 -0
- package/backend-project/node_modules/nodemon/lib/config/exec.js +240 -0
- package/backend-project/node_modules/nodemon/lib/config/index.js +93 -0
- package/backend-project/node_modules/nodemon/lib/config/load.js +225 -0
- package/backend-project/node_modules/nodemon/lib/help/index.js +27 -0
- package/backend-project/node_modules/nodemon/lib/index.js +1 -0
- package/backend-project/node_modules/nodemon/lib/monitor/index.js +4 -0
- package/backend-project/node_modules/nodemon/lib/monitor/match.js +288 -0
- package/backend-project/node_modules/nodemon/lib/monitor/run.js +562 -0
- package/backend-project/node_modules/nodemon/lib/monitor/signals.js +34 -0
- package/backend-project/node_modules/nodemon/lib/monitor/watch.js +244 -0
- package/backend-project/node_modules/nodemon/lib/nodemon.js +317 -0
- package/backend-project/node_modules/nodemon/lib/rules/add.js +89 -0
- package/backend-project/node_modules/nodemon/lib/rules/index.js +53 -0
- package/backend-project/node_modules/nodemon/lib/rules/parse.js +43 -0
- package/backend-project/node_modules/nodemon/lib/spawn.js +74 -0
- package/backend-project/node_modules/nodemon/lib/utils/bus.js +44 -0
- package/backend-project/node_modules/nodemon/lib/utils/clone.js +40 -0
- package/backend-project/node_modules/nodemon/lib/utils/colour.js +26 -0
- package/backend-project/node_modules/nodemon/lib/utils/index.js +103 -0
- package/backend-project/node_modules/nodemon/lib/utils/log.js +82 -0
- package/backend-project/node_modules/nodemon/lib/utils/merge.js +47 -0
- package/backend-project/node_modules/nodemon/lib/version.js +100 -0
- package/backend-project/node_modules/nodemon/package.json +78 -0
- package/backend-project/node_modules/normalize-path/LICENSE +21 -0
- package/backend-project/node_modules/normalize-path/README.md +127 -0
- package/backend-project/node_modules/normalize-path/index.js +35 -0
- package/backend-project/node_modules/normalize-path/package.json +77 -0
- package/backend-project/node_modules/object-assign/index.js +90 -0
- package/backend-project/node_modules/object-assign/license +21 -0
- package/backend-project/node_modules/object-assign/package.json +42 -0
- package/backend-project/node_modules/object-assign/readme.md +61 -0
- package/backend-project/node_modules/object-inspect/.eslintrc +53 -0
- package/backend-project/node_modules/object-inspect/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/object-inspect/.nycrc +13 -0
- package/backend-project/node_modules/object-inspect/CHANGELOG.md +424 -0
- package/backend-project/node_modules/object-inspect/LICENSE +21 -0
- package/backend-project/node_modules/object-inspect/example/all.js +23 -0
- package/backend-project/node_modules/object-inspect/example/circular.js +6 -0
- package/backend-project/node_modules/object-inspect/example/fn.js +5 -0
- package/backend-project/node_modules/object-inspect/example/inspect.js +10 -0
- package/backend-project/node_modules/object-inspect/index.js +544 -0
- package/backend-project/node_modules/object-inspect/package-support.json +20 -0
- package/backend-project/node_modules/object-inspect/package.json +105 -0
- package/backend-project/node_modules/object-inspect/readme.markdown +84 -0
- package/backend-project/node_modules/object-inspect/test/bigint.js +58 -0
- package/backend-project/node_modules/object-inspect/test/browser/dom.js +15 -0
- package/backend-project/node_modules/object-inspect/test/circular.js +16 -0
- package/backend-project/node_modules/object-inspect/test/deep.js +12 -0
- package/backend-project/node_modules/object-inspect/test/element.js +53 -0
- package/backend-project/node_modules/object-inspect/test/err.js +48 -0
- package/backend-project/node_modules/object-inspect/test/fakes.js +29 -0
- package/backend-project/node_modules/object-inspect/test/fn.js +76 -0
- package/backend-project/node_modules/object-inspect/test/global.js +17 -0
- package/backend-project/node_modules/object-inspect/test/has.js +15 -0
- package/backend-project/node_modules/object-inspect/test/holes.js +15 -0
- package/backend-project/node_modules/object-inspect/test/indent-option.js +271 -0
- package/backend-project/node_modules/object-inspect/test/inspect.js +139 -0
- package/backend-project/node_modules/object-inspect/test/lowbyte.js +12 -0
- package/backend-project/node_modules/object-inspect/test/number.js +58 -0
- package/backend-project/node_modules/object-inspect/test/quoteStyle.js +26 -0
- package/backend-project/node_modules/object-inspect/test/toStringTag.js +40 -0
- package/backend-project/node_modules/object-inspect/test/undef.js +12 -0
- package/backend-project/node_modules/object-inspect/test/values.js +261 -0
- package/backend-project/node_modules/object-inspect/test-core-js.js +26 -0
- package/backend-project/node_modules/object-inspect/util.inspect.js +1 -0
- package/backend-project/node_modules/on-finished/HISTORY.md +98 -0
- package/backend-project/node_modules/on-finished/LICENSE +23 -0
- package/backend-project/node_modules/on-finished/README.md +162 -0
- package/backend-project/node_modules/on-finished/index.js +234 -0
- package/backend-project/node_modules/on-finished/package.json +39 -0
- package/backend-project/node_modules/once/LICENSE +15 -0
- package/backend-project/node_modules/once/README.md +79 -0
- package/backend-project/node_modules/once/once.js +42 -0
- package/backend-project/node_modules/once/package.json +33 -0
- package/backend-project/node_modules/parseurl/HISTORY.md +58 -0
- package/backend-project/node_modules/parseurl/LICENSE +24 -0
- package/backend-project/node_modules/parseurl/README.md +133 -0
- package/backend-project/node_modules/parseurl/index.js +158 -0
- package/backend-project/node_modules/parseurl/package.json +40 -0
- package/backend-project/node_modules/path-to-regexp/LICENSE +21 -0
- package/backend-project/node_modules/path-to-regexp/Readme.md +224 -0
- package/backend-project/node_modules/path-to-regexp/dist/index.d.ts +147 -0
- package/backend-project/node_modules/path-to-regexp/dist/index.js +431 -0
- package/backend-project/node_modules/path-to-regexp/dist/index.js.map +1 -0
- package/backend-project/node_modules/path-to-regexp/package.json +64 -0
- package/backend-project/node_modules/picomatch/LICENSE +21 -0
- package/backend-project/node_modules/picomatch/README.md +716 -0
- package/backend-project/node_modules/picomatch/index.js +3 -0
- package/backend-project/node_modules/picomatch/lib/constants.js +184 -0
- package/backend-project/node_modules/picomatch/lib/parse.js +1392 -0
- package/backend-project/node_modules/picomatch/lib/picomatch.js +342 -0
- package/backend-project/node_modules/picomatch/lib/scan.js +391 -0
- package/backend-project/node_modules/picomatch/lib/utils.js +64 -0
- package/backend-project/node_modules/picomatch/package.json +81 -0
- package/backend-project/node_modules/proxy-addr/HISTORY.md +161 -0
- package/backend-project/node_modules/proxy-addr/LICENSE +22 -0
- package/backend-project/node_modules/proxy-addr/README.md +139 -0
- package/backend-project/node_modules/proxy-addr/index.js +327 -0
- package/backend-project/node_modules/proxy-addr/package.json +47 -0
- package/backend-project/node_modules/pstree.remy/.travis.yml +8 -0
- package/backend-project/node_modules/pstree.remy/LICENSE +7 -0
- package/backend-project/node_modules/pstree.remy/README.md +26 -0
- package/backend-project/node_modules/pstree.remy/lib/index.js +37 -0
- package/backend-project/node_modules/pstree.remy/lib/tree.js +37 -0
- package/backend-project/node_modules/pstree.remy/lib/utils.js +53 -0
- package/backend-project/node_modules/pstree.remy/package.json +33 -0
- package/backend-project/node_modules/pstree.remy/tests/fixtures/index.js +13 -0
- package/backend-project/node_modules/pstree.remy/tests/fixtures/out1 +10 -0
- package/backend-project/node_modules/pstree.remy/tests/fixtures/out2 +29 -0
- package/backend-project/node_modules/pstree.remy/tests/index.test.js +51 -0
- package/backend-project/node_modules/qs/.editorconfig +46 -0
- package/backend-project/node_modules/qs/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/qs/.github/SECURITY.md +11 -0
- package/backend-project/node_modules/qs/.github/THREAT_MODEL.md +78 -0
- package/backend-project/node_modules/qs/.nycrc +13 -0
- package/backend-project/node_modules/qs/CHANGELOG.md +812 -0
- package/backend-project/node_modules/qs/LICENSE.md +29 -0
- package/backend-project/node_modules/qs/README.md +758 -0
- package/backend-project/node_modules/qs/dist/qs.js +141 -0
- package/backend-project/node_modules/qs/eslint.config.mjs +56 -0
- package/backend-project/node_modules/qs/lib/formats.js +23 -0
- package/backend-project/node_modules/qs/lib/index.js +11 -0
- package/backend-project/node_modules/qs/lib/parse.js +373 -0
- package/backend-project/node_modules/qs/lib/stringify.js +356 -0
- package/backend-project/node_modules/qs/lib/utils.js +342 -0
- package/backend-project/node_modules/qs/package.json +94 -0
- package/backend-project/node_modules/qs/test/empty-keys-cases.js +267 -0
- package/backend-project/node_modules/qs/test/parse.js +1654 -0
- package/backend-project/node_modules/qs/test/stringify.js +1319 -0
- package/backend-project/node_modules/qs/test/utils.js +432 -0
- package/backend-project/node_modules/range-parser/HISTORY.md +56 -0
- package/backend-project/node_modules/range-parser/LICENSE +23 -0
- package/backend-project/node_modules/range-parser/README.md +84 -0
- package/backend-project/node_modules/range-parser/index.js +162 -0
- package/backend-project/node_modules/range-parser/package.json +44 -0
- package/backend-project/node_modules/raw-body/LICENSE +22 -0
- package/backend-project/node_modules/raw-body/README.md +223 -0
- package/backend-project/node_modules/raw-body/index.d.ts +85 -0
- package/backend-project/node_modules/raw-body/index.js +336 -0
- package/backend-project/node_modules/raw-body/package.json +46 -0
- package/backend-project/node_modules/readdirp/LICENSE +21 -0
- package/backend-project/node_modules/readdirp/README.md +122 -0
- package/backend-project/node_modules/readdirp/index.d.ts +43 -0
- package/backend-project/node_modules/readdirp/index.js +287 -0
- package/backend-project/node_modules/readdirp/package.json +122 -0
- package/backend-project/node_modules/router/HISTORY.md +228 -0
- package/backend-project/node_modules/router/LICENSE +23 -0
- package/backend-project/node_modules/router/README.md +416 -0
- package/backend-project/node_modules/router/index.js +748 -0
- package/backend-project/node_modules/router/lib/layer.js +247 -0
- package/backend-project/node_modules/router/lib/route.js +242 -0
- package/backend-project/node_modules/router/package.json +44 -0
- package/backend-project/node_modules/safer-buffer/LICENSE +21 -0
- package/backend-project/node_modules/safer-buffer/Porting-Buffer.md +268 -0
- package/backend-project/node_modules/safer-buffer/Readme.md +156 -0
- package/backend-project/node_modules/safer-buffer/dangerous.js +58 -0
- package/backend-project/node_modules/safer-buffer/package.json +34 -0
- package/backend-project/node_modules/safer-buffer/safer.js +77 -0
- package/backend-project/node_modules/safer-buffer/tests.js +406 -0
- package/backend-project/node_modules/semver/LICENSE +15 -0
- package/backend-project/node_modules/semver/README.md +680 -0
- package/backend-project/node_modules/semver/bin/semver.js +195 -0
- package/backend-project/node_modules/semver/classes/comparator.js +143 -0
- package/backend-project/node_modules/semver/classes/index.js +7 -0
- package/backend-project/node_modules/semver/classes/range.js +557 -0
- package/backend-project/node_modules/semver/classes/semver.js +333 -0
- package/backend-project/node_modules/semver/functions/clean.js +8 -0
- package/backend-project/node_modules/semver/functions/cmp.js +54 -0
- package/backend-project/node_modules/semver/functions/coerce.js +62 -0
- package/backend-project/node_modules/semver/functions/compare-build.js +9 -0
- package/backend-project/node_modules/semver/functions/compare-loose.js +5 -0
- package/backend-project/node_modules/semver/functions/compare.js +7 -0
- package/backend-project/node_modules/semver/functions/diff.js +60 -0
- package/backend-project/node_modules/semver/functions/eq.js +5 -0
- package/backend-project/node_modules/semver/functions/gt.js +5 -0
- package/backend-project/node_modules/semver/functions/gte.js +5 -0
- package/backend-project/node_modules/semver/functions/inc.js +21 -0
- package/backend-project/node_modules/semver/functions/lt.js +5 -0
- package/backend-project/node_modules/semver/functions/lte.js +5 -0
- package/backend-project/node_modules/semver/functions/major.js +5 -0
- package/backend-project/node_modules/semver/functions/minor.js +5 -0
- package/backend-project/node_modules/semver/functions/neq.js +5 -0
- package/backend-project/node_modules/semver/functions/parse.js +18 -0
- package/backend-project/node_modules/semver/functions/patch.js +5 -0
- package/backend-project/node_modules/semver/functions/prerelease.js +8 -0
- package/backend-project/node_modules/semver/functions/rcompare.js +5 -0
- package/backend-project/node_modules/semver/functions/rsort.js +5 -0
- package/backend-project/node_modules/semver/functions/satisfies.js +12 -0
- package/backend-project/node_modules/semver/functions/sort.js +5 -0
- package/backend-project/node_modules/semver/functions/truncate.js +48 -0
- package/backend-project/node_modules/semver/functions/valid.js +8 -0
- package/backend-project/node_modules/semver/index.js +93 -0
- package/backend-project/node_modules/semver/internal/constants.js +37 -0
- package/backend-project/node_modules/semver/internal/debug.js +11 -0
- package/backend-project/node_modules/semver/internal/identifiers.js +29 -0
- package/backend-project/node_modules/semver/internal/lrucache.js +42 -0
- package/backend-project/node_modules/semver/internal/parse-options.js +17 -0
- package/backend-project/node_modules/semver/internal/re.js +223 -0
- package/backend-project/node_modules/semver/package.json +78 -0
- package/backend-project/node_modules/semver/preload.js +4 -0
- package/backend-project/node_modules/semver/range.bnf +17 -0
- package/backend-project/node_modules/semver/ranges/gtr.js +6 -0
- package/backend-project/node_modules/semver/ranges/intersects.js +9 -0
- package/backend-project/node_modules/semver/ranges/ltr.js +6 -0
- package/backend-project/node_modules/semver/ranges/max-satisfying.js +27 -0
- package/backend-project/node_modules/semver/ranges/min-satisfying.js +26 -0
- package/backend-project/node_modules/semver/ranges/min-version.js +63 -0
- package/backend-project/node_modules/semver/ranges/outside.js +82 -0
- package/backend-project/node_modules/semver/ranges/simplify.js +49 -0
- package/backend-project/node_modules/semver/ranges/subset.js +249 -0
- package/backend-project/node_modules/semver/ranges/to-comparators.js +10 -0
- package/backend-project/node_modules/semver/ranges/valid.js +13 -0
- package/backend-project/node_modules/send/LICENSE +23 -0
- package/backend-project/node_modules/send/README.md +317 -0
- package/backend-project/node_modules/send/index.js +997 -0
- package/backend-project/node_modules/send/package.json +63 -0
- package/backend-project/node_modules/serve-static/LICENSE +25 -0
- package/backend-project/node_modules/serve-static/README.md +253 -0
- package/backend-project/node_modules/serve-static/index.js +208 -0
- package/backend-project/node_modules/serve-static/package.json +44 -0
- package/backend-project/node_modules/setprototypeof/LICENSE +13 -0
- package/backend-project/node_modules/setprototypeof/README.md +31 -0
- package/backend-project/node_modules/setprototypeof/index.d.ts +2 -0
- package/backend-project/node_modules/setprototypeof/index.js +17 -0
- package/backend-project/node_modules/setprototypeof/package.json +38 -0
- package/backend-project/node_modules/setprototypeof/test/index.js +24 -0
- package/backend-project/node_modules/side-channel/.editorconfig +9 -0
- package/backend-project/node_modules/side-channel/.eslintrc +12 -0
- package/backend-project/node_modules/side-channel/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/side-channel/.nycrc +13 -0
- package/backend-project/node_modules/side-channel/CHANGELOG.md +110 -0
- package/backend-project/node_modules/side-channel/LICENSE +21 -0
- package/backend-project/node_modules/side-channel/README.md +61 -0
- package/backend-project/node_modules/side-channel/index.d.ts +14 -0
- package/backend-project/node_modules/side-channel/index.js +43 -0
- package/backend-project/node_modules/side-channel/package.json +85 -0
- package/backend-project/node_modules/side-channel/test/index.js +104 -0
- package/backend-project/node_modules/side-channel/tsconfig.json +9 -0
- package/backend-project/node_modules/side-channel-list/.editorconfig +9 -0
- package/backend-project/node_modules/side-channel-list/.eslintrc +11 -0
- package/backend-project/node_modules/side-channel-list/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/side-channel-list/.nycrc +13 -0
- package/backend-project/node_modules/side-channel-list/CHANGELOG.md +36 -0
- package/backend-project/node_modules/side-channel-list/LICENSE +21 -0
- package/backend-project/node_modules/side-channel-list/README.md +62 -0
- package/backend-project/node_modules/side-channel-list/index.d.ts +13 -0
- package/backend-project/node_modules/side-channel-list/index.js +111 -0
- package/backend-project/node_modules/side-channel-list/list.d.ts +14 -0
- package/backend-project/node_modules/side-channel-list/package.json +77 -0
- package/backend-project/node_modules/side-channel-list/test/index.js +154 -0
- package/backend-project/node_modules/side-channel-list/tsconfig.json +9 -0
- package/backend-project/node_modules/side-channel-map/.editorconfig +9 -0
- package/backend-project/node_modules/side-channel-map/.eslintrc +11 -0
- package/backend-project/node_modules/side-channel-map/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/side-channel-map/.nycrc +13 -0
- package/backend-project/node_modules/side-channel-map/CHANGELOG.md +22 -0
- package/backend-project/node_modules/side-channel-map/LICENSE +21 -0
- package/backend-project/node_modules/side-channel-map/README.md +62 -0
- package/backend-project/node_modules/side-channel-map/index.d.ts +15 -0
- package/backend-project/node_modules/side-channel-map/index.js +68 -0
- package/backend-project/node_modules/side-channel-map/package.json +80 -0
- package/backend-project/node_modules/side-channel-map/test/index.js +114 -0
- package/backend-project/node_modules/side-channel-map/tsconfig.json +9 -0
- package/backend-project/node_modules/side-channel-weakmap/.editorconfig +9 -0
- package/backend-project/node_modules/side-channel-weakmap/.eslintrc +12 -0
- package/backend-project/node_modules/side-channel-weakmap/.github/FUNDING.yml +12 -0
- package/backend-project/node_modules/side-channel-weakmap/.nycrc +13 -0
- package/backend-project/node_modules/side-channel-weakmap/CHANGELOG.md +28 -0
- package/backend-project/node_modules/side-channel-weakmap/LICENSE +21 -0
- package/backend-project/node_modules/side-channel-weakmap/README.md +62 -0
- package/backend-project/node_modules/side-channel-weakmap/index.d.ts +15 -0
- package/backend-project/node_modules/side-channel-weakmap/index.js +84 -0
- package/backend-project/node_modules/side-channel-weakmap/package.json +87 -0
- package/backend-project/node_modules/side-channel-weakmap/test/index.js +114 -0
- package/backend-project/node_modules/side-channel-weakmap/tsconfig.json +9 -0
- package/backend-project/node_modules/simple-update-notifier/LICENSE +21 -0
- package/backend-project/node_modules/simple-update-notifier/README.md +82 -0
- package/backend-project/node_modules/simple-update-notifier/build/index.d.ts +13 -0
- package/backend-project/node_modules/simple-update-notifier/build/index.js +210 -0
- package/backend-project/node_modules/simple-update-notifier/package.json +100 -0
- package/backend-project/node_modules/simple-update-notifier/src/borderedText.ts +12 -0
- package/backend-project/node_modules/simple-update-notifier/src/cache.spec.ts +17 -0
- package/backend-project/node_modules/simple-update-notifier/src/cache.ts +44 -0
- package/backend-project/node_modules/simple-update-notifier/src/getDistVersion.spec.ts +35 -0
- package/backend-project/node_modules/simple-update-notifier/src/getDistVersion.ts +29 -0
- package/backend-project/node_modules/simple-update-notifier/src/hasNewVersion.spec.ts +82 -0
- package/backend-project/node_modules/simple-update-notifier/src/hasNewVersion.ts +40 -0
- package/backend-project/node_modules/simple-update-notifier/src/index.spec.ts +27 -0
- package/backend-project/node_modules/simple-update-notifier/src/index.ts +34 -0
- package/backend-project/node_modules/simple-update-notifier/src/isNpmOrYarn.ts +12 -0
- package/backend-project/node_modules/simple-update-notifier/src/types.ts +8 -0
- package/backend-project/node_modules/sql-escaper/LICENSE +21 -0
- package/backend-project/node_modules/sql-escaper/README.md +424 -0
- package/backend-project/node_modules/sql-escaper/lib/index.d.ts +15 -0
- package/backend-project/node_modules/sql-escaper/lib/index.js +398 -0
- package/backend-project/node_modules/sql-escaper/lib/index.mjs +305 -0
- package/backend-project/node_modules/sql-escaper/lib/types.d.ts +5 -0
- package/backend-project/node_modules/sql-escaper/lib/types.js +2 -0
- package/backend-project/node_modules/sql-escaper/package.json +81 -0
- package/backend-project/node_modules/statuses/HISTORY.md +87 -0
- package/backend-project/node_modules/statuses/LICENSE +23 -0
- package/backend-project/node_modules/statuses/README.md +139 -0
- package/backend-project/node_modules/statuses/codes.json +65 -0
- package/backend-project/node_modules/statuses/index.js +146 -0
- package/backend-project/node_modules/statuses/package.json +49 -0
- package/backend-project/node_modules/supports-color/browser.js +5 -0
- package/backend-project/node_modules/supports-color/index.js +131 -0
- package/backend-project/node_modules/supports-color/license +9 -0
- package/backend-project/node_modules/supports-color/package.json +53 -0
- package/backend-project/node_modules/supports-color/readme.md +66 -0
- package/backend-project/node_modules/to-regex-range/LICENSE +21 -0
- package/backend-project/node_modules/to-regex-range/README.md +305 -0
- package/backend-project/node_modules/to-regex-range/index.js +288 -0
- package/backend-project/node_modules/to-regex-range/package.json +88 -0
- package/backend-project/node_modules/toidentifier/HISTORY.md +9 -0
- package/backend-project/node_modules/toidentifier/LICENSE +21 -0
- package/backend-project/node_modules/toidentifier/README.md +61 -0
- package/backend-project/node_modules/toidentifier/index.js +32 -0
- package/backend-project/node_modules/toidentifier/package.json +38 -0
- package/backend-project/node_modules/touch/LICENSE +15 -0
- package/backend-project/node_modules/touch/README.md +52 -0
- package/backend-project/node_modules/touch/bin/nodetouch.js +112 -0
- package/backend-project/node_modules/touch/index.js +224 -0
- package/backend-project/node_modules/touch/package.json +25 -0
- package/backend-project/node_modules/type-is/HISTORY.md +292 -0
- package/backend-project/node_modules/type-is/LICENSE +23 -0
- package/backend-project/node_modules/type-is/README.md +198 -0
- package/backend-project/node_modules/type-is/index.js +250 -0
- package/backend-project/node_modules/type-is/package.json +47 -0
- package/backend-project/node_modules/undefsafe/.github/workflows/release.yml +25 -0
- package/backend-project/node_modules/undefsafe/.jscsrc +13 -0
- package/backend-project/node_modules/undefsafe/.jshintrc +16 -0
- package/backend-project/node_modules/undefsafe/.travis.yml +18 -0
- package/backend-project/node_modules/undefsafe/LICENSE +22 -0
- package/backend-project/node_modules/undefsafe/README.md +63 -0
- package/backend-project/node_modules/undefsafe/example.js +14 -0
- package/backend-project/node_modules/undefsafe/lib/undefsafe.js +125 -0
- package/backend-project/node_modules/undefsafe/package.json +34 -0
- package/backend-project/node_modules/undici-types/LICENSE +21 -0
- package/backend-project/node_modules/undici-types/README.md +6 -0
- package/backend-project/node_modules/undici-types/agent.d.ts +32 -0
- package/backend-project/node_modules/undici-types/api.d.ts +43 -0
- package/backend-project/node_modules/undici-types/balanced-pool.d.ts +30 -0
- package/backend-project/node_modules/undici-types/cache-interceptor.d.ts +179 -0
- package/backend-project/node_modules/undici-types/cache.d.ts +36 -0
- package/backend-project/node_modules/undici-types/client-stats.d.ts +15 -0
- package/backend-project/node_modules/undici-types/client.d.ts +123 -0
- package/backend-project/node_modules/undici-types/connector.d.ts +34 -0
- package/backend-project/node_modules/undici-types/content-type.d.ts +21 -0
- package/backend-project/node_modules/undici-types/cookies.d.ts +30 -0
- package/backend-project/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
- package/backend-project/node_modules/undici-types/dispatcher.d.ts +277 -0
- package/backend-project/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
- package/backend-project/node_modules/undici-types/errors.d.ts +161 -0
- package/backend-project/node_modules/undici-types/eventsource.d.ts +66 -0
- package/backend-project/node_modules/undici-types/fetch.d.ts +211 -0
- package/backend-project/node_modules/undici-types/formdata.d.ts +108 -0
- package/backend-project/node_modules/undici-types/global-dispatcher.d.ts +9 -0
- package/backend-project/node_modules/undici-types/global-origin.d.ts +7 -0
- package/backend-project/node_modules/undici-types/h2c-client.d.ts +73 -0
- package/backend-project/node_modules/undici-types/handlers.d.ts +15 -0
- package/backend-project/node_modules/undici-types/header.d.ts +160 -0
- package/backend-project/node_modules/undici-types/index.d.ts +88 -0
- package/backend-project/node_modules/undici-types/interceptors.d.ts +73 -0
- package/backend-project/node_modules/undici-types/mock-agent.d.ts +68 -0
- package/backend-project/node_modules/undici-types/mock-call-history.d.ts +111 -0
- package/backend-project/node_modules/undici-types/mock-client.d.ts +27 -0
- package/backend-project/node_modules/undici-types/mock-errors.d.ts +12 -0
- package/backend-project/node_modules/undici-types/mock-interceptor.d.ts +94 -0
- package/backend-project/node_modules/undici-types/mock-pool.d.ts +27 -0
- package/backend-project/node_modules/undici-types/package.json +55 -0
- package/backend-project/node_modules/undici-types/patch.d.ts +29 -0
- package/backend-project/node_modules/undici-types/pool-stats.d.ts +19 -0
- package/backend-project/node_modules/undici-types/pool.d.ts +41 -0
- package/backend-project/node_modules/undici-types/proxy-agent.d.ts +29 -0
- package/backend-project/node_modules/undici-types/readable.d.ts +68 -0
- package/backend-project/node_modules/undici-types/retry-agent.d.ts +8 -0
- package/backend-project/node_modules/undici-types/retry-handler.d.ts +125 -0
- package/backend-project/node_modules/undici-types/round-robin-pool.d.ts +41 -0
- package/backend-project/node_modules/undici-types/snapshot-agent.d.ts +109 -0
- package/backend-project/node_modules/undici-types/util.d.ts +18 -0
- package/backend-project/node_modules/undici-types/utility.d.ts +7 -0
- package/backend-project/node_modules/undici-types/webidl.d.ts +347 -0
- package/backend-project/node_modules/undici-types/websocket.d.ts +188 -0
- package/backend-project/node_modules/unpipe/HISTORY.md +4 -0
- package/backend-project/node_modules/unpipe/LICENSE +22 -0
- package/backend-project/node_modules/unpipe/README.md +43 -0
- package/backend-project/node_modules/unpipe/index.js +69 -0
- package/backend-project/node_modules/unpipe/package.json +27 -0
- package/backend-project/node_modules/vary/HISTORY.md +39 -0
- package/backend-project/node_modules/vary/LICENSE +22 -0
- package/backend-project/node_modules/vary/README.md +101 -0
- package/backend-project/node_modules/vary/index.js +149 -0
- package/backend-project/node_modules/vary/package.json +43 -0
- package/backend-project/node_modules/wrappy/LICENSE +15 -0
- package/backend-project/node_modules/wrappy/README.md +36 -0
- package/backend-project/node_modules/wrappy/package.json +29 -0
- package/backend-project/node_modules/wrappy/wrappy.js +33 -0
- package/backend-project/package-lock.json +1308 -0
- package/backend-project/package.json +20 -0
- package/backend-project/server.js +1263 -0
- package/frontend-project/README.md +16 -0
- package/frontend-project/eslint.config.js +21 -0
- package/frontend-project/index.html +13 -0
- package/frontend-project/package-lock.json +2999 -0
- package/frontend-project/package.json +30 -0
- package/frontend-project/public/favicon.svg +1 -0
- package/frontend-project/public/icons.svg +24 -0
- package/frontend-project/src/App.css +184 -0
- package/frontend-project/src/App.jsx +1888 -0
- package/frontend-project/src/assets/hero.png +0 -0
- package/frontend-project/src/assets/react.svg +1 -0
- package/frontend-project/src/assets/vite.svg +1 -0
- package/frontend-project/src/exister 1.code-workspace +8 -0
- package/frontend-project/src/index.css +1 -0
- package/frontend-project/src/main.jsx +10 -0
- package/frontend-project/vite.config.js +16 -0
- package/package.json +13 -0
|
@@ -0,0 +1,1888 @@
|
|
|
1
|
+
// // import { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
// // import axios from 'axios';
|
|
3
|
+
|
|
4
|
+
// // function App() {
|
|
5
|
+
// // const [activeTab, setActiveTab] = useState('dashboard');
|
|
6
|
+
// // const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
7
|
+
// // const [loginData, setLoginData] = useState({ username: '', password: '' });
|
|
8
|
+
// // const [user, setUser] = useState(null);
|
|
9
|
+
|
|
10
|
+
// // // Data States
|
|
11
|
+
// // const [patients, setPatients] = useState([]);
|
|
12
|
+
// // const [doctors, setDoctors] = useState([]);
|
|
13
|
+
// // const [appointments, setAppointments] = useState([]);
|
|
14
|
+
// // const [payments, setPayments] = useState([]);
|
|
15
|
+
|
|
16
|
+
// // // Form States
|
|
17
|
+
// // const [patientForm, setPatientForm] = useState({ PatientID: null, Name: '', Age: '', Phone: '' });
|
|
18
|
+
// // const [doctorForm, setDoctorForm] = useState({ DoctorID: null, Name: '', Specialization: '' });
|
|
19
|
+
// // const [appointmentForm, setAppointmentForm] = useState({ AppointmentID: null, PatientID: '', DoctorID: '', Date: '' });
|
|
20
|
+
// // const [paymentForm, setPaymentForm] = useState({ PaymentID: null, PatientID: '', Amount: '', Date: '' });
|
|
21
|
+
|
|
22
|
+
// // // Authentication
|
|
23
|
+
// // const handleLogin = async (e) => {
|
|
24
|
+
// // e.preventDefault();
|
|
25
|
+
// // try {
|
|
26
|
+
// // const response = await axios.post('http://localhost:5000/api/login', loginData, {
|
|
27
|
+
// // headers: { 'Content-Type': 'application/json' }
|
|
28
|
+
// // });
|
|
29
|
+
// // if (response.data.success) {
|
|
30
|
+
// // setIsAuthenticated(true);
|
|
31
|
+
// // setUser(response.data.user);
|
|
32
|
+
// // setLoginData({ username: '', password: '' });
|
|
33
|
+
// // } else {
|
|
34
|
+
// // alert(response.data.message);
|
|
35
|
+
// // }
|
|
36
|
+
// // } catch (error) {
|
|
37
|
+
// // if (error.response && error.response.data && error.response.data.message) {
|
|
38
|
+
// // alert(error.response.data.message);
|
|
39
|
+
// // } else {
|
|
40
|
+
// // alert('Login failed. Please check backend connection.');
|
|
41
|
+
// // }
|
|
42
|
+
// // }
|
|
43
|
+
// // };
|
|
44
|
+
|
|
45
|
+
// // const handleLogout = () => {
|
|
46
|
+
// // setIsAuthenticated(false);
|
|
47
|
+
// // setUser(null);
|
|
48
|
+
// // setActiveTab('dashboard');
|
|
49
|
+
// // };
|
|
50
|
+
|
|
51
|
+
// // // Fetch Data Functions
|
|
52
|
+
// // const fetchPatients = useCallback(async () => {
|
|
53
|
+
// // try {
|
|
54
|
+
// // const response = await axios.get('http://localhost:5000/api/patients');
|
|
55
|
+
// // setPatients(response.data);
|
|
56
|
+
// // } catch (err) { console.error(err); }
|
|
57
|
+
// // }, []);
|
|
58
|
+
|
|
59
|
+
// // const fetchDoctors = useCallback(async () => {
|
|
60
|
+
// // try {
|
|
61
|
+
// // const response = await axios.get('http://localhost:5000/api/doctors');
|
|
62
|
+
// // setDoctors(response.data);
|
|
63
|
+
// // } catch (err) { console.error(err); }
|
|
64
|
+
// // }, []);
|
|
65
|
+
|
|
66
|
+
// // const fetchAppointments = useCallback(async () => {
|
|
67
|
+
// // try {
|
|
68
|
+
// // const response = await axios.get('http://localhost:5000/api/appointments');
|
|
69
|
+
// // setAppointments(response.data);
|
|
70
|
+
// // } catch (err) { console.error(err); }
|
|
71
|
+
// // }, []);
|
|
72
|
+
|
|
73
|
+
// // const fetchPayments = useCallback(async () => {
|
|
74
|
+
// // try {
|
|
75
|
+
// // const response = await axios.get('http://localhost:5000/api/payments');
|
|
76
|
+
// // setPayments(response.data);
|
|
77
|
+
// // } catch (err) { console.error(err); }
|
|
78
|
+
// // }, []);
|
|
79
|
+
|
|
80
|
+
// // const fetchAllData = useCallback(() => {
|
|
81
|
+
// // fetchPatients();
|
|
82
|
+
// // fetchDoctors();
|
|
83
|
+
// // fetchAppointments();
|
|
84
|
+
// // fetchPayments();
|
|
85
|
+
// // }, [fetchPatients, fetchDoctors, fetchAppointments, fetchPayments]);
|
|
86
|
+
|
|
87
|
+
// // useEffect(() => {
|
|
88
|
+
// // if (isAuthenticated) {
|
|
89
|
+
// // fetchAllData();
|
|
90
|
+
// // }
|
|
91
|
+
// // }, [isAuthenticated, fetchAllData]);
|
|
92
|
+
|
|
93
|
+
// // // Total Revenue Calculation
|
|
94
|
+
// // const totalRevenue = payments.reduce((sum, p) => sum + Number(p.Amount || 0), 0);
|
|
95
|
+
|
|
96
|
+
// // // Patient Actions
|
|
97
|
+
// // const handlePatientSubmit = async (e) => {
|
|
98
|
+
// // e.preventDefault();
|
|
99
|
+
// // if (!patientForm.Name || !patientForm.Age || !patientForm.Phone) return alert('Fill all fields');
|
|
100
|
+
// // try {
|
|
101
|
+
// // if (patientForm.PatientID) {
|
|
102
|
+
// // await axios.put(`http://localhost:5000/api/patients/${patientForm.PatientID}`, patientForm);
|
|
103
|
+
// // } else {
|
|
104
|
+
// // await axios.post('http://localhost:5000/api/patients', patientForm);
|
|
105
|
+
// // }
|
|
106
|
+
// // setPatientForm({ PatientID: null, Name: '', Age: '', Phone: '' });
|
|
107
|
+
// // fetchAllData();
|
|
108
|
+
// // } catch (err) { alert('Operation failed'); }
|
|
109
|
+
// // };
|
|
110
|
+
|
|
111
|
+
// // const handlePatientDelete = async (id) => {
|
|
112
|
+
// // if (window.confirm('Delete this patient?')) {
|
|
113
|
+
// // try {
|
|
114
|
+
// // await axios.delete(`http://localhost:5000/api/patients/${id}`);
|
|
115
|
+
// // fetchAllData();
|
|
116
|
+
// // } catch (err) { alert('Could not delete patient.'); }
|
|
117
|
+
// // }
|
|
118
|
+
// // };
|
|
119
|
+
|
|
120
|
+
// // // Doctor Actions
|
|
121
|
+
// // const handleDoctorSubmit = async (e) => {
|
|
122
|
+
// // e.preventDefault();
|
|
123
|
+
// // if (!doctorForm.Name || !doctorForm.Specialization) return alert('Fill all fields');
|
|
124
|
+
// // try {
|
|
125
|
+
// // if (doctorForm.DoctorID) {
|
|
126
|
+
// // await axios.put(`http://localhost:5000/api/doctors/${doctorForm.DoctorID}`, doctorForm);
|
|
127
|
+
// // } else {
|
|
128
|
+
// // await axios.post('http://localhost:5000/api/doctors', doctorForm);
|
|
129
|
+
// // }
|
|
130
|
+
// // setDoctorForm({ DoctorID: null, Name: '', Specialization: '' });
|
|
131
|
+
// // fetchAllData();
|
|
132
|
+
// // } catch (err) { alert('Operation failed'); }
|
|
133
|
+
// // };
|
|
134
|
+
|
|
135
|
+
// // const handleDoctorDelete = async (id) => {
|
|
136
|
+
// // if (window.confirm('Delete this doctor?')) {
|
|
137
|
+
// // try {
|
|
138
|
+
// // await axios.delete(`http://localhost:5000/api/doctors/${id}`);
|
|
139
|
+
// // fetchAllData();
|
|
140
|
+
// // } catch (err) { alert('Could not delete doctor.'); }
|
|
141
|
+
// // }
|
|
142
|
+
// // };
|
|
143
|
+
|
|
144
|
+
// // // Appointment Actions
|
|
145
|
+
// // const handleAppointmentSubmit = async (e) => {
|
|
146
|
+
// // e.preventDefault();
|
|
147
|
+
// // if (!appointmentForm.PatientID || !appointmentForm.DoctorID || !appointmentForm.Date) return alert('Fill all fields');
|
|
148
|
+
// // try {
|
|
149
|
+
// // if (appointmentForm.AppointmentID) {
|
|
150
|
+
// // await axios.put(`http://localhost:5000/api/appointments/${appointmentForm.AppointmentID}`, appointmentForm);
|
|
151
|
+
// // } else {
|
|
152
|
+
// // await axios.post('http://localhost:5000/api/appointments', appointmentForm);
|
|
153
|
+
// // }
|
|
154
|
+
// // setAppointmentForm({ AppointmentID: null, PatientID: '', DoctorID: '', Date: '' });
|
|
155
|
+
// // fetchAppointments();
|
|
156
|
+
// // } catch (err) { alert('Operation failed'); }
|
|
157
|
+
// // };
|
|
158
|
+
|
|
159
|
+
// // const handleAppointmentDelete = async (id) => {
|
|
160
|
+
// // if (window.confirm('Delete this appointment?')) {
|
|
161
|
+
// // try {
|
|
162
|
+
// // await axios.delete(`http://localhost:5000/api/appointments/${id}`);
|
|
163
|
+
// // fetchAppointments();
|
|
164
|
+
// // } catch (err) { alert('Operation failed'); }
|
|
165
|
+
// // }
|
|
166
|
+
// // };
|
|
167
|
+
|
|
168
|
+
// // // Payment Actions
|
|
169
|
+
// // const handlePaymentSubmit = async (e) => {
|
|
170
|
+
// // e.preventDefault();
|
|
171
|
+
// // if (!paymentForm.PatientID || !paymentForm.Amount || !paymentForm.Date) return alert('Fill all fields');
|
|
172
|
+
// // try {
|
|
173
|
+
// // if (paymentForm.PaymentID) {
|
|
174
|
+
// // await axios.put(`http://localhost:5000/api/payments/${paymentForm.PaymentID}`, paymentForm);
|
|
175
|
+
// // } else {
|
|
176
|
+
// // await axios.post('http://localhost:5000/api/payments', paymentForm);
|
|
177
|
+
// // }
|
|
178
|
+
// // setPaymentForm({ PaymentID: null, PatientID: '', Amount: '', Date: '' });
|
|
179
|
+
// // fetchPayments();
|
|
180
|
+
// // } catch (err) { alert('Operation failed'); }
|
|
181
|
+
// // };
|
|
182
|
+
|
|
183
|
+
// // const handlePaymentDelete = async (id) => {
|
|
184
|
+
// // if (window.confirm('Delete this payment record?')) {
|
|
185
|
+
// // try {
|
|
186
|
+
// // await axios.delete(`http://localhost:5000/api/payments/${id}`);
|
|
187
|
+
// // fetchPayments();
|
|
188
|
+
// // } catch (err) { alert('Operation failed'); }
|
|
189
|
+
// // }
|
|
190
|
+
// // };
|
|
191
|
+
|
|
192
|
+
// // // UI rendering ya Login niba adahuye
|
|
193
|
+
// // if (!isAuthenticated) {
|
|
194
|
+
// // return (
|
|
195
|
+
// // <div className="min-h-screen bg-gradient-to-tr from-slate-900 via-indigo-950 to-slate-900 flex items-center justify-center p-4">
|
|
196
|
+
// // <div className="bg-white/95 backdrop-blur-md p-8 rounded-2xl shadow-2xl w-full max-w-md border border-white/20">
|
|
197
|
+
// // <div className="text-center mb-8">
|
|
198
|
+
// // <div className="bg-blue-600 text-white w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4 text-3xl font-black shadow-lg shadow-blue-500/30">
|
|
199
|
+
// // H
|
|
200
|
+
// // </div>
|
|
201
|
+
// // <h1 className="text-2xl font-black tracking-tight text-slate-800">Hospital Management</h1>
|
|
202
|
+
// // <p className="text-slate-500 text-sm mt-1">Sign in to access your administrative dashboard</p>
|
|
203
|
+
// // </div>
|
|
204
|
+
// // <form onSubmit={handleLogin} className="space-y-5">
|
|
205
|
+
// // <div>
|
|
206
|
+
// // <label className="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-2">Username</label>
|
|
207
|
+
// // <input
|
|
208
|
+
// // type="text"
|
|
209
|
+
// // value={loginData.username}
|
|
210
|
+
// // onChange={(e) => setLoginData({ ...loginData, username: e.target.value })}
|
|
211
|
+
// // className="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all text-slate-800"
|
|
212
|
+
// // placeholder="Enter your username"
|
|
213
|
+
// // />
|
|
214
|
+
// // </div>
|
|
215
|
+
// // <div>
|
|
216
|
+
// // <label className="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-2">Password</label>
|
|
217
|
+
// // <input
|
|
218
|
+
// // type="password"
|
|
219
|
+
// // value={loginData.password}
|
|
220
|
+
// // onChange={(e) => setLoginData({ ...loginData, password: e.target.value })}
|
|
221
|
+
// // className="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all text-slate-800"
|
|
222
|
+
// // placeholder="••••••••"
|
|
223
|
+
// // />
|
|
224
|
+
// // </div>
|
|
225
|
+
// // <button type="submit" className="w-full bg-gradient-to-r from-blue-600 to-indigo-600 text-white py-3 rounded-xl font-bold shadow-lg shadow-blue-500/20">
|
|
226
|
+
// // Sign In
|
|
227
|
+
// // </button>
|
|
228
|
+
// // </form>
|
|
229
|
+
// // <div className="mt-6 text-center bg-slate-50 py-2.5 rounded-xl border border-slate-100">
|
|
230
|
+
// // <p className="text-xs text-slate-500 font-medium">Demo Access: <span className="font-mono font-bold text-blue-600 bg-blue-50 px-1.5 py-0.5 rounded border border-blue-100">admin / admin123</span></p>
|
|
231
|
+
// // </div>
|
|
232
|
+
// // </div>
|
|
233
|
+
// // </div>
|
|
234
|
+
// // );
|
|
235
|
+
// // }
|
|
236
|
+
|
|
237
|
+
// // return (
|
|
238
|
+
// // <div className="min-h-screen bg-slate-50/50 flex text-slate-800">
|
|
239
|
+
|
|
240
|
+
// // {/* SIDEBAR NAVIGATION */}
|
|
241
|
+
// // <aside className="w-64 bg-slate-900 text-slate-300 flex flex-col fixed inset-y-0 left-0 z-50 border-r border-slate-800 shadow-xl">
|
|
242
|
+
// // <div className="p-5 border-b border-slate-800 flex items-center space-x-3">
|
|
243
|
+
// // <div className="bg-gradient-to-tr from-blue-500 to-indigo-600 text-white w-9 h-9 rounded-xl flex items-center justify-center font-black text-lg">
|
|
244
|
+
// // H
|
|
245
|
+
// // </div>
|
|
246
|
+
// // <div>
|
|
247
|
+
// // <h1 className="text-sm font-black text-white tracking-tight leading-none">MediCare Pro</h1>
|
|
248
|
+
// // <p className="text-[9px] text-slate-500 font-bold uppercase tracking-widest mt-1">Management Hub</p>
|
|
249
|
+
// // </div>
|
|
250
|
+
// // </div>
|
|
251
|
+
|
|
252
|
+
// // <div className="p-4 mx-3 my-4 bg-slate-800/50 rounded-xl border border-slate-800/60 flex items-center space-x-3">
|
|
253
|
+
// // <div className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
|
|
254
|
+
// // <div className="flex-1 min-w-0">
|
|
255
|
+
// // <p className="text-xs font-bold text-white truncate leading-none">{user?.username}</p>
|
|
256
|
+
// // <p className="text-[9px] text-blue-400 font-bold uppercase tracking-wider mt-1">{user?.role}</p>
|
|
257
|
+
// // </div>
|
|
258
|
+
// // </div>
|
|
259
|
+
|
|
260
|
+
// // <nav className="flex-1 px-3 space-y-1">
|
|
261
|
+
// // {[
|
|
262
|
+
// // { id: 'dashboard', label: 'Dashboard Overview', icon: '📊' },
|
|
263
|
+
// // { id: 'patients', label: 'Patients Registry', icon: '👥' },
|
|
264
|
+
// // { id: 'doctors', label: 'Medical Staff', icon: '🩺' },
|
|
265
|
+
// // { id: 'appointments', label: 'Appointments Slot', icon: '📅' },
|
|
266
|
+
// // { id: 'payments', label: 'Financial Billing', icon: '💳' },
|
|
267
|
+
// // { id: 'reports', label: 'General Report', icon: '📋' }
|
|
268
|
+
// // ].map((tab) => (
|
|
269
|
+
// // <button
|
|
270
|
+
// // key={tab.id}
|
|
271
|
+
// // onClick={() => setActiveTab(tab.id)}
|
|
272
|
+
// // className={`w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-xs font-bold tracking-wide transition-all ${
|
|
273
|
+
// // activeTab === tab.id ? 'bg-blue-600 text-white shadow-lg' : 'text-slate-400 hover:bg-slate-800 hover:text-slate-200'
|
|
274
|
+
// // }`}
|
|
275
|
+
// // >
|
|
276
|
+
// // <span className="text-base">{tab.icon}</span>
|
|
277
|
+
// // <span>{tab.label}</span>
|
|
278
|
+
// // </button>
|
|
279
|
+
// // ))}
|
|
280
|
+
// // </nav>
|
|
281
|
+
|
|
282
|
+
// // <div className="p-4 border-t border-slate-800">
|
|
283
|
+
// // <button onClick={handleLogout} className="w-full bg-red-950/40 text-red-400 hover:bg-red-900 hover:text-white px-4 py-2.5 rounded-xl text-xs font-bold flex items-center justify-center space-x-2">
|
|
284
|
+
// // <span>🚪</span>
|
|
285
|
+
// // <span>Logout Session</span>
|
|
286
|
+
// // </button>
|
|
287
|
+
// // </div>
|
|
288
|
+
// // </aside>
|
|
289
|
+
|
|
290
|
+
// // {/* MAIN CONTENT AREA CONTAINER */}
|
|
291
|
+
// // <div className="flex-1 pl-64 flex flex-col min-h-screen">
|
|
292
|
+
// // <header className="bg-white/80 backdrop-blur-md border-b border-slate-100 px-8 py-4 flex justify-between items-center sticky top-0 z-40">
|
|
293
|
+
// // <div>
|
|
294
|
+
// // <h2 className="text-sm font-bold text-slate-400 uppercase tracking-wider text-[10px]">Active Workspace</h2>
|
|
295
|
+
// // <h1 className="text-lg font-black text-slate-800 capitalize tracking-tight mt-0.5">{activeTab} Section</h1>
|
|
296
|
+
// // </div>
|
|
297
|
+
// // <div className="text-xs text-slate-400 font-semibold bg-slate-50 px-3 py-1.5 rounded-xl border border-slate-100">
|
|
298
|
+
// // System Status: <span className="text-emerald-500 font-bold">Online</span>
|
|
299
|
+
// // </div>
|
|
300
|
+
// // </header>
|
|
301
|
+
|
|
302
|
+
// // <main className="flex-1 p-8 max-w-7xl w-full mx-auto">
|
|
303
|
+
|
|
304
|
+
// // {/* TAB 1: DASHBOARD OVERVIEW */}
|
|
305
|
+
// // {activeTab === 'dashboard' && (
|
|
306
|
+
// // <div className="space-y-6">
|
|
307
|
+
// // <div className="bg-gradient-to-r from-slate-900 to-indigo-950 rounded-2xl p-6 text-white shadow-xl flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
|
|
308
|
+
// // <div>
|
|
309
|
+
// // <h2 className="text-xl font-black tracking-tight">System Operational Summary</h2>
|
|
310
|
+
// // <p className="text-slate-400 text-xs mt-1 font-medium">Manage all hospital records dynamically in real-time right here.</p>
|
|
311
|
+
// // </div>
|
|
312
|
+
// // </div>
|
|
313
|
+
|
|
314
|
+
// // <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
315
|
+
// // <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
316
|
+
// // <div>
|
|
317
|
+
// // <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Total Patients</p>
|
|
318
|
+
// // <p className="text-2xl font-black text-slate-800 mt-1">{patients.length}</p>
|
|
319
|
+
// // </div>
|
|
320
|
+
// // <div className="w-12 h-12 bg-blue-50 rounded-xl flex items-center justify-center text-xl">👥</div>
|
|
321
|
+
// // </div>
|
|
322
|
+
// // <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
323
|
+
// // <div>
|
|
324
|
+
// // <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Active Staff Doctors</p>
|
|
325
|
+
// // <p className="text-2xl font-black text-slate-800 mt-1">{doctors.length}</p>
|
|
326
|
+
// // </div>
|
|
327
|
+
// // <div className="w-12 h-12 bg-emerald-50 rounded-xl flex items-center justify-center text-xl">🩺</div>
|
|
328
|
+
// // </div>
|
|
329
|
+
// // <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
330
|
+
// // <div>
|
|
331
|
+
// // <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Total Consultations</p>
|
|
332
|
+
// // <p className="text-2xl font-black text-slate-800 mt-1">{appointments.length}</p>
|
|
333
|
+
// // </div>
|
|
334
|
+
// // <div className="w-12 h-12 bg-amber-50 rounded-xl flex items-center justify-center text-xl">📅</div>
|
|
335
|
+
// // </div>
|
|
336
|
+
// // <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
337
|
+
// // <div>
|
|
338
|
+
// // <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Gross Income Inflow</p>
|
|
339
|
+
// // <p className="text-xl font-black text-slate-800 mt-1">{totalRevenue.toLocaleString()} RWF</p>
|
|
340
|
+
// // </div>
|
|
341
|
+
// // <div className="w-12 h-12 bg-indigo-50 rounded-xl flex items-center justify-center text-xl">💰</div>
|
|
342
|
+
// // </div>
|
|
343
|
+
// // </div>
|
|
344
|
+
|
|
345
|
+
// // <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
346
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm flex flex-col">
|
|
347
|
+
// // <h3 className="text-sm font-bold text-slate-800 mb-4">Recent Appointment Bookings</h3>
|
|
348
|
+
// // <div className="divide-y overflow-y-auto max-h-64 flex-1">
|
|
349
|
+
// // {appointments.slice(-4).reverse().map((a) => (
|
|
350
|
+
// // <div key={a.AppointmentID} className="py-3 flex justify-between items-center px-1 rounded-lg">
|
|
351
|
+
// // <div>
|
|
352
|
+
// // <p className="font-bold text-slate-800 text-xs">{a.PatientName}</p>
|
|
353
|
+
// // <p className="text-[10px] text-slate-400">Assigned Doctor: {a.DoctorName}</p>
|
|
354
|
+
// // </div>
|
|
355
|
+
// // <span className="text-[10px] bg-blue-50 text-blue-600 font-bold px-2.5 py-1 rounded-lg">
|
|
356
|
+
// // {new Date(a.Date).toLocaleDateString()}
|
|
357
|
+
// // </span>
|
|
358
|
+
// // </div>
|
|
359
|
+
// // ))}
|
|
360
|
+
// // {appointments.length === 0 && <div className="text-center py-8 text-slate-400 text-xs">No records found.</div>}
|
|
361
|
+
// // </div>
|
|
362
|
+
// // </div>
|
|
363
|
+
|
|
364
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm flex flex-col">
|
|
365
|
+
// // <h3 className="text-sm font-bold text-slate-800 mb-4">Latest Financial Ledger Inflow</h3>
|
|
366
|
+
// // <div className="divide-y overflow-y-auto max-h-64 flex-1">
|
|
367
|
+
// // {payments.slice(-4).reverse().map((p) => (
|
|
368
|
+
// // <div key={p.PaymentID} className="py-3 flex justify-between items-center px-1 rounded-lg">
|
|
369
|
+
// // <div>
|
|
370
|
+
// // <p className="font-bold text-slate-800 text-xs">{p.PatientName}</p>
|
|
371
|
+
// // <p className="text-[10px] text-slate-400">{new Date(p.Date).toLocaleDateString()}</p>
|
|
372
|
+
// // </div>
|
|
373
|
+
// // <span className="text-xs font-black text-emerald-600">+{p.Amount?.toLocaleString()} RWF</span>
|
|
374
|
+
// // </div>
|
|
375
|
+
// // ))}
|
|
376
|
+
// // {payments.length === 0 && <div className="text-center py-8 text-slate-400 text-xs">No records found.</div>}
|
|
377
|
+
// // </div>
|
|
378
|
+
// // </div>
|
|
379
|
+
// // </div>
|
|
380
|
+
// // </div>
|
|
381
|
+
// // )}
|
|
382
|
+
|
|
383
|
+
// // {/* TAB 2: PATIENTS */}
|
|
384
|
+
// // {activeTab === 'patients' && (
|
|
385
|
+
// // <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
386
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
387
|
+
// // <h2 className="text-sm font-bold text-slate-800 mb-4">{patientForm.PatientID ? 'Update Patient File Record' : 'Register New Patient File'}</h2>
|
|
388
|
+
// // <form onSubmit={handlePatientSubmit} className="space-y-4">
|
|
389
|
+
// // <div>
|
|
390
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Full Name</label>
|
|
391
|
+
// // <input type="text" value={patientForm.Name} onChange={(e) => setPatientForm({ ...patientForm, Name: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Full Name" />
|
|
392
|
+
// // </div>
|
|
393
|
+
// // <div>
|
|
394
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Patient Age</label>
|
|
395
|
+
// // <input type="number" value={patientForm.Age} onChange={(e) => setPatientForm({ ...patientForm, Age: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Age" />
|
|
396
|
+
// // </div>
|
|
397
|
+
// // <div>
|
|
398
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Phone</label>
|
|
399
|
+
// // <input type="text" value={patientForm.Phone} onChange={(e) => setPatientForm({ ...patientForm, Phone: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Phone Connection" />
|
|
400
|
+
// // </div>
|
|
401
|
+
// // <button type="submit" className="w-full bg-blue-600 text-white py-2.5 rounded-xl text-xs font-bold">Save Patient Records</button>
|
|
402
|
+
// // </form>
|
|
403
|
+
// // </div>
|
|
404
|
+
|
|
405
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
406
|
+
// // <table className="w-full text-left text-xs border-collapse">
|
|
407
|
+
// // <thead>
|
|
408
|
+
// // <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
409
|
+
// // <th className="p-3">ID</th>
|
|
410
|
+
// // <th className="p-3">Name</th>
|
|
411
|
+
// // <th className="p-3">Age</th>
|
|
412
|
+
// // <th className="p-3">Phone</th>
|
|
413
|
+
// // <th className="p-3 text-right">Actions</th>
|
|
414
|
+
// // </tr>
|
|
415
|
+
// // </thead>
|
|
416
|
+
// // <tbody className="divide-y">
|
|
417
|
+
// // {patients.map((p) => (
|
|
418
|
+
// // <tr key={p.PatientID} className="hover:bg-slate-50/50">
|
|
419
|
+
// // <td className="p-3 font-mono text-slate-400">{p.PatientID}</td>
|
|
420
|
+
// // <td className="p-3 font-bold text-slate-800">{p.Name}</td>
|
|
421
|
+
// // <td className="p-3">{p.Age} Yrs</td>
|
|
422
|
+
// // <td className="p-3 font-mono">{p.Phone}</td>
|
|
423
|
+
// // <td className="p-3 text-right space-x-1.5">
|
|
424
|
+
// // <button onClick={() => setPatientForm(p)} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
425
|
+
// // <button onClick={() => handlePatientDelete(p.PatientID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
426
|
+
// // </td>
|
|
427
|
+
// // </tr>
|
|
428
|
+
// // ))}
|
|
429
|
+
// // </tbody>
|
|
430
|
+
// // </table>
|
|
431
|
+
// // </div>
|
|
432
|
+
// // </div>
|
|
433
|
+
// // )}
|
|
434
|
+
|
|
435
|
+
// // {/* TAB 3: DOCTORS */}
|
|
436
|
+
// // {activeTab === 'doctors' && (
|
|
437
|
+
// // <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
438
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
439
|
+
// // <h2 className="text-sm font-bold text-slate-800 mb-4">{doctorForm.DoctorID ? 'Update Doctor Profile' : 'Register New Doctor'}</h2>
|
|
440
|
+
// // <form onSubmit={handleDoctorSubmit} className="space-y-4">
|
|
441
|
+
// // <div>
|
|
442
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Doctor Name</label>
|
|
443
|
+
// // <input type="text" value={doctorForm.Name} onChange={(e) => setDoctorForm({ ...doctorForm, Name: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Dr. Name" />
|
|
444
|
+
// // </div>
|
|
445
|
+
// // <div>
|
|
446
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Specialization</label>
|
|
447
|
+
// // <input type="text" value={doctorForm.Specialization} onChange={(e) => setDoctorForm({ ...doctorForm, Specialization: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Specialization" />
|
|
448
|
+
// // </div>
|
|
449
|
+
// // <button type="submit" className="w-full bg-emerald-600 text-white py-2.5 rounded-xl text-xs font-bold">Save Doctor Specs</button>
|
|
450
|
+
// // </form>
|
|
451
|
+
// // </div>
|
|
452
|
+
|
|
453
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
454
|
+
// // <table className="w-full text-left text-xs">
|
|
455
|
+
// // <thead>
|
|
456
|
+
// // <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
457
|
+
// // <th className="p-3">ID</th>
|
|
458
|
+
// // <th className="p-3">Name</th>
|
|
459
|
+
// // <th className="p-3">Specialization</th>
|
|
460
|
+
// // <th className="p-3 text-right">Actions</th>
|
|
461
|
+
// // </tr>
|
|
462
|
+
// // </thead>
|
|
463
|
+
// // <tbody className="divide-y">
|
|
464
|
+
// // {doctors.map((d) => (
|
|
465
|
+
// // <tr key={d.DoctorID} className="hover:bg-slate-50/50">
|
|
466
|
+
// // <td className="p-3 font-mono text-slate-400">{d.DoctorID}</td>
|
|
467
|
+
// // <td className="p-3 font-bold text-slate-800">{d.Name}</td>
|
|
468
|
+
// // <td className="p-3 font-medium text-slate-600">{d.Specialization}</td>
|
|
469
|
+
// // <td className="p-3 text-right space-x-1.5">
|
|
470
|
+
// // <button onClick={() => setDoctorForm(d)} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
471
|
+
// // <button onClick={() => handleDoctorDelete(d.DoctorID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
472
|
+
// // </td>
|
|
473
|
+
// // </tr>
|
|
474
|
+
// // ))}
|
|
475
|
+
// // </tbody>
|
|
476
|
+
// // </table>
|
|
477
|
+
// // </div>
|
|
478
|
+
// // </div>
|
|
479
|
+
// // )}
|
|
480
|
+
|
|
481
|
+
// // {/* TAB 4: APPOINTMENTS */}
|
|
482
|
+
// // {activeTab === 'appointments' && (
|
|
483
|
+
// // <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
484
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
485
|
+
// // <h2 className="text-sm font-bold text-slate-800 mb-4">{appointmentForm.AppointmentID ? 'Modify Booking Slot' : 'Book Appointment Slot'}</h2>
|
|
486
|
+
// // <form onSubmit={handleAppointmentSubmit} className="space-y-4">
|
|
487
|
+
// // <div>
|
|
488
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Patient</label>
|
|
489
|
+
// // <select value={appointmentForm.PatientID} onChange={(e) => setAppointmentForm({ ...appointmentForm, PatientID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
490
|
+
// // <option value="">-- Choose Registered Patient --</option>
|
|
491
|
+
// // {patients.map(p => <option key={p.PatientID} value={p.PatientID}>{p.Name} (ID: {p.PatientID})</option>)}
|
|
492
|
+
// // </select>
|
|
493
|
+
// // </div>
|
|
494
|
+
// // <div>
|
|
495
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Doctor</label>
|
|
496
|
+
// // <select value={appointmentForm.DoctorID} onChange={(e) => setAppointmentForm({ ...appointmentForm, DoctorID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
497
|
+
// // <option value="">-- Choose Medical Officer --</option>
|
|
498
|
+
// // {doctors.map(d => <option key={d.DoctorID} value={d.DoctorID}>{d.Name}</option>)}
|
|
499
|
+
// // </select>
|
|
500
|
+
// // </div>
|
|
501
|
+
// // <div>
|
|
502
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Consultation Date</label>
|
|
503
|
+
// // <input type="date" value={appointmentForm.Date ? appointmentForm.Date.split('T')[0] : ''} onChange={(e) => setAppointmentForm({ ...appointmentForm, Date: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" />
|
|
504
|
+
// // </div>
|
|
505
|
+
// // <button type="submit" className="w-full bg-amber-600 text-white py-2.5 rounded-xl text-xs font-bold">Commit Slot Booking</button>
|
|
506
|
+
// // </form>
|
|
507
|
+
// // </div>
|
|
508
|
+
|
|
509
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
510
|
+
// // <table className="w-full text-left text-xs">
|
|
511
|
+
// // <thead>
|
|
512
|
+
// // <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
513
|
+
// // <th className="p-3">ID</th>
|
|
514
|
+
// // <th className="p-3">Patient</th>
|
|
515
|
+
// // <th className="p-3">Doctor</th>
|
|
516
|
+
// // <th className="p-3">Date</th>
|
|
517
|
+
// // <th className="p-3 text-right">Actions</th>
|
|
518
|
+
// // </tr>
|
|
519
|
+
// // </thead>
|
|
520
|
+
// // <tbody className="divide-y">
|
|
521
|
+
// // {appointments.map((a) => (
|
|
522
|
+
// // <tr key={a.AppointmentID} className="hover:bg-slate-50/50">
|
|
523
|
+
// // <td className="p-3 text-slate-400 font-mono">{a.AppointmentID}</td>
|
|
524
|
+
// // <td className="p-3 font-bold text-slate-800">{a.PatientName}</td>
|
|
525
|
+
// // <td className="p-3 font-medium text-slate-600">{a.DoctorName}</td>
|
|
526
|
+
// // <td className="p-3 font-mono"><span className="bg-blue-50 text-blue-600 px-2 py-0.5 rounded border border-blue-100">{new Date(a.Date).toLocaleDateString()}</span></td>
|
|
527
|
+
// // <td className="p-3 text-right space-x-1.5">
|
|
528
|
+
// // <button onClick={() => setAppointmentForm({ AppointmentID: a.AppointmentID, PatientID: a.PatientID || '', DoctorID: a.DoctorID || '', Date: a.Date })} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
529
|
+
// // <button onClick={() => handleAppointmentDelete(a.AppointmentID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
530
|
+
// // </td>
|
|
531
|
+
// // </tr>
|
|
532
|
+
// // ))}
|
|
533
|
+
// // </tbody>
|
|
534
|
+
// // </table>
|
|
535
|
+
// // </div>
|
|
536
|
+
// // </div>
|
|
537
|
+
// // )}
|
|
538
|
+
|
|
539
|
+
// // {/* TAB 5: PAYMENTS */}
|
|
540
|
+
// // {activeTab === 'payments' && (
|
|
541
|
+
// // <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
542
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
543
|
+
// // <h2 className="text-sm font-bold text-slate-800 mb-4">{paymentForm.PaymentID ? 'Modify Invoice Data' : 'Generate New Patient Invoice'}</h2>
|
|
544
|
+
// // <form onSubmit={handlePaymentSubmit} className="space-y-4">
|
|
545
|
+
// // <div>
|
|
546
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Patient Debtor</label>
|
|
547
|
+
// // <select value={paymentForm.PatientID} onChange={(e) => setPaymentForm({ ...paymentForm, PatientID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
548
|
+
// // <option value="">-- Select Patient --</option>
|
|
549
|
+
// // {patients.map(p => <option key={p.PatientID} value={p.PatientID}>{p.Name}</option>)}
|
|
550
|
+
// // </select>
|
|
551
|
+
// // </div>
|
|
552
|
+
// // <div>
|
|
553
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Amount (RWF)</label>
|
|
554
|
+
// // <input type="number" value={paymentForm.Amount} onChange={(e) => setPaymentForm({ ...paymentForm, Amount: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Invoice Value" />
|
|
555
|
+
// // </div>
|
|
556
|
+
// // <div>
|
|
557
|
+
// // <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Billing Date</label>
|
|
558
|
+
// // <input type="date" value={paymentForm.Date ? paymentForm.Date.split('T')[0] : ''} onChange={(e) => setPaymentForm({ ...paymentForm, Date: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" />
|
|
559
|
+
// // </div>
|
|
560
|
+
// // <button type="submit" className="w-full bg-indigo-600 text-white py-2.5 rounded-xl text-xs font-bold">Commit Statement</button>
|
|
561
|
+
// // </form>
|
|
562
|
+
// // </div>
|
|
563
|
+
|
|
564
|
+
// // <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
565
|
+
// // <table className="w-full text-left text-xs">
|
|
566
|
+
// // <thead>
|
|
567
|
+
// // <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
568
|
+
// // <th className="p-3">ID</th>
|
|
569
|
+
// // <th className="p-3">Patient Name</th>
|
|
570
|
+
// // <th className="p-3">Amount</th>
|
|
571
|
+
// // <th className="p-3">Date</th>
|
|
572
|
+
// // <th className="p-3 text-right">Actions</th>
|
|
573
|
+
// // </tr>
|
|
574
|
+
// // </thead>
|
|
575
|
+
// // <tbody className="divide-y">
|
|
576
|
+
// // {payments.map((p) => (
|
|
577
|
+
// // <tr key={p.PaymentID} className="hover:bg-slate-50/50">
|
|
578
|
+
// // <td className="p-3 text-slate-400 font-mono">{p.PaymentID}</td>
|
|
579
|
+
// // <td className="p-3 font-bold text-slate-800">{p.PatientName}</td>
|
|
580
|
+
// // <td className="p-3 font-black text-emerald-600">{Number(p.Amount).toLocaleString()} RWF</td>
|
|
581
|
+
// // <td className="p-3 font-mono text-slate-500">{new Date(p.Date).toLocaleDateString()}</td>
|
|
582
|
+
// // <td className="p-3 text-right space-x-1.5">
|
|
583
|
+
// // <button onClick={() => setPaymentForm({ PaymentID: p.PaymentID, PatientID: p.PatientID || '', Amount: p.Amount, Date: p.Date })} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
584
|
+
// // <button onClick={() => handlePaymentDelete(p.PaymentID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
585
|
+
// // </td>
|
|
586
|
+
// // </tr>
|
|
587
|
+
// // ))}
|
|
588
|
+
// // </tbody>
|
|
589
|
+
// // </table>
|
|
590
|
+
// // </div>
|
|
591
|
+
// // </div>
|
|
592
|
+
// // )}
|
|
593
|
+
|
|
594
|
+
// // {/* TAB 6: REPORTS */}
|
|
595
|
+
// // {activeTab === 'reports' && (
|
|
596
|
+
// // <div className="bg-white p-8 rounded-2xl border shadow-sm space-y-6">
|
|
597
|
+
// // <div className="border-b pb-4 text-center">
|
|
598
|
+
// // <h1 className="text-xl font-black text-slate-800 uppercase tracking-wide">MediCare Pro Comprehensive Summary Report</h1>
|
|
599
|
+
// // <p className="text-slate-400 text-xs mt-1">Generated dynamically on {new Date().toLocaleDateString()}</p>
|
|
600
|
+
// // </div>
|
|
601
|
+
// // <div className="grid grid-cols-1 md:grid-cols-3 gap-6 text-center">
|
|
602
|
+
// // <div className="p-4 bg-slate-50 rounded-xl border">
|
|
603
|
+
// // <h3 className="text-xs font-bold uppercase text-slate-400">Total Patients Dossiers</h3>
|
|
604
|
+
// // <p className="text-3xl font-black text-blue-600 mt-2">{patients.length}</p>
|
|
605
|
+
// // </div>
|
|
606
|
+
// // <div className="p-4 bg-slate-50 rounded-xl border">
|
|
607
|
+
// // <h3 className="text-xs font-bold uppercase text-slate-400">Consultations Services</h3>
|
|
608
|
+
// // <p className="text-3xl font-black text-amber-600 mt-2">{appointments.length}</p>
|
|
609
|
+
// // </div>
|
|
610
|
+
// // <div className="p-4 bg-slate-50 rounded-xl border">
|
|
611
|
+
// // <h3 className="text-xs font-bold uppercase text-slate-400">Cumulative Income</h3>
|
|
612
|
+
// // <p className="text-3xl font-black text-emerald-600 mt-2">{totalRevenue.toLocaleString()} RWF</p>
|
|
613
|
+
// // </div>
|
|
614
|
+
// // </div>
|
|
615
|
+
// // </div>
|
|
616
|
+
// // )}
|
|
617
|
+
// // </main>
|
|
618
|
+
// // </div>
|
|
619
|
+
// // </div>
|
|
620
|
+
// // );
|
|
621
|
+
// // }
|
|
622
|
+
|
|
623
|
+
// // export default App;
|
|
624
|
+
|
|
625
|
+
// import { useState, useEffect, useCallback } from 'react';
|
|
626
|
+
// import axios from 'axios';
|
|
627
|
+
|
|
628
|
+
// function App() {
|
|
629
|
+
// const [activeTab, setActiveTab] = useState('dashboard');
|
|
630
|
+
// const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
631
|
+
// const [isRegisterMode, setIsRegisterMode] = useState(false); // Ifasha guhinduranya login na register
|
|
632
|
+
// const [loginData, setLoginData] = useState({ username: '', password: '' });
|
|
633
|
+
// const [user, setUser] = useState(null);
|
|
634
|
+
|
|
635
|
+
// // Data States
|
|
636
|
+
// const [patients, setPatients] = useState([]);
|
|
637
|
+
// const [doctors, setDoctors] = useState([]);
|
|
638
|
+
// const [appointments, setAppointments] = useState([]);
|
|
639
|
+
// const [payments, setPayments] = useState([]);
|
|
640
|
+
|
|
641
|
+
// // Form States
|
|
642
|
+
// const [patientForm, setPatientForm] = useState({ PatientID: null, Name: '', Age: '', Phone: '' });
|
|
643
|
+
// const [doctorForm, setDoctorForm] = useState({ DoctorID: null, Name: '', Specialization: '' });
|
|
644
|
+
// const [appointmentForm, setAppointmentForm] = useState({ AppointmentID: null, PatientID: '', DoctorID: '', Date: '' });
|
|
645
|
+
// const [paymentForm, setPaymentForm] = useState({ PaymentID: null, PatientID: '', Amount: '', Date: '' });
|
|
646
|
+
|
|
647
|
+
// // Authentication: Login
|
|
648
|
+
// const handleLogin = async (e) => {
|
|
649
|
+
// e.preventDefault();
|
|
650
|
+
// try {
|
|
651
|
+
// const response = await axios.post('http://localhost:5000/api/login', loginData, {
|
|
652
|
+
// headers: { 'Content-Type': 'application/json' }
|
|
653
|
+
// });
|
|
654
|
+
// if (response.data.success) {
|
|
655
|
+
// setIsAuthenticated(true);
|
|
656
|
+
// setUser(response.data.user);
|
|
657
|
+
// setLoginData({ username: '', password: '' });
|
|
658
|
+
// } else {
|
|
659
|
+
// alert(response.data.message);
|
|
660
|
+
// }
|
|
661
|
+
// } catch (error) {
|
|
662
|
+
// if (error.response && error.response.data && error.response.data.message) {
|
|
663
|
+
// alert(error.response.data.message);
|
|
664
|
+
// } else {
|
|
665
|
+
// alert('Login failed. Please check backend connection.');
|
|
666
|
+
// }
|
|
667
|
+
// }
|
|
668
|
+
// };
|
|
669
|
+
|
|
670
|
+
// // Authentication: Register
|
|
671
|
+
// const handleRegister = async (e) => {
|
|
672
|
+
// e.preventDefault();
|
|
673
|
+
// if (!loginData.username || !loginData.password) {
|
|
674
|
+
// return alert('Please fill in all fields');
|
|
675
|
+
// }
|
|
676
|
+
// try {
|
|
677
|
+
// const response = await axios.post('http://localhost:5000/api/register', loginData, {
|
|
678
|
+
// headers: { 'Content-Type': 'application/json' }
|
|
679
|
+
// });
|
|
680
|
+
// if (response.data.success) {
|
|
681
|
+
// alert(response.data.message);
|
|
682
|
+
// setIsRegisterMode(false); // Subira kuri login screen
|
|
683
|
+
// }
|
|
684
|
+
// } catch (error) {
|
|
685
|
+
// if (error.response && error.response.data && error.response.data.message) {
|
|
686
|
+
// alert(error.response.data.message);
|
|
687
|
+
// } else {
|
|
688
|
+
// alert('Registration failed. Please check backend connection.');
|
|
689
|
+
// }
|
|
690
|
+
// }
|
|
691
|
+
// };
|
|
692
|
+
|
|
693
|
+
// const handleLogout = () => {
|
|
694
|
+
// setIsAuthenticated(false);
|
|
695
|
+
// setUser(null);
|
|
696
|
+
// setActiveTab('dashboard');
|
|
697
|
+
// };
|
|
698
|
+
|
|
699
|
+
// // Fetch Data Functions
|
|
700
|
+
// const fetchPatients = useCallback(async () => {
|
|
701
|
+
// try {
|
|
702
|
+
// const response = await axios.get('http://localhost:5000/api/patients');
|
|
703
|
+
// setPatients(response.data);
|
|
704
|
+
// } catch (err) { console.error(err); }
|
|
705
|
+
// }, []);
|
|
706
|
+
|
|
707
|
+
// const fetchDoctors = useCallback(async () => {
|
|
708
|
+
// try {
|
|
709
|
+
// const response = await axios.get('http://localhost:5000/api/doctors');
|
|
710
|
+
// setDoctors(response.data);
|
|
711
|
+
// } catch (err) { console.error(err); }
|
|
712
|
+
// }, []);
|
|
713
|
+
|
|
714
|
+
// const fetchAppointments = useCallback(async () => {
|
|
715
|
+
// try {
|
|
716
|
+
// const response = await axios.get('http://localhost:5000/api/appointments');
|
|
717
|
+
// setAppointments(response.data);
|
|
718
|
+
// } catch (err) { console.error(err); }
|
|
719
|
+
// }, []);
|
|
720
|
+
|
|
721
|
+
// const fetchPayments = useCallback(async () => {
|
|
722
|
+
// try {
|
|
723
|
+
// const response = await axios.get('http://localhost:5000/api/payments');
|
|
724
|
+
// setPayments(response.data);
|
|
725
|
+
// } catch (err) { console.error(err); }
|
|
726
|
+
// }, []);
|
|
727
|
+
|
|
728
|
+
// const fetchAllData = useCallback(() => {
|
|
729
|
+
// fetchPatients();
|
|
730
|
+
// fetchDoctors();
|
|
731
|
+
// fetchAppointments();
|
|
732
|
+
// fetchPayments();
|
|
733
|
+
// }, [fetchPatients, fetchDoctors, fetchAppointments, fetchPayments]);
|
|
734
|
+
|
|
735
|
+
// useEffect(() => {
|
|
736
|
+
// if (isAuthenticated) {
|
|
737
|
+
// fetchAllData();
|
|
738
|
+
// }
|
|
739
|
+
// }, [isAuthenticated, fetchAllData]);
|
|
740
|
+
|
|
741
|
+
// // Total Revenue Calculation
|
|
742
|
+
// const totalRevenue = payments.reduce((sum, p) => sum + Number(p.Amount || 0), 0);
|
|
743
|
+
|
|
744
|
+
// // Patient Actions
|
|
745
|
+
// const handlePatientSubmit = async (e) => {
|
|
746
|
+
// e.preventDefault();
|
|
747
|
+
// if (!patientForm.Name || !patientForm.Age || !patientForm.Phone) return alert('Fill all fields');
|
|
748
|
+
// try {
|
|
749
|
+
// if (patientForm.PatientID) {
|
|
750
|
+
// await axios.put(`http://localhost:5000/api/patients/${patientForm.PatientID}`, patientForm);
|
|
751
|
+
// } else {
|
|
752
|
+
// await axios.post('http://localhost:5000/api/patients', patientForm);
|
|
753
|
+
// }
|
|
754
|
+
// setPatientForm({ PatientID: null, Name: '', Age: '', Phone: '' });
|
|
755
|
+
// fetchAllData();
|
|
756
|
+
// } catch (err) { alert('Operation failed'); }
|
|
757
|
+
// };
|
|
758
|
+
|
|
759
|
+
// const handlePatientDelete = async (id) => {
|
|
760
|
+
// if (window.confirm('Delete this patient?')) {
|
|
761
|
+
// try {
|
|
762
|
+
// await axios.delete(`http://localhost:5000/api/patients/${id}`);
|
|
763
|
+
// fetchAllData();
|
|
764
|
+
// } catch (err) { alert('Could not delete patient.'); }
|
|
765
|
+
// }
|
|
766
|
+
// };
|
|
767
|
+
|
|
768
|
+
// // Doctor Actions
|
|
769
|
+
// const handleDoctorSubmit = async (e) => {
|
|
770
|
+
// e.preventDefault();
|
|
771
|
+
// if (!doctorForm.Name || !doctorForm.Specialization) return alert('Fill all fields');
|
|
772
|
+
// try {
|
|
773
|
+
// if (doctorForm.DoctorID) {
|
|
774
|
+
// await axios.put(`http://localhost:5000/api/doctors/${doctorForm.DoctorID}`, doctorForm);
|
|
775
|
+
// } else {
|
|
776
|
+
// await axios.post('http://localhost:5000/api/doctors', doctorForm);
|
|
777
|
+
// }
|
|
778
|
+
// setDoctorForm({ DoctorID: null, Name: '', Specialization: '' });
|
|
779
|
+
// fetchAllData();
|
|
780
|
+
// } catch (err) { alert('Operation failed'); }
|
|
781
|
+
// };
|
|
782
|
+
|
|
783
|
+
// const handleDoctorDelete = async (id) => {
|
|
784
|
+
// if (window.confirm('Delete this doctor?')) {
|
|
785
|
+
// try {
|
|
786
|
+
// await axios.delete(`http://localhost:5000/api/doctors/${id}`);
|
|
787
|
+
// fetchAllData();
|
|
788
|
+
// } catch (err) { alert('Could not delete doctor.'); }
|
|
789
|
+
// }
|
|
790
|
+
// };
|
|
791
|
+
|
|
792
|
+
// // Appointment Actions
|
|
793
|
+
// const handleAppointmentSubmit = async (e) => {
|
|
794
|
+
// e.preventDefault();
|
|
795
|
+
// if (!appointmentForm.PatientID || !appointmentForm.DoctorID || !appointmentForm.Date) return alert('Fill all fields');
|
|
796
|
+
// try {
|
|
797
|
+
// if (appointmentForm.AppointmentID) {
|
|
798
|
+
// await axios.put(`http://localhost:5000/api/appointments/${appointmentForm.AppointmentID}`, appointmentForm);
|
|
799
|
+
// } else {
|
|
800
|
+
// await axios.post('http://localhost:5000/api/appointments', appointmentForm);
|
|
801
|
+
// }
|
|
802
|
+
// setAppointmentForm({ AppointmentID: null, PatientID: '', DoctorID: '', Date: '' });
|
|
803
|
+
// fetchAppointments();
|
|
804
|
+
// } catch (err) { alert('Operation failed'); }
|
|
805
|
+
// };
|
|
806
|
+
|
|
807
|
+
// const handleAppointmentDelete = async (id) => {
|
|
808
|
+
// if (window.confirm('Delete this appointment?')) {
|
|
809
|
+
// try {
|
|
810
|
+
// await axios.delete(`http://localhost:5000/api/appointments/${id}`);
|
|
811
|
+
// fetchAppointments();
|
|
812
|
+
// } catch (err) { alert('Operation failed'); }
|
|
813
|
+
// }
|
|
814
|
+
// };
|
|
815
|
+
|
|
816
|
+
// // Payment Actions
|
|
817
|
+
// const handlePaymentSubmit = async (e) => {
|
|
818
|
+
// e.preventDefault();
|
|
819
|
+
// if (!paymentForm.PatientID || !paymentForm.Amount || !paymentForm.Date) return alert('Fill all fields');
|
|
820
|
+
// try {
|
|
821
|
+
// if (paymentForm.PaymentID) {
|
|
822
|
+
// await axios.put(`http://localhost:5000/api/payments/${paymentForm.PaymentID}`, paymentForm);
|
|
823
|
+
// } else {
|
|
824
|
+
// await axios.post('http://localhost:5000/api/payments', paymentForm);
|
|
825
|
+
// }
|
|
826
|
+
// setPaymentForm({ PaymentID: null, PatientID: '', Amount: '', Date: '' });
|
|
827
|
+
// fetchPayments();
|
|
828
|
+
// } catch (err) { alert('Operation failed'); }
|
|
829
|
+
// };
|
|
830
|
+
|
|
831
|
+
// const handlePaymentDelete = async (id) => {
|
|
832
|
+
// if (window.confirm('Delete this payment record?')) {
|
|
833
|
+
// try {
|
|
834
|
+
// await axios.delete(`http://localhost:5000/api/payments/${id}`);
|
|
835
|
+
// fetchPayments();
|
|
836
|
+
// } catch (err) { alert('Operation failed'); }
|
|
837
|
+
// }
|
|
838
|
+
// };
|
|
839
|
+
|
|
840
|
+
// // UI rendering ya Login / Register niba adahuye
|
|
841
|
+
// if (!isAuthenticated) {
|
|
842
|
+
// return (
|
|
843
|
+
// <div className="min-h-screen bg-gradient-to-tr from-slate-900 via-indigo-950 to-slate-900 flex items-center justify-center p-4">
|
|
844
|
+
// <div className="bg-white/95 backdrop-blur-md p-8 rounded-2xl shadow-2xl w-full max-w-md border border-white/20">
|
|
845
|
+
// <div className="text-center mb-8">
|
|
846
|
+
// <div className="bg-blue-600 text-white w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4 text-3xl font-black shadow-lg shadow-blue-500/30">
|
|
847
|
+
// H
|
|
848
|
+
// </div>
|
|
849
|
+
// <h1 className="text-2xl font-black tracking-tight text-slate-800">Hospital Management</h1>
|
|
850
|
+
// <p className="text-slate-500 text-sm mt-1">
|
|
851
|
+
// {isRegisterMode ? 'Create a new administrative account' : 'Sign in to access your administrative dashboard'}
|
|
852
|
+
// </p>
|
|
853
|
+
// </div>
|
|
854
|
+
|
|
855
|
+
// <form onSubmit={isRegisterMode ? handleRegister : handleLogin} className="space-y-5">
|
|
856
|
+
// <div>
|
|
857
|
+
// <label className="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-2">Username</label>
|
|
858
|
+
// <input
|
|
859
|
+
// type="text"
|
|
860
|
+
// value={loginData.username}
|
|
861
|
+
// onChange={(e) => setLoginData({ ...loginData, username: e.target.value })}
|
|
862
|
+
// className="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all text-slate-800"
|
|
863
|
+
// placeholder="Enter username"
|
|
864
|
+
// />
|
|
865
|
+
// </div>
|
|
866
|
+
// <div>
|
|
867
|
+
// <label className="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-2">Password</label>
|
|
868
|
+
// <input
|
|
869
|
+
// type="password"
|
|
870
|
+
// value={loginData.password}
|
|
871
|
+
// onChange={(e) => setLoginData({ ...loginData, password: e.target.value })}
|
|
872
|
+
// className="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all text-slate-800"
|
|
873
|
+
// placeholder="••••••••"
|
|
874
|
+
// />
|
|
875
|
+
// </div>
|
|
876
|
+
// <button type="submit" className="w-full bg-gradient-to-r from-blue-600 to-indigo-600 text-white py-3 rounded-xl font-bold shadow-lg shadow-blue-500/20">
|
|
877
|
+
// {isRegisterMode ? 'Register Account' : 'Sign In'}
|
|
878
|
+
// </button>
|
|
879
|
+
// </form>
|
|
880
|
+
|
|
881
|
+
// <div className="mt-4 text-center">
|
|
882
|
+
// <button
|
|
883
|
+
// onClick={() => setIsRegisterMode(!isRegisterMode)}
|
|
884
|
+
// className="text-xs text-blue-600 font-bold hover:underline"
|
|
885
|
+
// >
|
|
886
|
+
// {isRegisterMode ? 'Already have an account? Sign In' : "Don't have an account? Register here"}
|
|
887
|
+
// </button>
|
|
888
|
+
// </div>
|
|
889
|
+
|
|
890
|
+
// {!isRegisterMode && (
|
|
891
|
+
// <div className="mt-6 text-center bg-slate-50 py-2.5 rounded-xl border border-slate-100">
|
|
892
|
+
// <p className="text-xs text-slate-500 font-medium">Demo Access: <span className="font-mono font-bold text-blue-600 bg-blue-50 px-1.5 py-0.5 rounded border border-blue-100">admin / admin123</span></p>
|
|
893
|
+
// </div>
|
|
894
|
+
// )}
|
|
895
|
+
// </div>
|
|
896
|
+
// </div>
|
|
897
|
+
// );
|
|
898
|
+
// }
|
|
899
|
+
|
|
900
|
+
// return (
|
|
901
|
+
// <div className="min-h-screen bg-slate-50/50 flex text-slate-800">
|
|
902
|
+
|
|
903
|
+
// {/* SIDEBAR NAVIGATION */}
|
|
904
|
+
// <aside className="w-64 bg-slate-900 text-slate-300 flex flex-col fixed inset-y-0 left-0 z-50 border-r border-slate-800 shadow-xl">
|
|
905
|
+
// <div className="p-5 border-b border-slate-800 flex items-center space-x-3">
|
|
906
|
+
// <div className="bg-gradient-to-tr from-blue-500 to-indigo-600 text-white w-9 h-9 rounded-xl flex items-center justify-center font-black text-lg">
|
|
907
|
+
// H
|
|
908
|
+
// </div>
|
|
909
|
+
// <div>
|
|
910
|
+
// <h1 className="text-sm font-black text-white tracking-tight leading-none">MediCare Pro</h1>
|
|
911
|
+
// <p className="text-[9px] text-slate-500 font-bold uppercase tracking-widest mt-1">Management Hub</p>
|
|
912
|
+
// </div>
|
|
913
|
+
// </div>
|
|
914
|
+
|
|
915
|
+
// <div className="p-4 mx-3 my-4 bg-slate-800/50 rounded-xl border border-slate-800/60 flex items-center space-x-3">
|
|
916
|
+
// <div className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
|
|
917
|
+
// <div className="flex-1 min-w-0">
|
|
918
|
+
// <p className="text-xs font-bold text-white truncate leading-none">{user?.username || 'System User'}</p>
|
|
919
|
+
// <p className="text-[9px] text-blue-400 font-bold uppercase tracking-wider mt-1">{user?.role || 'Administrator'}</p>
|
|
920
|
+
// </div>
|
|
921
|
+
// </div>
|
|
922
|
+
|
|
923
|
+
// <nav className="flex-1 px-3 space-y-1">
|
|
924
|
+
// {[
|
|
925
|
+
// { id: 'dashboard', label: 'Dashboard Overview', icon: '📊' },
|
|
926
|
+
// { id: 'patients', label: 'Patients Registry', icon: '👥' },
|
|
927
|
+
// { id: 'doctors', label: 'Medical Staff', icon: '🩺' },
|
|
928
|
+
// { id: 'appointments', label: 'Appointments Slot', icon: '📅' },
|
|
929
|
+
// { id: 'payments', label: 'Financial Billing', icon: '💳' },
|
|
930
|
+
// ].map((tab) => (
|
|
931
|
+
// <button
|
|
932
|
+
// key={tab.id}
|
|
933
|
+
// onClick={() => setActiveTab(tab.id)}
|
|
934
|
+
// className={`w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-xs font-bold tracking-wide transition-all ${
|
|
935
|
+
// activeTab === tab.id ? 'bg-blue-600 text-white shadow-lg' : 'text-slate-400 hover:bg-slate-800 hover:text-slate-200'
|
|
936
|
+
// }`}
|
|
937
|
+
// >
|
|
938
|
+
// <span className="text-base">{tab.icon}</span>
|
|
939
|
+
// <span>{tab.label}</span>
|
|
940
|
+
// </button>
|
|
941
|
+
// ))}
|
|
942
|
+
// </nav>
|
|
943
|
+
|
|
944
|
+
// <div className="p-4 border-t border-slate-800">
|
|
945
|
+
// <button onClick={handleLogout} className="w-full bg-red-950/40 text-red-400 hover:bg-red-900 hover:text-white px-4 py-2.5 rounded-xl text-xs font-bold flex items-center justify-center space-x-2">
|
|
946
|
+
// <span>🚪</span>
|
|
947
|
+
// <span>Logout Session</span>
|
|
948
|
+
// </button>
|
|
949
|
+
// </div>
|
|
950
|
+
// </aside>
|
|
951
|
+
|
|
952
|
+
// {/* MAIN CONTENT AREA CONTAINER */}
|
|
953
|
+
// <div className="flex-1 pl-64 flex flex-col min-h-screen">
|
|
954
|
+
// <header className="bg-white/80 backdrop-blur-md border-b border-slate-100 px-8 py-4 flex justify-between items-center sticky top-0 z-40">
|
|
955
|
+
// <div>
|
|
956
|
+
// <h2 className="text-sm font-bold text-slate-400 uppercase tracking-wider text-[10px]">Active Workspace</h2>
|
|
957
|
+
// <h1 className="text-lg font-black text-slate-800 capitalize tracking-tight mt-0.5">{activeTab} Section</h1>
|
|
958
|
+
// </div>
|
|
959
|
+
// <div className="text-xs text-slate-400 font-semibold bg-slate-50 px-3 py-1.5 rounded-xl border border-slate-100">
|
|
960
|
+
// System Status: <span className="text-emerald-500 font-bold">Online</span>
|
|
961
|
+
// </div>
|
|
962
|
+
// </header>
|
|
963
|
+
|
|
964
|
+
// <main className="flex-1 p-8 max-w-7xl w-full mx-auto">
|
|
965
|
+
|
|
966
|
+
// {/* TAB 1: DASHBOARD OVERVIEW */}
|
|
967
|
+
// {activeTab === 'dashboard' && (
|
|
968
|
+
// <div className="space-y-6">
|
|
969
|
+
// <div className="bg-gradient-to-r from-slate-900 to-indigo-950 rounded-2xl p-6 text-white shadow-xl flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
|
|
970
|
+
// <div>
|
|
971
|
+
// <h2 className="text-xl font-black tracking-tight">System Operational Summary</h2>
|
|
972
|
+
// <p className="text-slate-400 text-xs mt-1 font-medium">Manage all hospital records dynamically in real-time right here.</p>
|
|
973
|
+
// </div>
|
|
974
|
+
// </div>
|
|
975
|
+
|
|
976
|
+
// <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
977
|
+
// <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
978
|
+
// <div>
|
|
979
|
+
// <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Total Patients</p>
|
|
980
|
+
// <p className="text-2xl font-black text-slate-800 mt-1">{patients.length}</p>
|
|
981
|
+
// </div>
|
|
982
|
+
// <div className="w-12 h-12 bg-blue-50 rounded-xl flex items-center justify-center text-xl">👥</div>
|
|
983
|
+
// </div>
|
|
984
|
+
// <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
985
|
+
// <div>
|
|
986
|
+
// <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Active Staff Doctors</p>
|
|
987
|
+
// <p className="text-2xl font-black text-slate-800 mt-1">{doctors.length}</p>
|
|
988
|
+
// </div>
|
|
989
|
+
// <div className="w-12 h-12 bg-emerald-50 rounded-xl flex items-center justify-center text-xl">🩺</div>
|
|
990
|
+
// </div>
|
|
991
|
+
// <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
992
|
+
// <div>
|
|
993
|
+
// <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Total Consultations</p>
|
|
994
|
+
// <p className="text-2xl font-black text-slate-800 mt-1">{appointments.length}</p>
|
|
995
|
+
// </div>
|
|
996
|
+
// <div className="w-12 h-12 bg-amber-50 rounded-xl flex items-center justify-center text-xl">📅</div>
|
|
997
|
+
// </div>
|
|
998
|
+
// <div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
999
|
+
// <div>
|
|
1000
|
+
// <p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Gross Income Inflow</p>
|
|
1001
|
+
// <p className="text-xl font-black text-slate-800 mt-1">{totalRevenue.toLocaleString()} RWF</p>
|
|
1002
|
+
// </div>
|
|
1003
|
+
// <div className="w-12 h-12 bg-indigo-50 rounded-xl flex items-center justify-center text-xl">💰</div>
|
|
1004
|
+
// </div>
|
|
1005
|
+
// </div>
|
|
1006
|
+
|
|
1007
|
+
// <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
1008
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm flex flex-col">
|
|
1009
|
+
// <h3 className="text-sm font-bold text-slate-800 mb-4">Recent Appointment Bookings</h3>
|
|
1010
|
+
// <div className="divide-y overflow-y-auto max-h-64 flex-1">
|
|
1011
|
+
// {appointments.slice(-4).reverse().map((a) => (
|
|
1012
|
+
// <div key={a.AppointmentID} className="py-3 flex justify-between items-center px-1 rounded-lg">
|
|
1013
|
+
// <div>
|
|
1014
|
+
// <p className="font-bold text-slate-800 text-xs">{a.PatientName}</p>
|
|
1015
|
+
// <p className="text-[10px] text-slate-400">Assigned Doctor: {a.DoctorName}</p>
|
|
1016
|
+
// </div>
|
|
1017
|
+
// <span className="text-[10px] bg-blue-50 text-blue-600 font-bold px-2.5 py-1 rounded-lg">
|
|
1018
|
+
// {new Date(a.Date).toLocaleDateString()}
|
|
1019
|
+
// </span>
|
|
1020
|
+
// </div>
|
|
1021
|
+
// ))}
|
|
1022
|
+
// {appointments.length === 0 && <div className="text-center py-8 text-slate-400 text-xs">No records found.</div>}
|
|
1023
|
+
// </div>
|
|
1024
|
+
// </div>
|
|
1025
|
+
|
|
1026
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm flex flex-col">
|
|
1027
|
+
// <h3 className="text-sm font-bold text-slate-800 mb-4">Latest Financial Ledger Inflow</h3>
|
|
1028
|
+
// <div className="divide-y overflow-y-auto max-h-64 flex-1">
|
|
1029
|
+
// {payments.slice(-4).reverse().map((p) => (
|
|
1030
|
+
// <div key={p.PaymentID} className="py-3 flex justify-between items-center px-1 rounded-lg">
|
|
1031
|
+
// <div>
|
|
1032
|
+
// <p className="font-bold text-slate-800 text-xs">{p.PatientName}</p>
|
|
1033
|
+
// <p className="text-[10px] text-slate-400">{new Date(p.Date).toLocaleDateString()}</p>
|
|
1034
|
+
// </div>
|
|
1035
|
+
// <span className="text-xs font-black text-emerald-600">+{p.Amount?.toLocaleString()} RWF</span>
|
|
1036
|
+
// </div>
|
|
1037
|
+
// ))}
|
|
1038
|
+
// {payments.length === 0 && <div className="text-center py-8 text-slate-400 text-xs">No records found.</div>}
|
|
1039
|
+
// </div>
|
|
1040
|
+
// </div>
|
|
1041
|
+
// </div>
|
|
1042
|
+
// </div>
|
|
1043
|
+
// )}
|
|
1044
|
+
|
|
1045
|
+
// {/* TAB 2: PATIENTS */}
|
|
1046
|
+
// {activeTab === 'patients' && (
|
|
1047
|
+
// <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1048
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1049
|
+
// <h2 className="text-sm font-bold text-slate-800 mb-4">{patientForm.PatientID ? 'Update Patient File Record' : 'Register New Patient File'}</h2>
|
|
1050
|
+
// <form onSubmit={handlePatientSubmit} className="space-y-4">
|
|
1051
|
+
// <div>
|
|
1052
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Full Name</label>
|
|
1053
|
+
// <input type="text" value={patientForm.Name} onChange={(e) => setPatientForm({ ...patientForm, Name: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Full Name" />
|
|
1054
|
+
// </div>
|
|
1055
|
+
// <div>
|
|
1056
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Patient Age</label>
|
|
1057
|
+
// <input type="number" value={patientForm.Age} onChange={(e) => setPatientForm({ ...patientForm, Age: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Age" />
|
|
1058
|
+
// </div>
|
|
1059
|
+
// <div>
|
|
1060
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Phone</label>
|
|
1061
|
+
// <input type="text" value={patientForm.Phone} onChange={(e) => setPatientForm({ ...patientForm, Phone: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Phone Connection" />
|
|
1062
|
+
// </div>
|
|
1063
|
+
// <button type="submit" className="w-full bg-blue-600 text-white py-2.5 rounded-xl text-xs font-bold">Save Patient Records</button>
|
|
1064
|
+
// </form>
|
|
1065
|
+
// </div>
|
|
1066
|
+
|
|
1067
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1068
|
+
// <table className="w-full text-left text-xs border-collapse">
|
|
1069
|
+
// <thead>
|
|
1070
|
+
// <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1071
|
+
// <th className="p-3">ID</th>
|
|
1072
|
+
// <th className="p-3">Name</th>
|
|
1073
|
+
// <th className="p-3">Age</th>
|
|
1074
|
+
// <th className="p-3">Phone</th>
|
|
1075
|
+
// <th className="p-3 text-right">Actions</th>
|
|
1076
|
+
// </tr>
|
|
1077
|
+
// </thead>
|
|
1078
|
+
// <tbody className="divide-y">
|
|
1079
|
+
// {patients.map((p) => (
|
|
1080
|
+
// <tr key={p.PatientID} className="hover:bg-slate-50/50">
|
|
1081
|
+
// <td className="p-3 font-mono text-slate-400">{p.PatientID}</td>
|
|
1082
|
+
// <td className="p-3 font-bold text-slate-800">{p.Name}</td>
|
|
1083
|
+
// <td className="p-3">{p.Age} Yrs</td>
|
|
1084
|
+
// <td className="p-3 font-mono">{p.Phone}</td>
|
|
1085
|
+
// <td className="p-3 text-right space-x-1.5">
|
|
1086
|
+
// <button onClick={() => setPatientForm(p)} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1087
|
+
// <button onClick={() => handlePatientDelete(p.PatientID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1088
|
+
// </td>
|
|
1089
|
+
// </tr>
|
|
1090
|
+
// ))}
|
|
1091
|
+
// </tbody>
|
|
1092
|
+
// </table>
|
|
1093
|
+
// </div>
|
|
1094
|
+
// </div>
|
|
1095
|
+
// )}
|
|
1096
|
+
|
|
1097
|
+
// {/* TAB 3: DOCTORS */}
|
|
1098
|
+
// {activeTab === 'doctors' && (
|
|
1099
|
+
// <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1100
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1101
|
+
// <h2 className="text-sm font-bold text-slate-800 mb-4">{doctorForm.DoctorID ? 'Update Doctor Profile' : 'Register New Doctor'}</h2>
|
|
1102
|
+
// <form onSubmit={handleDoctorSubmit} className="space-y-4">
|
|
1103
|
+
// <div>
|
|
1104
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Doctor Name</label>
|
|
1105
|
+
// <input type="text" value={doctorForm.Name} onChange={(e) => setDoctorForm({ ...doctorForm, Name: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Dr. Name" />
|
|
1106
|
+
// </div>
|
|
1107
|
+
// <div>
|
|
1108
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Specialization</label>
|
|
1109
|
+
// <input type="text" value={doctorForm.Specialization} onChange={(e) => setDoctorForm({ ...doctorForm, Specialization: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Specialization" />
|
|
1110
|
+
// </div>
|
|
1111
|
+
// <button type="submit" className="w-full bg-emerald-600 text-white py-2.5 rounded-xl text-xs font-bold">Save Doctor Specs</button>
|
|
1112
|
+
// </form>
|
|
1113
|
+
// </div>
|
|
1114
|
+
|
|
1115
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1116
|
+
// <table className="w-full text-left text-xs">
|
|
1117
|
+
// <thead>
|
|
1118
|
+
// <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1119
|
+
// <th className="p-3">ID</th>
|
|
1120
|
+
// <th className="p-3">Name</th>
|
|
1121
|
+
// <th className="p-3">Specialization</th>
|
|
1122
|
+
// <th className="p-3 text-right">Actions</th>
|
|
1123
|
+
// </tr>
|
|
1124
|
+
// </thead>
|
|
1125
|
+
// <tbody className="divide-y">
|
|
1126
|
+
// {doctors.map((d) => (
|
|
1127
|
+
// <tr key={d.DoctorID} className="hover:bg-slate-50/50">
|
|
1128
|
+
// <td className="p-3 font-mono text-slate-400">{d.DoctorID}</td>
|
|
1129
|
+
// <td className="p-3 font-bold text-slate-800">{d.Name}</td>
|
|
1130
|
+
// <td className="p-3 font-medium text-slate-600">{d.Specialization}</td>
|
|
1131
|
+
// <td className="p-3 text-right space-x-1.5">
|
|
1132
|
+
// <button onClick={() => setDoctorForm(d)} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1133
|
+
// <button onClick={() => handleDoctorDelete(d.DoctorID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1134
|
+
// </td>
|
|
1135
|
+
// </tr>
|
|
1136
|
+
// ))}
|
|
1137
|
+
// </tbody>
|
|
1138
|
+
// </table>
|
|
1139
|
+
// </div>
|
|
1140
|
+
// </div>
|
|
1141
|
+
// )}
|
|
1142
|
+
|
|
1143
|
+
// {/* TAB 4: APPOINTMENTS */}
|
|
1144
|
+
// {activeTab === 'appointments' && (
|
|
1145
|
+
// <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1146
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1147
|
+
// <h2 className="text-sm font-bold text-slate-800 mb-4">{appointmentForm.AppointmentID ? 'Modify Booking Slot' : 'Book Appointment Slot'}</h2>
|
|
1148
|
+
// <form onSubmit={handleAppointmentSubmit} className="space-y-4">
|
|
1149
|
+
// <div>
|
|
1150
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Patient</label>
|
|
1151
|
+
// <select value={appointmentForm.PatientID} onChange={(e) => setAppointmentForm({ ...appointmentForm, PatientID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
1152
|
+
// <option value="">-- Choose Registered Patient --</option>
|
|
1153
|
+
// {patients.map(p => <option key={p.PatientID} value={p.PatientID}>{p.Name} (ID: {p.PatientID})</option>)}
|
|
1154
|
+
// </select>
|
|
1155
|
+
// </div>
|
|
1156
|
+
// <div>
|
|
1157
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Doctor</label>
|
|
1158
|
+
// <select value={appointmentForm.DoctorID} onChange={(e) => setAppointmentForm({ ...appointmentForm, DoctorID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
1159
|
+
// <option value="">-- Choose Medical Officer --</option>
|
|
1160
|
+
// {doctors.map(d => <option key={d.DoctorID} value={d.DoctorID}>{d.Name}</option>)}
|
|
1161
|
+
// </select>
|
|
1162
|
+
// </div>
|
|
1163
|
+
// <div>
|
|
1164
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Consultation Date</label>
|
|
1165
|
+
// <input type="date" value={appointmentForm.Date ? appointmentForm.Date.split('T')[0] : ''} onChange={(e) => setAppointmentForm({ ...appointmentForm, Date: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" />
|
|
1166
|
+
// </div>
|
|
1167
|
+
// <button type="submit" className="w-full bg-amber-600 text-white py-2.5 rounded-xl text-xs font-bold">Commit Slot Booking</button>
|
|
1168
|
+
// </form>
|
|
1169
|
+
// </div>
|
|
1170
|
+
|
|
1171
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1172
|
+
// <table className="w-full text-left text-xs">
|
|
1173
|
+
// <thead>
|
|
1174
|
+
// <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1175
|
+
// <th className="p-3">ID</th>
|
|
1176
|
+
// <th className="p-3">Patient</th>
|
|
1177
|
+
// <th className="p-3">Doctor</th>
|
|
1178
|
+
// <th className="p-3">Date</th>
|
|
1179
|
+
// <th className="p-3 text-right">Actions</th>
|
|
1180
|
+
// </tr>
|
|
1181
|
+
// </thead>
|
|
1182
|
+
// <tbody className="divide-y">
|
|
1183
|
+
// {appointments.map((a) => (
|
|
1184
|
+
// <tr key={a.AppointmentID} className="hover:bg-slate-50/50">
|
|
1185
|
+
// <td className="p-3 text-slate-400 font-mono">{a.AppointmentID}</td>
|
|
1186
|
+
// <td className="p-3 font-bold text-slate-800">{a.PatientName}</td>
|
|
1187
|
+
// <td className="p-3 font-medium text-slate-600">{a.DoctorName}</td>
|
|
1188
|
+
// <td className="p-3 font-mono"><span className="bg-blue-50 text-blue-600 px-2 py-0.5 rounded border border-blue-100">{new Date(a.Date).toLocaleDateString()}</span></td>
|
|
1189
|
+
// <td className="p-3 text-right space-x-1.5">
|
|
1190
|
+
// <button onClick={() => setAppointmentForm({ AppointmentID: a.AppointmentID, PatientID: a.PatientID || '', DoctorID: a.DoctorID || '', Date: a.Date })} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1191
|
+
// <button onClick={() => handleAppointmentDelete(a.AppointmentID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1192
|
+
// </td>
|
|
1193
|
+
// </tr>
|
|
1194
|
+
// ))}
|
|
1195
|
+
// </tbody>
|
|
1196
|
+
// </table>
|
|
1197
|
+
// </div>
|
|
1198
|
+
// </div>
|
|
1199
|
+
// )}
|
|
1200
|
+
|
|
1201
|
+
// {/* TAB 5: PAYMENTS */}
|
|
1202
|
+
// {activeTab === 'payments' && (
|
|
1203
|
+
// <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1204
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1205
|
+
// <h2 className="text-sm font-bold text-slate-800 mb-4">{paymentForm.PaymentID ? 'Modify Invoice Data' : 'Generate New Patient Invoice'}</h2>
|
|
1206
|
+
// <form onSubmit={handlePaymentSubmit} className="space-y-4">
|
|
1207
|
+
// <div>
|
|
1208
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Patient Debtor</label>
|
|
1209
|
+
// <select value={paymentForm.PatientID} onChange={(e) => setPaymentForm({ ...paymentForm, PatientID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
1210
|
+
// <option value="">-- Select Patient --</option>
|
|
1211
|
+
// {patients.map(p => <option key={p.PatientID} value={p.PatientID}>{p.Name}</option>)}
|
|
1212
|
+
// </select>
|
|
1213
|
+
// </div>
|
|
1214
|
+
// <div>
|
|
1215
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Amount (RWF)</label>
|
|
1216
|
+
// <input type="number" value={paymentForm.Amount} onChange={(e) => setPaymentForm({ ...paymentForm, Amount: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Invoice Value" />
|
|
1217
|
+
// </div>
|
|
1218
|
+
// <div>
|
|
1219
|
+
// <label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Billing Date</label>
|
|
1220
|
+
// <input type="date" value={paymentForm.Date ? paymentForm.Date.split('T')[0] : ''} onChange={(e) => setPaymentForm({ ...paymentForm, Date: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" />
|
|
1221
|
+
// </div>
|
|
1222
|
+
// <button type="submit" className="w-full bg-indigo-600 text-white py-2.5 rounded-xl text-xs font-bold">Commit Statement</button>
|
|
1223
|
+
// </form>
|
|
1224
|
+
// </div>
|
|
1225
|
+
|
|
1226
|
+
// <div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1227
|
+
// <table className="w-full text-left text-xs">
|
|
1228
|
+
// <thead>
|
|
1229
|
+
// <tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1230
|
+
// <th className="p-3">ID</th>
|
|
1231
|
+
// <th className="p-3">Patient Name</th>
|
|
1232
|
+
// <th className="p-3">Amount</th>
|
|
1233
|
+
// <th className="p-3">Date</th>
|
|
1234
|
+
// <th className="p-3 text-right">Actions</th>
|
|
1235
|
+
// </tr>
|
|
1236
|
+
// </thead>
|
|
1237
|
+
// <tbody className="divide-y">
|
|
1238
|
+
// {payments.map((p) => (
|
|
1239
|
+
// <tr key={p.PaymentID} className="hover:bg-slate-50/50">
|
|
1240
|
+
// <td className="p-3 text-slate-400 font-mono">{p.PaymentID}</td>
|
|
1241
|
+
// <td className="p-3 font-bold text-slate-800">{p.PatientName}</td>
|
|
1242
|
+
// <td className="p-3 text-emerald-600 font-black">+{p.Amount?.toLocaleString()} RWF</td>
|
|
1243
|
+
// <td className="p-3 font-mono">{new Date(p.Date).toLocaleDateString()}</td>
|
|
1244
|
+
// <td className="p-3 text-right space-x-1.5">
|
|
1245
|
+
// <button onClick={() => setPaymentForm({ PaymentID: p.PaymentID, PatientID: p.PatientID || '', Amount: p.Amount || '', Date: p.Date })} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1246
|
+
// <button onClick={() => handlePaymentDelete(p.PaymentID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1247
|
+
// </td>
|
|
1248
|
+
// </tr>
|
|
1249
|
+
// ))}
|
|
1250
|
+
// </tbody>
|
|
1251
|
+
// </table>
|
|
1252
|
+
// </div>
|
|
1253
|
+
// </div>
|
|
1254
|
+
// )}
|
|
1255
|
+
// </main>
|
|
1256
|
+
// </div>
|
|
1257
|
+
// </div>
|
|
1258
|
+
// );
|
|
1259
|
+
// }
|
|
1260
|
+
|
|
1261
|
+
// export default App;
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
1267
|
+
import axios from 'axios';
|
|
1268
|
+
|
|
1269
|
+
function App() {
|
|
1270
|
+
const [activeTab, setActiveTab] = useState('dashboard');
|
|
1271
|
+
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
1272
|
+
const [loginData, setLoginData] = useState({ username: '', password: '' });
|
|
1273
|
+
const [user, setUser] = useState(null);
|
|
1274
|
+
|
|
1275
|
+
// Data States
|
|
1276
|
+
const [patients, setPatients] = useState([]);
|
|
1277
|
+
const [doctors, setDoctors] = useState([]);
|
|
1278
|
+
const [appointments, setAppointments] = useState([]);
|
|
1279
|
+
const [payments, setPayments] = useState([]);
|
|
1280
|
+
|
|
1281
|
+
// Form States
|
|
1282
|
+
const [patientForm, setPatientForm] = useState({ PatientID: null, Name: '', Age: '', Phone: '' });
|
|
1283
|
+
const [doctorForm, setDoctorForm] = useState({ DoctorID: null, Name: '', Specialization: '' });
|
|
1284
|
+
const [appointmentForm, setAppointmentForm] = useState({ AppointmentID: null, PatientID: '', DoctorID: '', Date: '' });
|
|
1285
|
+
const [paymentForm, setPaymentForm] = useState({ PaymentID: null, PatientID: '', Amount: '', Date: '' });
|
|
1286
|
+
|
|
1287
|
+
// Authentication
|
|
1288
|
+
const handleLogin = async (e) => {
|
|
1289
|
+
e.preventDefault();
|
|
1290
|
+
try {
|
|
1291
|
+
const response = await axios.post('http://localhost:5000/api/login', loginData, {
|
|
1292
|
+
headers: { 'Content-Type': 'application/json' }
|
|
1293
|
+
});
|
|
1294
|
+
if (response.data.success) {
|
|
1295
|
+
setIsAuthenticated(true);
|
|
1296
|
+
setUser(response.data.user);
|
|
1297
|
+
setLoginData({ username: '', password: '' });
|
|
1298
|
+
} else {
|
|
1299
|
+
alert(response.data.message);
|
|
1300
|
+
}
|
|
1301
|
+
} catch (error) {
|
|
1302
|
+
if (error.response && error.response.data && error.response.data.message) {
|
|
1303
|
+
alert(error.response.data.message);
|
|
1304
|
+
} else {
|
|
1305
|
+
alert('Login failed. Please check backend connection.');
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1310
|
+
const handleLogout = () => {
|
|
1311
|
+
setIsAuthenticated(false);
|
|
1312
|
+
setUser(null);
|
|
1313
|
+
setActiveTab('dashboard');
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
// Fetch Data Functions
|
|
1317
|
+
const fetchPatients = useCallback(async () => {
|
|
1318
|
+
try {
|
|
1319
|
+
const response = await axios.get('http://localhost:5000/api/patients');
|
|
1320
|
+
setPatients(response.data);
|
|
1321
|
+
} catch (err) { console.error(err); }
|
|
1322
|
+
}, []);
|
|
1323
|
+
|
|
1324
|
+
const fetchDoctors = useCallback(async () => {
|
|
1325
|
+
try {
|
|
1326
|
+
const response = await axios.get('http://localhost:5000/api/doctors');
|
|
1327
|
+
setDoctors(response.data);
|
|
1328
|
+
} catch (err) { console.error(err); }
|
|
1329
|
+
}, []);
|
|
1330
|
+
|
|
1331
|
+
const fetchAppointments = useCallback(async () => {
|
|
1332
|
+
try {
|
|
1333
|
+
const response = await axios.get('http://localhost:5000/api/appointments');
|
|
1334
|
+
setAppointments(response.data);
|
|
1335
|
+
} catch (err) { console.error(err); }
|
|
1336
|
+
}, []);
|
|
1337
|
+
|
|
1338
|
+
const fetchPayments = useCallback(async () => {
|
|
1339
|
+
try {
|
|
1340
|
+
const response = await axios.get('http://localhost:5000/api/payments');
|
|
1341
|
+
setPayments(response.data);
|
|
1342
|
+
} catch (err) { console.error(err); }
|
|
1343
|
+
}, []);
|
|
1344
|
+
|
|
1345
|
+
const fetchAllData = useCallback(() => {
|
|
1346
|
+
fetchPatients();
|
|
1347
|
+
fetchDoctors();
|
|
1348
|
+
fetchAppointments();
|
|
1349
|
+
fetchPayments();
|
|
1350
|
+
}, [fetchPatients, fetchDoctors, fetchAppointments, fetchPayments]);
|
|
1351
|
+
|
|
1352
|
+
useEffect(() => {
|
|
1353
|
+
if (isAuthenticated) {
|
|
1354
|
+
fetchAllData();
|
|
1355
|
+
}
|
|
1356
|
+
}, [isAuthenticated, fetchAllData]);
|
|
1357
|
+
|
|
1358
|
+
// Total Revenue Calculation
|
|
1359
|
+
const totalRevenue = payments.reduce((sum, p) => sum + Number(p.Amount || 0), 0);
|
|
1360
|
+
|
|
1361
|
+
// Patient Actions
|
|
1362
|
+
const handlePatientSubmit = async (e) => {
|
|
1363
|
+
e.preventDefault();
|
|
1364
|
+
if (!patientForm.Name || !patientForm.Age || !patientForm.Phone) return alert('Fill all fields');
|
|
1365
|
+
try {
|
|
1366
|
+
if (patientForm.PatientID) {
|
|
1367
|
+
await axios.put(`http://localhost:5000/api/patients/${patientForm.PatientID}`, patientForm);
|
|
1368
|
+
} else {
|
|
1369
|
+
await axios.post('http://localhost:5000/api/patients', patientForm);
|
|
1370
|
+
}
|
|
1371
|
+
setPatientForm({ PatientID: null, Name: '', Age: '', Phone: '' });
|
|
1372
|
+
fetchAllData();
|
|
1373
|
+
} catch (err) { alert('Operation failed'); }
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
const handlePatientDelete = async (id) => {
|
|
1377
|
+
if (window.confirm('Delete this patient?')) {
|
|
1378
|
+
try {
|
|
1379
|
+
await axios.delete(`http://localhost:5000/api/patients/${id}`);
|
|
1380
|
+
fetchAllData();
|
|
1381
|
+
} catch (err) { alert('Could not delete patient.'); }
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
|
|
1385
|
+
// Doctor Actions
|
|
1386
|
+
const handleDoctorSubmit = async (e) => {
|
|
1387
|
+
e.preventDefault();
|
|
1388
|
+
if (!doctorForm.Name || !doctorForm.Specialization) return alert('Fill all fields');
|
|
1389
|
+
try {
|
|
1390
|
+
if (doctorForm.DoctorID) {
|
|
1391
|
+
await axios.put(`http://localhost:5000/api/doctors/${doctorForm.DoctorID}`, doctorForm);
|
|
1392
|
+
} else {
|
|
1393
|
+
await axios.post('http://localhost:5000/api/doctors', doctorForm);
|
|
1394
|
+
}
|
|
1395
|
+
setDoctorForm({ DoctorID: null, Name: '', Specialization: '' });
|
|
1396
|
+
fetchAllData();
|
|
1397
|
+
} catch (err) { alert('Operation failed'); }
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1400
|
+
const handleDoctorDelete = async (id) => {
|
|
1401
|
+
if (window.confirm('Delete this doctor?')) {
|
|
1402
|
+
try {
|
|
1403
|
+
await axios.delete(`http://localhost:5000/api/doctors/${id}`);
|
|
1404
|
+
fetchAllData();
|
|
1405
|
+
} catch (err) { alert('Could not delete doctor.'); }
|
|
1406
|
+
}
|
|
1407
|
+
};
|
|
1408
|
+
|
|
1409
|
+
// Appointment Actions
|
|
1410
|
+
const handleAppointmentSubmit = async (e) => {
|
|
1411
|
+
e.preventDefault();
|
|
1412
|
+
if (!appointmentForm.PatientID || !appointmentForm.DoctorID || !appointmentForm.Date) return alert('Fill all fields');
|
|
1413
|
+
try {
|
|
1414
|
+
if (appointmentForm.AppointmentID) {
|
|
1415
|
+
await axios.put(`http://localhost:5000/api/appointments/${appointmentForm.AppointmentID}`, appointmentForm);
|
|
1416
|
+
} else {
|
|
1417
|
+
await axios.post('http://localhost:5000/api/appointments', appointmentForm);
|
|
1418
|
+
}
|
|
1419
|
+
setAppointmentForm({ AppointmentID: null, PatientID: '', DoctorID: '', Date: '' });
|
|
1420
|
+
fetchAppointments();
|
|
1421
|
+
} catch (err) { alert('Operation failed'); }
|
|
1422
|
+
};
|
|
1423
|
+
|
|
1424
|
+
const handleAppointmentDelete = async (id) => {
|
|
1425
|
+
if (window.confirm('Delete this appointment?')) {
|
|
1426
|
+
try {
|
|
1427
|
+
await axios.delete(`http://localhost:5000/api/appointments/${id}`);
|
|
1428
|
+
fetchAppointments();
|
|
1429
|
+
} catch (err) { alert('Operation failed'); }
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
|
|
1433
|
+
// Payment Actions
|
|
1434
|
+
const handlePaymentSubmit = async (e) => {
|
|
1435
|
+
e.preventDefault();
|
|
1436
|
+
if (!paymentForm.PatientID || !paymentForm.Amount || !paymentForm.Date) return alert('Fill all fields');
|
|
1437
|
+
try {
|
|
1438
|
+
if (paymentForm.PaymentID) {
|
|
1439
|
+
await axios.put(`http://localhost:5000/api/payments/${paymentForm.PaymentID}`, paymentForm);
|
|
1440
|
+
} else {
|
|
1441
|
+
await axios.post('http://localhost:5000/api/payments', paymentForm);
|
|
1442
|
+
}
|
|
1443
|
+
setPaymentForm({ PaymentID: null, PatientID: '', Amount: '', Date: '' });
|
|
1444
|
+
fetchPayments();
|
|
1445
|
+
} catch (err) { alert('Operation failed'); }
|
|
1446
|
+
};
|
|
1447
|
+
|
|
1448
|
+
const handlePaymentDelete = async (id) => {
|
|
1449
|
+
if (window.confirm('Delete this payment record?')) {
|
|
1450
|
+
try {
|
|
1451
|
+
await axios.delete(`http://localhost:5000/api/payments/${id}`);
|
|
1452
|
+
fetchPayments();
|
|
1453
|
+
} catch (err) { alert('Operation failed'); }
|
|
1454
|
+
}
|
|
1455
|
+
};
|
|
1456
|
+
|
|
1457
|
+
// UI rendering ya Login niba adahuye
|
|
1458
|
+
if (!isAuthenticated) {
|
|
1459
|
+
return (
|
|
1460
|
+
<div className="min-h-screen bg-gradient-to-tr from-slate-900 via-indigo-950 to-slate-900 flex items-center justify-center p-4">
|
|
1461
|
+
<div className="bg-white/95 backdrop-blur-md p-8 rounded-2xl shadow-2xl w-full max-w-md border border-white/20">
|
|
1462
|
+
<div className="text-center mb-8">
|
|
1463
|
+
<div className="bg-blue-600 text-white w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4 text-3xl font-black shadow-lg shadow-blue-500/30">
|
|
1464
|
+
H
|
|
1465
|
+
</div>
|
|
1466
|
+
<h1 className="text-2xl font-black tracking-tight text-slate-800">Hospital Management</h1>
|
|
1467
|
+
<p className="text-slate-500 text-sm mt-1">Sign in to access your administrative dashboard</p>
|
|
1468
|
+
</div>
|
|
1469
|
+
<form onSubmit={handleLogin} className="space-y-5">
|
|
1470
|
+
<div>
|
|
1471
|
+
<label className="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-2">Username</label>
|
|
1472
|
+
<input
|
|
1473
|
+
type="text"
|
|
1474
|
+
value={loginData.username}
|
|
1475
|
+
onChange={(e) => setLoginData({ ...loginData, username: e.target.value })}
|
|
1476
|
+
className="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all text-slate-800"
|
|
1477
|
+
placeholder="Enter your username"
|
|
1478
|
+
/>
|
|
1479
|
+
</div>
|
|
1480
|
+
<div>
|
|
1481
|
+
<label className="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-2">Password</label>
|
|
1482
|
+
<input
|
|
1483
|
+
type="password"
|
|
1484
|
+
value={loginData.password}
|
|
1485
|
+
onChange={(e) => setLoginData({ ...loginData, password: e.target.value })}
|
|
1486
|
+
className="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all text-slate-800"
|
|
1487
|
+
placeholder="••••••••"
|
|
1488
|
+
/>
|
|
1489
|
+
</div>
|
|
1490
|
+
<button type="submit" className="w-full bg-gradient-to-r from-blue-600 to-indigo-600 text-white py-3 rounded-xl font-bold shadow-lg shadow-blue-500/20">
|
|
1491
|
+
Sign In
|
|
1492
|
+
</button>
|
|
1493
|
+
</form>
|
|
1494
|
+
<div className="mt-6 text-center bg-slate-50 py-2.5 rounded-xl border border-slate-100">
|
|
1495
|
+
<p className="text-xs text-slate-500 font-medium">Demo Access: <span className="font-mono font-bold text-blue-600 bg-blue-50 px-1.5 py-0.5 rounded border border-blue-100">admin / admin123</span></p>
|
|
1496
|
+
</div>
|
|
1497
|
+
</div>
|
|
1498
|
+
</div>
|
|
1499
|
+
);
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
return (
|
|
1503
|
+
<div className="min-h-screen bg-slate-50/50 flex text-slate-800">
|
|
1504
|
+
|
|
1505
|
+
{/* SIDEBAR NAVIGATION */}
|
|
1506
|
+
<aside className="w-64 bg-slate-900 text-slate-300 flex flex-col fixed inset-y-0 left-0 z-50 border-r border-slate-800 shadow-xl">
|
|
1507
|
+
<div className="p-5 border-b border-slate-800 flex items-center space-x-3">
|
|
1508
|
+
<div className="bg-gradient-to-tr from-blue-500 to-indigo-600 text-white w-9 h-9 rounded-xl flex items-center justify-center font-black text-lg">
|
|
1509
|
+
H
|
|
1510
|
+
</div>
|
|
1511
|
+
<div>
|
|
1512
|
+
<h1 className="text-sm font-black text-white tracking-tight leading-none">MediCare Pro</h1>
|
|
1513
|
+
<p className="text-[9px] text-slate-500 font-bold uppercase tracking-widest mt-1">Management Hub</p>
|
|
1514
|
+
</div>
|
|
1515
|
+
</div>
|
|
1516
|
+
|
|
1517
|
+
<div className="p-4 mx-3 my-4 bg-slate-800/50 rounded-xl border border-slate-800/60 flex items-center space-x-3">
|
|
1518
|
+
<div className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
|
|
1519
|
+
<div className="flex-1 min-w-0">
|
|
1520
|
+
<p className="text-xs font-bold text-white truncate leading-none">{user?.username}</p>
|
|
1521
|
+
<p className="text-[9px] text-blue-400 font-bold uppercase tracking-wider mt-1">{user?.role}</p>
|
|
1522
|
+
</div>
|
|
1523
|
+
</div>
|
|
1524
|
+
|
|
1525
|
+
<nav className="flex-1 px-3 space-y-1">
|
|
1526
|
+
{[
|
|
1527
|
+
{ id: 'dashboard', label: 'Dashboard Overview', icon: '📊' },
|
|
1528
|
+
{ id: 'patients', label: 'Patients Registry', icon: '👥' },
|
|
1529
|
+
{ id: 'doctors', label: 'Medical Staff', icon: '🩺' },
|
|
1530
|
+
{ id: 'appointments', label: 'Appointments Slot', icon: '📅' },
|
|
1531
|
+
{ id: 'payments', label: 'Financial Billing', icon: '💳' },
|
|
1532
|
+
{ id: 'reports', label: 'General Report', icon: '📋' }
|
|
1533
|
+
].map((tab) => (
|
|
1534
|
+
<button
|
|
1535
|
+
key={tab.id}
|
|
1536
|
+
onClick={() => setActiveTab(tab.id)}
|
|
1537
|
+
className={`w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-xs font-bold tracking-wide transition-all ${
|
|
1538
|
+
activeTab === tab.id ? 'bg-blue-600 text-white shadow-lg' : 'text-slate-400 hover:bg-slate-800 hover:text-slate-200'
|
|
1539
|
+
}`}
|
|
1540
|
+
>
|
|
1541
|
+
<span className="text-base">{tab.icon}</span>
|
|
1542
|
+
<span>{tab.label}</span>
|
|
1543
|
+
</button>
|
|
1544
|
+
))}
|
|
1545
|
+
</nav>
|
|
1546
|
+
|
|
1547
|
+
<div className="p-4 border-t border-slate-800">
|
|
1548
|
+
<button onClick={handleLogout} className="w-full bg-red-950/40 text-red-400 hover:bg-red-900 hover:text-white px-4 py-2.5 rounded-xl text-xs font-bold flex items-center justify-center space-x-2">
|
|
1549
|
+
<span>🚪</span>
|
|
1550
|
+
<span>Logout Session</span>
|
|
1551
|
+
</button>
|
|
1552
|
+
</div>
|
|
1553
|
+
</aside>
|
|
1554
|
+
|
|
1555
|
+
{/* MAIN CONTENT AREA CONTAINER */}
|
|
1556
|
+
<div className="flex-1 pl-64 flex flex-col min-h-screen">
|
|
1557
|
+
<header className="bg-white/80 backdrop-blur-md border-b border-slate-100 px-8 py-4 flex justify-between items-center sticky top-0 z-40">
|
|
1558
|
+
<div>
|
|
1559
|
+
<h2 className="text-sm font-bold text-slate-400 uppercase tracking-wider text-[10px]">Active Workspace</h2>
|
|
1560
|
+
<h1 className="text-lg font-black text-slate-800 capitalize tracking-tight mt-0.5">{activeTab} Section</h1>
|
|
1561
|
+
</div>
|
|
1562
|
+
<div className="text-xs text-slate-400 font-semibold bg-slate-50 px-3 py-1.5 rounded-xl border border-slate-100">
|
|
1563
|
+
System Status: <span className="text-emerald-500 font-bold">Online</span>
|
|
1564
|
+
</div>
|
|
1565
|
+
</header>
|
|
1566
|
+
|
|
1567
|
+
<main className="flex-1 p-8 max-w-7xl w-full mx-auto">
|
|
1568
|
+
|
|
1569
|
+
{/* TAB 1: DASHBOARD OVERVIEW */}
|
|
1570
|
+
{activeTab === 'dashboard' && (
|
|
1571
|
+
<div className="space-y-6">
|
|
1572
|
+
<div className="bg-gradient-to-r from-slate-900 to-indigo-950 rounded-2xl p-6 text-white shadow-xl flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
|
|
1573
|
+
<div>
|
|
1574
|
+
<h2 className="text-xl font-black tracking-tight">System Operational Summary</h2>
|
|
1575
|
+
<p className="text-slate-400 text-xs mt-1 font-medium">Manage all hospital records dynamically in real-time right here.</p>
|
|
1576
|
+
</div>
|
|
1577
|
+
</div>
|
|
1578
|
+
|
|
1579
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
1580
|
+
<div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
1581
|
+
<div>
|
|
1582
|
+
<p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Total Patients</p>
|
|
1583
|
+
<p className="text-2xl font-black text-slate-800 mt-1">{patients.length}</p>
|
|
1584
|
+
</div>
|
|
1585
|
+
<div className="w-12 h-12 bg-blue-50 rounded-xl flex items-center justify-center text-xl">👥</div>
|
|
1586
|
+
</div>
|
|
1587
|
+
<div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
1588
|
+
<div>
|
|
1589
|
+
<p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Active Staff Doctors</p>
|
|
1590
|
+
<p className="text-2xl font-black text-slate-800 mt-1">{doctors.length}</p>
|
|
1591
|
+
</div>
|
|
1592
|
+
<div className="w-12 h-12 bg-emerald-50 rounded-xl flex items-center justify-center text-xl">🩺</div>
|
|
1593
|
+
</div>
|
|
1594
|
+
<div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
1595
|
+
<div>
|
|
1596
|
+
<p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Total Consultations</p>
|
|
1597
|
+
<p className="text-2xl font-black text-slate-800 mt-1">{appointments.length}</p>
|
|
1598
|
+
</div>
|
|
1599
|
+
<div className="w-12 h-12 bg-amber-50 rounded-xl flex items-center justify-center text-xl">📅</div>
|
|
1600
|
+
</div>
|
|
1601
|
+
<div className="bg-white p-5 rounded-2xl border flex items-center justify-between shadow-sm">
|
|
1602
|
+
<div>
|
|
1603
|
+
<p className="text-slate-400 text-[10px] font-bold uppercase tracking-wider">Gross Income Inflow</p>
|
|
1604
|
+
<p className="text-xl font-black text-slate-800 mt-1">{totalRevenue.toLocaleString()} RWF</p>
|
|
1605
|
+
</div>
|
|
1606
|
+
<div className="w-12 h-12 bg-indigo-50 rounded-xl flex items-center justify-center text-xl">💰</div>
|
|
1607
|
+
</div>
|
|
1608
|
+
</div>
|
|
1609
|
+
|
|
1610
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
1611
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm flex flex-col">
|
|
1612
|
+
<h3 className="text-sm font-bold text-slate-800 mb-4">Recent Appointment Bookings</h3>
|
|
1613
|
+
<div className="divide-y overflow-y-auto max-h-64 flex-1">
|
|
1614
|
+
{appointments.slice(-4).reverse().map((a) => (
|
|
1615
|
+
<div key={a.AppointmentID} className="py-3 flex justify-between items-center px-1 rounded-lg">
|
|
1616
|
+
<div>
|
|
1617
|
+
<p className="font-bold text-slate-800 text-xs">{a.PatientName}</p>
|
|
1618
|
+
<p className="text-[10px] text-slate-400">Assigned Doctor: {a.DoctorName}</p>
|
|
1619
|
+
</div>
|
|
1620
|
+
<span className="text-[10px] bg-blue-50 text-blue-600 font-bold px-2.5 py-1 rounded-lg">
|
|
1621
|
+
{new Date(a.Date).toLocaleDateString()}
|
|
1622
|
+
</span>
|
|
1623
|
+
</div>
|
|
1624
|
+
))}
|
|
1625
|
+
{appointments.length === 0 && <div className="text-center py-8 text-slate-400 text-xs">No records found.</div>}
|
|
1626
|
+
</div>
|
|
1627
|
+
</div>
|
|
1628
|
+
|
|
1629
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm flex flex-col">
|
|
1630
|
+
<h3 className="text-sm font-bold text-slate-800 mb-4">Latest Financial Ledger Inflow</h3>
|
|
1631
|
+
<div className="divide-y overflow-y-auto max-h-64 flex-1">
|
|
1632
|
+
{payments.slice(-4).reverse().map((p) => (
|
|
1633
|
+
<div key={p.PaymentID} className="py-3 flex justify-between items-center px-1 rounded-lg">
|
|
1634
|
+
<div>
|
|
1635
|
+
<p className="font-bold text-slate-800 text-xs">{p.PatientName}</p>
|
|
1636
|
+
<p className="text-[10px] text-slate-400">{new Date(p.Date).toLocaleDateString()}</p>
|
|
1637
|
+
</div>
|
|
1638
|
+
<span className="text-xs font-black text-emerald-600">+{p.Amount?.toLocaleString()} RWF</span>
|
|
1639
|
+
</div>
|
|
1640
|
+
))}
|
|
1641
|
+
{payments.length === 0 && <div className="text-center py-8 text-slate-400 text-xs">No records found.</div>}
|
|
1642
|
+
</div>
|
|
1643
|
+
</div>
|
|
1644
|
+
</div>
|
|
1645
|
+
</div>
|
|
1646
|
+
)}
|
|
1647
|
+
|
|
1648
|
+
{/* TAB 2: PATIENTS */}
|
|
1649
|
+
{activeTab === 'patients' && (
|
|
1650
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1651
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1652
|
+
<h2 className="text-sm font-bold text-slate-800 mb-4">{patientForm.PatientID ? 'Update Patient File Record' : 'Register New Patient File'}</h2>
|
|
1653
|
+
<form onSubmit={handlePatientSubmit} className="space-y-4">
|
|
1654
|
+
<div>
|
|
1655
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Full Name</label>
|
|
1656
|
+
<input type="text" value={patientForm.Name} onChange={(e) => setPatientForm({ ...patientForm, Name: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Full Name" />
|
|
1657
|
+
</div>
|
|
1658
|
+
<div>
|
|
1659
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Patient Age</label>
|
|
1660
|
+
<input type="number" value={patientForm.Age} onChange={(e) => setPatientForm({ ...patientForm, Age: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Age" />
|
|
1661
|
+
</div>
|
|
1662
|
+
<div>
|
|
1663
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Phone</label>
|
|
1664
|
+
<input type="text" value={patientForm.Phone} onChange={(e) => setPatientForm({ ...patientForm, Phone: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Phone Connection" />
|
|
1665
|
+
</div>
|
|
1666
|
+
<button type="submit" className="w-full bg-blue-600 text-white py-2.5 rounded-xl text-xs font-bold">Save Patient Records</button>
|
|
1667
|
+
</form>
|
|
1668
|
+
</div>
|
|
1669
|
+
|
|
1670
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1671
|
+
<table className="w-full text-left text-xs border-collapse">
|
|
1672
|
+
<thead>
|
|
1673
|
+
<tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1674
|
+
<th className="p-3">ID</th>
|
|
1675
|
+
<th className="p-3">Name</th>
|
|
1676
|
+
<th className="p-3">Age</th>
|
|
1677
|
+
<th className="p-3">Phone</th>
|
|
1678
|
+
<th className="p-3 text-right">Actions</th>
|
|
1679
|
+
</tr>
|
|
1680
|
+
</thead>
|
|
1681
|
+
<tbody className="divide-y">
|
|
1682
|
+
{patients.map((p) => (
|
|
1683
|
+
<tr key={p.PatientID} className="hover:bg-slate-50/50">
|
|
1684
|
+
<td className="p-3 font-mono text-slate-400">{p.PatientID}</td>
|
|
1685
|
+
<td className="p-3 font-bold text-slate-800">{p.Name}</td>
|
|
1686
|
+
<td className="p-3">{p.Age} Yrs</td>
|
|
1687
|
+
<td className="p-3 font-mono">{p.Phone}</td>
|
|
1688
|
+
<td className="p-3 text-right space-x-1.5">
|
|
1689
|
+
<button onClick={() => setPatientForm(p)} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1690
|
+
<button onClick={() => handlePatientDelete(p.PatientID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1691
|
+
</td>
|
|
1692
|
+
</tr>
|
|
1693
|
+
))}
|
|
1694
|
+
</tbody>
|
|
1695
|
+
</table>
|
|
1696
|
+
</div>
|
|
1697
|
+
</div>
|
|
1698
|
+
)}
|
|
1699
|
+
|
|
1700
|
+
{/* TAB 3: DOCTORS */}
|
|
1701
|
+
{activeTab === 'doctors' && (
|
|
1702
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1703
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1704
|
+
<h2 className="text-sm font-bold text-slate-800 mb-4">{doctorForm.DoctorID ? 'Update Doctor Profile' : 'Register New Doctor'}</h2>
|
|
1705
|
+
<form onSubmit={handleDoctorSubmit} className="space-y-4">
|
|
1706
|
+
<div>
|
|
1707
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Doctor Name</label>
|
|
1708
|
+
<input type="text" value={doctorForm.Name} onChange={(e) => setDoctorForm({ ...doctorForm, Name: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Dr. Name" />
|
|
1709
|
+
</div>
|
|
1710
|
+
<div>
|
|
1711
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Specialization</label>
|
|
1712
|
+
<input type="text" value={doctorForm.Specialization} onChange={(e) => setDoctorForm({ ...doctorForm, Specialization: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Specialization" />
|
|
1713
|
+
</div>
|
|
1714
|
+
<button type="submit" className="w-full bg-emerald-600 text-white py-2.5 rounded-xl text-xs font-bold">Save Doctor Specs</button>
|
|
1715
|
+
</form>
|
|
1716
|
+
</div>
|
|
1717
|
+
|
|
1718
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1719
|
+
<table className="w-full text-left text-xs">
|
|
1720
|
+
<thead>
|
|
1721
|
+
<tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1722
|
+
<th className="p-3">ID</th>
|
|
1723
|
+
<th className="p-3">Name</th>
|
|
1724
|
+
<th className="p-3">Specialization</th>
|
|
1725
|
+
<th className="p-3 text-right">Actions</th>
|
|
1726
|
+
</tr>
|
|
1727
|
+
</thead>
|
|
1728
|
+
<tbody className="divide-y">
|
|
1729
|
+
{doctors.map((d) => (
|
|
1730
|
+
<tr key={d.DoctorID} className="hover:bg-slate-50/50">
|
|
1731
|
+
<td className="p-3 font-mono text-slate-400">{d.DoctorID}</td>
|
|
1732
|
+
<td className="p-3 font-bold text-slate-800">{d.Name}</td>
|
|
1733
|
+
<td className="p-3 font-medium text-slate-600">{d.Specialization}</td>
|
|
1734
|
+
<td className="p-3 text-right space-x-1.5">
|
|
1735
|
+
<button onClick={() => setDoctorForm(d)} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1736
|
+
<button onClick={() => handleDoctorDelete(d.DoctorID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1737
|
+
</td>
|
|
1738
|
+
</tr>
|
|
1739
|
+
))}
|
|
1740
|
+
</tbody>
|
|
1741
|
+
</table>
|
|
1742
|
+
</div>
|
|
1743
|
+
</div>
|
|
1744
|
+
)}
|
|
1745
|
+
|
|
1746
|
+
{/* TAB 4: APPOINTMENTS */}
|
|
1747
|
+
{activeTab === 'appointments' && (
|
|
1748
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1749
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1750
|
+
<h2 className="text-sm font-bold text-slate-800 mb-4">{appointmentForm.AppointmentID ? 'Modify Booking Slot' : 'Book Appointment Slot'}</h2>
|
|
1751
|
+
<form onSubmit={handleAppointmentSubmit} className="space-y-4">
|
|
1752
|
+
<div>
|
|
1753
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Patient</label>
|
|
1754
|
+
<select value={appointmentForm.PatientID} onChange={(e) => setAppointmentForm({ ...appointmentForm, PatientID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
1755
|
+
<option value="">-- Choose Registered Patient --</option>
|
|
1756
|
+
{patients.map(p => <option key={p.PatientID} value={p.PatientID}>{p.Name} (ID: {p.PatientID})</option>)}
|
|
1757
|
+
</select>
|
|
1758
|
+
</div>
|
|
1759
|
+
<div>
|
|
1760
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Doctor</label>
|
|
1761
|
+
<select value={appointmentForm.DoctorID} onChange={(e) => setAppointmentForm({ ...appointmentForm, DoctorID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
1762
|
+
<option value="">-- Choose Medical Officer --</option>
|
|
1763
|
+
{doctors.map(d => <option key={d.DoctorID} value={d.DoctorID}>{d.Name}</option>)}
|
|
1764
|
+
</select>
|
|
1765
|
+
</div>
|
|
1766
|
+
<div>
|
|
1767
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Consultation Date</label>
|
|
1768
|
+
<input type="date" value={appointmentForm.Date ? appointmentForm.Date.split('T')[0] : ''} onChange={(e) => setAppointmentForm({ ...appointmentForm, Date: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" />
|
|
1769
|
+
</div>
|
|
1770
|
+
<button type="submit" className="w-full bg-amber-600 text-white py-2.5 rounded-xl text-xs font-bold">Commit Slot Booking</button>
|
|
1771
|
+
</form>
|
|
1772
|
+
</div>
|
|
1773
|
+
|
|
1774
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1775
|
+
<table className="w-full text-left text-xs">
|
|
1776
|
+
<thead>
|
|
1777
|
+
<tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1778
|
+
<th className="p-3">ID</th>
|
|
1779
|
+
<th className="p-3">Patient</th>
|
|
1780
|
+
<th className="p-3">Doctor</th>
|
|
1781
|
+
<th className="p-3">Date</th>
|
|
1782
|
+
<th className="p-3 text-right">Actions</th>
|
|
1783
|
+
</tr>
|
|
1784
|
+
</thead>
|
|
1785
|
+
<tbody className="divide-y">
|
|
1786
|
+
{appointments.map((a) => (
|
|
1787
|
+
<tr key={a.AppointmentID} className="hover:bg-slate-50/50">
|
|
1788
|
+
<td className="p-3 text-slate-400 font-mono">{a.AppointmentID}</td>
|
|
1789
|
+
<td className="p-3 font-bold text-slate-800">{a.PatientName}</td>
|
|
1790
|
+
<td className="p-3 font-medium text-slate-600">{a.DoctorName}</td>
|
|
1791
|
+
<td className="p-3 font-mono"><span className="bg-blue-50 text-blue-600 px-2 py-0.5 rounded border border-blue-100">{new Date(a.Date).toLocaleDateString()}</span></td>
|
|
1792
|
+
<td className="p-3 text-right space-x-1.5">
|
|
1793
|
+
<button onClick={() => setAppointmentForm({ AppointmentID: a.AppointmentID, PatientID: a.PatientID || '', DoctorID: a.DoctorID || '', Date: a.Date })} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1794
|
+
<button onClick={() => handleAppointmentDelete(a.AppointmentID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1795
|
+
</td>
|
|
1796
|
+
</tr>
|
|
1797
|
+
))}
|
|
1798
|
+
</tbody>
|
|
1799
|
+
</table>
|
|
1800
|
+
</div>
|
|
1801
|
+
</div>
|
|
1802
|
+
)}
|
|
1803
|
+
|
|
1804
|
+
{/* TAB 5: PAYMENTS */}
|
|
1805
|
+
{activeTab === 'payments' && (
|
|
1806
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
1807
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm h-fit">
|
|
1808
|
+
<h2 className="text-sm font-bold text-slate-800 mb-4">{paymentForm.PaymentID ? 'Modify Invoice Data' : 'Generate New Patient Invoice'}</h2>
|
|
1809
|
+
<form onSubmit={handlePaymentSubmit} className="space-y-4">
|
|
1810
|
+
<div>
|
|
1811
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Select Patient Debtor</label>
|
|
1812
|
+
<select value={paymentForm.PatientID} onChange={(e) => setPaymentForm({ ...paymentForm, PatientID: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs bg-white">
|
|
1813
|
+
<option value="">-- Select Patient --</option>
|
|
1814
|
+
{patients.map(p => <option key={p.PatientID} value={p.PatientID}>{p.Name}</option>)}
|
|
1815
|
+
</select>
|
|
1816
|
+
</div>
|
|
1817
|
+
<div>
|
|
1818
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Amount (RWF)</label>
|
|
1819
|
+
<input type="number" value={paymentForm.Amount} onChange={(e) => setPaymentForm({ ...paymentForm, Amount: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" placeholder="Invoice Value" />
|
|
1820
|
+
</div>
|
|
1821
|
+
<div>
|
|
1822
|
+
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Billing Date</label>
|
|
1823
|
+
<input type="date" value={paymentForm.Date ? paymentForm.Date.split('T')[0] : ''} onChange={(e) => setPaymentForm({ ...paymentForm, Date: e.target.value })} className="w-full border p-2.5 rounded-xl text-xs" />
|
|
1824
|
+
</div>
|
|
1825
|
+
<button type="submit" className="w-full bg-indigo-600 text-white py-2.5 rounded-xl text-xs font-bold">Commit Statement</button>
|
|
1826
|
+
</form>
|
|
1827
|
+
</div>
|
|
1828
|
+
|
|
1829
|
+
<div className="bg-white p-5 rounded-2xl border shadow-sm col-span-2 overflow-x-auto">
|
|
1830
|
+
<table className="w-full text-left text-xs">
|
|
1831
|
+
<thead>
|
|
1832
|
+
<tr className="bg-slate-50 text-slate-500 uppercase font-bold text-[10px] border-b">
|
|
1833
|
+
<th className="p-3">ID</th>
|
|
1834
|
+
<th className="p-3">Patient Name</th>
|
|
1835
|
+
<th className="p-3">Amount</th>
|
|
1836
|
+
<th className="p-3">Date</th>
|
|
1837
|
+
<th className="p-3 text-right">Actions</th>
|
|
1838
|
+
</tr>
|
|
1839
|
+
</thead>
|
|
1840
|
+
<tbody className="divide-y">
|
|
1841
|
+
{payments.map((p) => (
|
|
1842
|
+
<tr key={p.PaymentID} className="hover:bg-slate-50/50">
|
|
1843
|
+
<td className="p-3 text-slate-400 font-mono">{p.PaymentID}</td>
|
|
1844
|
+
<td className="p-3 font-bold text-slate-800">{p.PatientName}</td>
|
|
1845
|
+
<td className="p-3 font-black text-emerald-600">{Number(p.Amount).toLocaleString()} RWF</td>
|
|
1846
|
+
<td className="p-3 font-mono text-slate-500">{new Date(p.Date).toLocaleDateString()}</td>
|
|
1847
|
+
<td className="p-3 text-right space-x-1.5">
|
|
1848
|
+
<button onClick={() => setPaymentForm({ PaymentID: p.PaymentID, PatientID: p.PatientID || '', Amount: p.Amount, Date: p.Date })} className="bg-amber-50 text-amber-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Edit</button>
|
|
1849
|
+
<button onClick={() => handlePaymentDelete(p.PaymentID)} className="bg-red-50 text-red-600 px-2 py-1 rounded-lg font-bold text-[10px] border">Delete</button>
|
|
1850
|
+
</td>
|
|
1851
|
+
</tr>
|
|
1852
|
+
))}
|
|
1853
|
+
</tbody>
|
|
1854
|
+
</table>
|
|
1855
|
+
</div>
|
|
1856
|
+
</div>
|
|
1857
|
+
)}
|
|
1858
|
+
|
|
1859
|
+
{/* TAB 6: REPORTS */}
|
|
1860
|
+
{activeTab === 'reports' && (
|
|
1861
|
+
<div className="bg-white p-8 rounded-2xl border shadow-sm space-y-6">
|
|
1862
|
+
<div className="border-b pb-4 text-center">
|
|
1863
|
+
<h1 className="text-xl font-black text-slate-800 uppercase tracking-wide">MediCare Pro Comprehensive Summary Report</h1>
|
|
1864
|
+
<p className="text-slate-400 text-xs mt-1">Generated dynamically on {new Date().toLocaleDateString()}</p>
|
|
1865
|
+
</div>
|
|
1866
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 text-center">
|
|
1867
|
+
<div className="p-4 bg-slate-50 rounded-xl border">
|
|
1868
|
+
<h3 className="text-xs font-bold uppercase text-slate-400">Total Patients Dossiers</h3>
|
|
1869
|
+
<p className="text-3xl font-black text-blue-600 mt-2">{patients.length}</p>
|
|
1870
|
+
</div>
|
|
1871
|
+
<div className="p-4 bg-slate-50 rounded-xl border">
|
|
1872
|
+
<h3 className="text-xs font-bold uppercase text-slate-400">Consultations Services</h3>
|
|
1873
|
+
<p className="text-3xl font-black text-amber-600 mt-2">{appointments.length}</p>
|
|
1874
|
+
</div>
|
|
1875
|
+
<div className="p-4 bg-slate-50 rounded-xl border">
|
|
1876
|
+
<h3 className="text-xs font-bold uppercase text-slate-400">Cumulative Income</h3>
|
|
1877
|
+
<p className="text-3xl font-black text-emerald-600 mt-2">{totalRevenue.toLocaleString()} RWF</p>
|
|
1878
|
+
</div>
|
|
1879
|
+
</div>
|
|
1880
|
+
</div>
|
|
1881
|
+
)}
|
|
1882
|
+
</main>
|
|
1883
|
+
</div>
|
|
1884
|
+
</div>
|
|
1885
|
+
);
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
export default App;
|