Compare commits
56 Commits
mobile-api
...
qc-mobile/
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ee0b98f07 | |||
| cc78d82ca4 | |||
| 3c2a8b3543 | |||
| 276cf9e970 | |||
| 8ccf722c90 | |||
| 7ad7b3496a | |||
| c9c39f319c | |||
| c976e6beaf | |||
| 4b21084748 | |||
| 3277d8cb19 | |||
| b951c698c5 | |||
| ad91a48d82 | |||
| a06036cab7 | |||
| c3d8ccd490 | |||
| ba6a83f61d | |||
| dc05c4ef7e | |||
| d56a00a92b | |||
| 43deddca43 | |||
| 1e647c0391 | |||
| 6f10ff7c3e | |||
| 09be7739d5 | |||
| 38734cda8c | |||
| 94dc780ead | |||
| fb9515dfe4 | |||
| 0b3d4830f9 | |||
| c710ca60b7 | |||
| 94e4b884a7 | |||
| 4164092100 | |||
| fcad857422 | |||
| 32619ee9b3 | |||
| b118a6425c | |||
| 45305e44cc | |||
| b6e5755942 | |||
| 09e1f702e1 | |||
| 14fbd1a6dd | |||
| a49b95ac8e | |||
| ba5620bcc5 | |||
| 40df3a5e5b | |||
| 134f1dceff | |||
| 24e6fcd0f7 | |||
| 9a3726cbcc | |||
| 10fb0449b4 | |||
| ac6c6217b5 | |||
| cf8d62531f | |||
| 04dd7e6c11 | |||
| 9a967f0965 | |||
| 5e07dfb749 | |||
| dbb71633d4 | |||
| 27259cd86c | |||
| b1a5e50b7b | |||
| a278470dbb | |||
| b209a12315 | |||
| 9aee4e52ed | |||
| 0f11fa37a5 | |||
| 29677066ef | |||
| 579444c002 |
35
CHANGELOG.md
35
CHANGELOG.md
@@ -2,6 +2,41 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||
|
||||
## [1.5.24](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.22...v1.5.24) (2025-12-08)
|
||||
|
||||
## [1.5.22](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.21...v1.5.22) (2025-12-03)
|
||||
|
||||
## [1.5.21](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.20...v1.5.21) (2025-12-03)
|
||||
|
||||
## [1.5.20](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.19...v1.5.20) (2025-12-02)
|
||||
|
||||
## [1.5.19](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.18...v1.5.19) (2025-12-01)
|
||||
|
||||
## [1.5.18](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.17...v1.5.18) (2025-11-28)
|
||||
|
||||
## [1.5.17](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.16...v1.5.17) (2025-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* delete all data user ([fb9515d](https://wibugit.wibudev.com/wibu/hipmi/commit/fb9515dfe465ef07d43460ca4e9bb31705ec48b8))
|
||||
|
||||
## [1.5.16](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.15...v1.5.16) (2025-11-20)
|
||||
|
||||
## [1.5.15](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.14...v1.5.15) (2025-11-18)
|
||||
|
||||
## [1.5.14](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.13...v1.5.14) (2025-11-17)
|
||||
|
||||
## [1.5.13](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.12...v1.5.13) (2025-11-17)
|
||||
|
||||
## [1.5.12](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.10...v1.5.12) (2025-11-13)
|
||||
|
||||
## [1.5.11](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.4.45...v1.5.11) (2025-11-07)
|
||||
|
||||
## [1.5.10](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.9...v1.5.10) (2025-11-03)
|
||||
|
||||
## [1.5.9](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.8...v1.5.9) (2025-10-30)
|
||||
|
||||
## [1.5.8](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.7...v1.5.8) (2025-10-29)
|
||||
|
||||
## [1.5.7](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.6...v1.5.7) (2025-10-28)
|
||||
|
||||
79
bun.lock
79
bun.lock
@@ -18,6 +18,7 @@
|
||||
"@mantine/notifications": "^6.0.17",
|
||||
"@mantine/tiptap": "^7.5.3",
|
||||
"@prisma/client": "^6.3.0",
|
||||
"@react-email/render": "^2.0.0",
|
||||
"@react-pdf/renderer": "^3.4.4",
|
||||
"@tabler/icons-react": "^3.31.0",
|
||||
"@tiptap/extension-highlight": "^2.2.3",
|
||||
@@ -40,6 +41,7 @@
|
||||
"autoprefixer": "10.4.14",
|
||||
"bufferutil": "^4.0.8",
|
||||
"bun": "^1.1.38",
|
||||
"caniuse-lite": "^1.0.30001757",
|
||||
"colors": "^1.4.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"dayjs": "^1.11.10",
|
||||
@@ -79,6 +81,7 @@
|
||||
"react-quill": "^2.0.0",
|
||||
"react-responsive-carousel": "^3.2.23",
|
||||
"react-toastify": "^9.1.3",
|
||||
"resend": "^6.4.2",
|
||||
"sharp": "^0.33.5",
|
||||
"socket.io-client": "^4.7.2",
|
||||
"swr": "^2.3.0",
|
||||
@@ -838,6 +841,8 @@
|
||||
|
||||
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
|
||||
|
||||
"@react-email/render": ["@react-email/render@2.0.0", "", { "dependencies": { "html-to-text": "^9.0.5", "prettier": "^3.5.3" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-rdjNj6iVzv8kRKDPFas+47nnoe6B40+nwukuXwY4FCwM7XBg6tmYr+chQryCuavUj2J65MMf6fztk1bxOUiSVA=="],
|
||||
|
||||
"@react-native/assets-registry": ["@react-native/assets-registry@0.78.0", "", {}, "sha512-PPHlTRuP9litTYkbFNkwveQFto3I94QRWPBBARU0cH/4ks4EkfCfb/Pdb3AHgtJi58QthSHKFvKTQnAWyHPs7w=="],
|
||||
|
||||
"@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.76.7", "", { "dependencies": { "@react-native/codegen": "0.76.7" } }, "sha512-+8H4DXJREM4l/pwLF/wSVMRzVhzhGDix5jLezNrMD9J1U1AMfV2aSkWA1XuqR7pjPs/Vqf6TaPL7vJMZ4LU05Q=="],
|
||||
@@ -894,6 +899,8 @@
|
||||
|
||||
"@segment/loosely-validate-event": ["@segment/loosely-validate-event@2.0.0", "", { "dependencies": { "component-type": "^1.2.1", "join-component": "^1.1.0" } }, "sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw=="],
|
||||
|
||||
"@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="],
|
||||
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
|
||||
|
||||
"@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="],
|
||||
@@ -902,6 +909,8 @@
|
||||
|
||||
"@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="],
|
||||
|
||||
"@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="],
|
||||
|
||||
"@supabase/auth-js": ["@supabase/auth-js@2.68.0", "", { "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "sha512-odG7nb7aOmZPUXk6SwL2JchSsn36Ppx11i2yWMIc/meUO2B2HK9YwZHPK06utD9Ql9ke7JKDbwGin/8prHKxxQ=="],
|
||||
|
||||
"@supabase/functions-js": ["@supabase/functions-js@2.4.4", "", { "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA=="],
|
||||
@@ -1380,7 +1389,7 @@
|
||||
|
||||
"camelize": ["camelize@1.0.1", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="],
|
||||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001757", "", {}, "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ=="],
|
||||
|
||||
"canvas": ["canvas@3.1.0", "", { "dependencies": { "node-addon-api": "^7.0.0", "prebuild-install": "^7.1.1" } }, "sha512-tTj3CqqukVJ9NgSahykNwtGda7V33VLObwrHfzT0vqJXu7J4d4C/7kQQW3fOEGDfZZoILPut5H00gOjyttPGyg=="],
|
||||
|
||||
@@ -1574,13 +1583,13 @@
|
||||
|
||||
"dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="],
|
||||
|
||||
"dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
|
||||
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||
|
||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||
|
||||
"domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="],
|
||||
|
||||
"domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="],
|
||||
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||
|
||||
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
|
||||
|
||||
@@ -1656,6 +1665,8 @@
|
||||
|
||||
"es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
|
||||
|
||||
"es6-promise": ["es6-promise@4.2.8", "", {}, "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="],
|
||||
|
||||
"es7-shim": ["es7-shim@6.0.0", "", { "dependencies": { "array-includes": "^3.0.2", "object.entries": "^1.0.3", "object.getownpropertydescriptors": "^2.0.2", "object.values": "^1.0.3", "string-at": "^1.0.1", "string.prototype.padend": "^3.0.0", "string.prototype.padstart": "^3.0.0", "string.prototype.trimleft": "^2.0.0", "string.prototype.trimright": "^2.0.0" } }, "sha512-aiQ/QyJBVJbabtsSediM1S4qI+P3p8F5J5YR5o/bH003BCnnclzxK9pi5Qd2Hg01ktAtZCaQBdejHrkOBGwf5Q=="],
|
||||
|
||||
"esbuild": ["esbuild@0.25.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.0", "@esbuild/android-arm": "0.25.0", "@esbuild/android-arm64": "0.25.0", "@esbuild/android-x64": "0.25.0", "@esbuild/darwin-arm64": "0.25.0", "@esbuild/darwin-x64": "0.25.0", "@esbuild/freebsd-arm64": "0.25.0", "@esbuild/freebsd-x64": "0.25.0", "@esbuild/linux-arm": "0.25.0", "@esbuild/linux-arm64": "0.25.0", "@esbuild/linux-ia32": "0.25.0", "@esbuild/linux-loong64": "0.25.0", "@esbuild/linux-mips64el": "0.25.0", "@esbuild/linux-ppc64": "0.25.0", "@esbuild/linux-riscv64": "0.25.0", "@esbuild/linux-s390x": "0.25.0", "@esbuild/linux-x64": "0.25.0", "@esbuild/netbsd-arm64": "0.25.0", "@esbuild/netbsd-x64": "0.25.0", "@esbuild/openbsd-arm64": "0.25.0", "@esbuild/openbsd-x64": "0.25.0", "@esbuild/sunos-x64": "0.25.0", "@esbuild/win32-arm64": "0.25.0", "@esbuild/win32-ia32": "0.25.0", "@esbuild/win32-x64": "0.25.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw=="],
|
||||
@@ -1754,6 +1765,8 @@
|
||||
|
||||
"fast-loops": ["fast-loops@1.1.4", "", {}, "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg=="],
|
||||
|
||||
"fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="],
|
||||
|
||||
"fast-unique-numbers": ["fast-unique-numbers@8.0.13", "", { "dependencies": { "@babel/runtime": "^7.23.8", "tslib": "^2.6.2" } }, "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g=="],
|
||||
|
||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
||||
@@ -1940,9 +1953,11 @@
|
||||
|
||||
"html-react-parser": ["html-react-parser@1.4.12", "", { "dependencies": { "domhandler": "4.3.1", "html-dom-parser": "1.2.0", "react-property": "2.0.0", "style-to-js": "1.1.0" }, "peerDependencies": { "react": "0.14 || 15 || 16 || 17 || 18" } }, "sha512-nqYQzr4uXh67G9ejAG7djupTHmQvSTgjY83zbXLRfKHJ0F06751jXx6WKSFARDdXxCngo2/7H4Rwtfeowql4gQ=="],
|
||||
|
||||
"html-to-text": ["html-to-text@9.0.5", "", { "dependencies": { "@selderee/plugin-htmlparser2": "^0.11.0", "deepmerge": "^4.3.1", "dom-serializer": "^2.0.0", "htmlparser2": "^8.0.2", "selderee": "^0.11.0" } }, "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg=="],
|
||||
|
||||
"html-tokenize": ["html-tokenize@2.0.1", "", { "dependencies": { "buffer-from": "~0.1.1", "inherits": "~2.0.1", "minimist": "~1.2.5", "readable-stream": "~1.0.27-1", "through2": "~0.4.1" }, "bin": { "html-tokenize": "bin/cmd.js" } }, "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w=="],
|
||||
|
||||
"htmlparser2": ["htmlparser2@7.2.0", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.2", "domutils": "^2.8.0", "entities": "^3.0.1" } }, "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog=="],
|
||||
"htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="],
|
||||
|
||||
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
||||
|
||||
@@ -2170,6 +2185,8 @@
|
||||
|
||||
"language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
|
||||
|
||||
"leac": ["leac@0.6.0", "", {}, "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg=="],
|
||||
|
||||
"leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
@@ -2504,6 +2521,8 @@
|
||||
|
||||
"parse-svg-path": ["parse-svg-path@0.1.2", "", {}, "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="],
|
||||
|
||||
"parseley": ["parseley@0.12.1", "", { "dependencies": { "leac": "^0.6.0", "peberminta": "^0.9.0" } }, "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw=="],
|
||||
|
||||
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
|
||||
|
||||
"password-prompt": ["password-prompt@1.1.3", "", { "dependencies": { "ansi-escapes": "^4.3.2", "cross-spawn": "^7.0.3" } }, "sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw=="],
|
||||
@@ -2530,6 +2549,8 @@
|
||||
|
||||
"pdfjs-dist": ["pdfjs-dist@4.10.38", "", { "optionalDependencies": { "@napi-rs/canvas": "^0.1.65" } }, "sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ=="],
|
||||
|
||||
"peberminta": ["peberminta@0.9.0", "", {}, "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ=="],
|
||||
|
||||
"peerjs": ["peerjs@1.5.4", "", { "dependencies": { "@msgpack/msgpack": "^2.8.0", "eventemitter3": "^4.0.7", "peerjs-js-binarypack": "^2.1.0", "webrtc-adapter": "^9.0.0" } }, "sha512-yFsoLMnurJKlQbx6kVSBpOp+AlNldY1JQS2BrSsHLKCZnq6t7saHleuHM5svuLNbQkUJXHLF3sKOJB1K0xulOw=="],
|
||||
|
||||
"peerjs-js-binarypack": ["peerjs-js-binarypack@2.1.0", "", {}, "sha512-YIwCC+pTzp3Bi8jPI9UFKO0t0SLo6xALnHkiNt/iUFmUUZG0fEEmEyFKvjsDKweiFitzHRyhuh6NvyJZ4nNxMg=="],
|
||||
@@ -2578,7 +2599,7 @@
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.5.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg=="],
|
||||
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||
|
||||
"pretty-bytes": ["pretty-bytes@5.6.0", "", {}, "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg=="],
|
||||
|
||||
@@ -2656,6 +2677,8 @@
|
||||
|
||||
"qrcode-terminal": ["qrcode-terminal@0.11.0", "", { "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ=="],
|
||||
|
||||
"querystringify": ["querystringify@2.2.0", "", {}, "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="],
|
||||
|
||||
"queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="],
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
@@ -2770,6 +2793,10 @@
|
||||
|
||||
"requireg": ["requireg@0.2.2", "", { "dependencies": { "nested-error-stacks": "~2.0.1", "rc": "~1.2.7", "resolve": "~1.7.1" } }, "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg=="],
|
||||
|
||||
"requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="],
|
||||
|
||||
"resend": ["resend@6.4.2", "", { "dependencies": { "svix": "1.76.1" }, "peerDependencies": { "@react-email/render": "*" }, "optionalPeers": ["@react-email/render"] }, "sha512-YnxmwneltZtjc7Xff+8ZjG1/xPLdstCiqsedgO/JxWTf7vKRAPCx6CkhQ3ZXskG0mrmf8+I5wr/wNRd8PQMUfw=="],
|
||||
|
||||
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
|
||||
|
||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||
@@ -2818,6 +2845,8 @@
|
||||
|
||||
"sdp": ["sdp@3.2.0", "", {}, "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="],
|
||||
|
||||
"selderee": ["selderee@0.11.0", "", { "dependencies": { "parseley": "^0.12.0" } }, "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA=="],
|
||||
|
||||
"selfsigned": ["selfsigned@2.4.1", "", { "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" } }, "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q=="],
|
||||
|
||||
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
||||
@@ -2992,6 +3021,8 @@
|
||||
|
||||
"svg-arc-to-cubic-bezier": ["svg-arc-to-cubic-bezier@3.2.0", "", {}, "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g=="],
|
||||
|
||||
"svix": ["svix@1.76.1", "", { "dependencies": { "@stablelib/base64": "^1.0.0", "@types/node": "^22.7.5", "es6-promise": "^4.2.8", "fast-sha256": "^1.3.0", "url-parse": "^1.5.10", "uuid": "^10.0.0" } }, "sha512-CRuDWBTgYfDnBLRaZdKp9VuoPcNUq9An14c/k+4YJ15Qc5Grvf66vp0jvTltd4t7OIRj+8lM1DAgvSgvf7hdLw=="],
|
||||
|
||||
"swr": ["swr@2.3.2", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-RosxFpiabojs75IwQ316DGoDRmOqtiAj0tg8wCcbEu4CiLZBs/a9QNtHV7TUfDXmmlgqij/NqzKq/eLelyv9xA=="],
|
||||
|
||||
"tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="],
|
||||
@@ -3106,7 +3137,7 @@
|
||||
|
||||
"undici": ["undici@6.21.1", "", {}, "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ=="],
|
||||
|
||||
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="],
|
||||
|
||||
@@ -3140,6 +3171,8 @@
|
||||
|
||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||
|
||||
"url-parse": ["url-parse@1.5.10", "", { "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="],
|
||||
|
||||
"use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
|
||||
|
||||
"use-composed-ref": ["use-composed-ref@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w=="],
|
||||
@@ -3430,6 +3463,8 @@
|
||||
|
||||
"@react-pdf/types/@react-pdf/stylesheet": ["@react-pdf/stylesheet@6.0.0", "", { "dependencies": { "@react-pdf/fns": "3.1.1", "@react-pdf/types": "^2.8.0", "color-string": "^1.9.1", "hsl-to-hex": "^1.0.0", "media-engine": "^1.0.3", "postcss-value-parser": "^4.1.0" } }, "sha512-uAwuMjbcEaxhRl7tGlqxAbLzo/KoYr6v9JksUJwgzd+rkvAp8jDq8NcG3sUp88tzgIyyRjBGl4FewgdxbAa2uw=="],
|
||||
|
||||
"@selderee/plugin-htmlparser2/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
@@ -3440,6 +3475,8 @@
|
||||
|
||||
"ast-types/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||
|
||||
"babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
|
||||
@@ -3448,6 +3485,8 @@
|
||||
|
||||
"blessed-contrib/strip-ansi": ["strip-ansi@3.0.1", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="],
|
||||
|
||||
"browserslist/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||
|
||||
"cacache/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||
|
||||
"caller-callsite/callsites": ["callsites@2.0.0", "", {}, "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ=="],
|
||||
@@ -3478,7 +3517,9 @@
|
||||
|
||||
"defaults/clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
|
||||
|
||||
"dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
|
||||
"dom-serializer/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"domutils/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"drawille-canvas-blessed-contrib/gl-matrix": ["gl-matrix@2.8.1", "", {}, "sha512-0YCjVpE3pS5XWlN3J4X7AiAx65+nqAI54LndtVFnQZB6G/FVLkZH8y8V6R3cIoOQR4pUdfwQGd1iwyoXHJ4Qfw=="],
|
||||
|
||||
@@ -3548,9 +3589,11 @@
|
||||
|
||||
"has-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="],
|
||||
|
||||
"html-dom-parser/htmlparser2": ["htmlparser2@7.2.0", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.2", "domutils": "^2.8.0", "entities": "^3.0.1" } }, "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog=="],
|
||||
|
||||
"html-tokenize/readable-stream": ["readable-stream@1.0.34", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg=="],
|
||||
|
||||
"htmlparser2/entities": ["entities@3.0.1", "", {}, "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q=="],
|
||||
"htmlparser2/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"hyperid/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||
|
||||
@@ -3602,12 +3645,16 @@
|
||||
|
||||
"minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||
|
||||
"next/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||
|
||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||
|
||||
"next-dev/@mantine/hooks": ["@mantine/hooks@7.17.0", "", { "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-vo3K49mLy1nJ8LQNb5KDbJgnX0xwt3Y8JOF3ythjB5LEFMptdLSSgulu64zj+QHtzvffFCsMb05DbTLLpVP/JQ=="],
|
||||
|
||||
"next-dev/axios": ["axios@1.8.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g=="],
|
||||
|
||||
"next-dev/prettier": ["prettier@3.5.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg=="],
|
||||
|
||||
"next-dev/react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="],
|
||||
|
||||
"next-dev/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="],
|
||||
@@ -3726,6 +3773,10 @@
|
||||
|
||||
"sucrase/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||
|
||||
"svix/@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
|
||||
|
||||
"svix/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
|
||||
|
||||
"tar/fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
||||
|
||||
"tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
||||
@@ -3922,6 +3973,10 @@
|
||||
|
||||
"fontkit/@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"html-dom-parser/htmlparser2/domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="],
|
||||
|
||||
"html-dom-parser/htmlparser2/entities": ["entities@3.0.1", "", {}, "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q=="],
|
||||
|
||||
"html-tokenize/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="],
|
||||
|
||||
"lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||
@@ -3958,6 +4013,8 @@
|
||||
|
||||
"onnxruntime-node/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||
|
||||
"openai/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||
|
||||
"ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
|
||||
|
||||
"ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
|
||||
@@ -4024,6 +4081,8 @@
|
||||
|
||||
"wibu/next/@swc/helpers": ["@swc/helpers@0.5.5", "", { "dependencies": { "@swc/counter": "^0.1.3", "tslib": "^2.4.0" } }, "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A=="],
|
||||
|
||||
"wibu/next/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||
|
||||
"wibu/next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||
|
||||
"wibu/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
|
||||
@@ -4058,6 +4117,8 @@
|
||||
|
||||
"execa/cross-spawn/shebang-command/shebang-regex": ["shebang-regex@1.0.0", "", {}, "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="],
|
||||
|
||||
"html-dom-parser/htmlparser2/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
|
||||
|
||||
"log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
|
||||
|
||||
"log-symbols/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
|
||||
@@ -4098,6 +4159,8 @@
|
||||
|
||||
"eslint-config-next/@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||
|
||||
"html-dom-parser/htmlparser2/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
|
||||
|
||||
"log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||
|
||||
"onnxruntime-node/tar/minizlib/rimraf/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hipmi",
|
||||
"version": "1.5.8",
|
||||
"version": "1.5.24",
|
||||
"private": true,
|
||||
"prisma": {
|
||||
"seed": "bun prisma/seed.ts"
|
||||
@@ -29,6 +29,7 @@
|
||||
"@mantine/notifications": "^6.0.17",
|
||||
"@mantine/tiptap": "^7.5.3",
|
||||
"@prisma/client": "^6.3.0",
|
||||
"@react-email/render": "^2.0.0",
|
||||
"@react-pdf/renderer": "^3.4.4",
|
||||
"@tabler/icons-react": "^3.31.0",
|
||||
"@tiptap/extension-highlight": "^2.2.3",
|
||||
@@ -51,6 +52,7 @@
|
||||
"autoprefixer": "10.4.14",
|
||||
"bufferutil": "^4.0.8",
|
||||
"bun": "^1.1.38",
|
||||
"caniuse-lite": "^1.0.30001757",
|
||||
"colors": "^1.4.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"dayjs": "^1.11.10",
|
||||
@@ -90,6 +92,7 @@
|
||||
"react-quill": "^2.0.0",
|
||||
"react-responsive-carousel": "^3.2.23",
|
||||
"react-toastify": "^9.1.3",
|
||||
"resend": "^6.4.2",
|
||||
"sharp": "^0.33.5",
|
||||
"socket.io-client": "^4.7.2",
|
||||
"swr": "^2.3.0",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Donasi_Invoice" ALTER COLUMN "masterBankId" SET DEFAULT 'null';
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "termsOfServiceAccepted" BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -0,0 +1,35 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "BlockedUser" (
|
||||
"id" TEXT NOT NULL,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"blockerId" TEXT NOT NULL,
|
||||
"blockedId" TEXT NOT NULL,
|
||||
"menuFeatureId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "BlockedUser_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MenuFeature" (
|
||||
"id" TEXT NOT NULL,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "MenuFeature_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BlockedUser_blockerId_blockedId_key" ON "BlockedUser"("blockerId", "blockedId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_menuFeatureId_fkey" FOREIGN KEY ("menuFeatureId") REFERENCES "MenuFeature"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_blockerId_fkey" FOREIGN KEY ("blockerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_blockedId_fkey" FOREIGN KEY ("blockedId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the `MenuFeature` table. If the table is not empty, all the data it contains will be lost.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "BlockedUser" DROP CONSTRAINT "BlockedUser_menuFeatureId_fkey";
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "MenuFeature";
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_menuFeatureId_fkey" FOREIGN KEY ("menuFeatureId") REFERENCES "MasterKategoriApp"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "acceptedForumTermsAt" TIMESTAMP(3),
|
||||
ADD COLUMN "acceptedTermsAt" TIMESTAMP(3);
|
||||
@@ -49,8 +49,15 @@ model User {
|
||||
BusinessMaps BusinessMaps[]
|
||||
Investasi_Invoice Investasi_Invoice[]
|
||||
|
||||
EventSponsor EventSponsor[]
|
||||
EventTransaksi EventTransaksi[]
|
||||
EventSponsor EventSponsor[]
|
||||
EventTransaksi EventTransaksi[]
|
||||
termsOfServiceAccepted Boolean @default(false)
|
||||
|
||||
blockedUsers BlockedUser[] @relation("Blocking")
|
||||
blockedBy BlockedUser[] @relation("BlockedBy")
|
||||
|
||||
acceptedTermsAt DateTime?
|
||||
acceptedForumTermsAt DateTime?
|
||||
}
|
||||
|
||||
model MasterUserRole {
|
||||
@@ -1011,6 +1018,8 @@ model MasterKategoriApp {
|
||||
updatedAt DateTime @updatedAt
|
||||
name String
|
||||
value String?
|
||||
|
||||
blockedUsers BlockedUser[]
|
||||
}
|
||||
|
||||
// ======================= EVENT ======================= //
|
||||
@@ -1073,3 +1082,20 @@ model Sticker {
|
||||
|
||||
MasterEmotions MasterEmotions[] @relation("StikerEmotions")
|
||||
}
|
||||
|
||||
model BlockedUser {
|
||||
id String @id @default(uuid())
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
blockerId String // ID user yang memblokir
|
||||
blockedId String // ID user yang diblokir
|
||||
|
||||
menuFeatureId String
|
||||
menuFeature MasterKategoriApp @relation(fields: [menuFeatureId], references: [id])
|
||||
|
||||
blocker User @relation("BlockedBy", fields: [blockerId], references: [id])
|
||||
blocked User @relation("Blocking", fields: [blockedId], references: [id])
|
||||
|
||||
@@unique([blockerId, blockedId])
|
||||
}
|
||||
|
||||
1098
prisma/schema.prisma.backup
Normal file
1098
prisma/schema.prisma.backup
Normal file
File diff suppressed because it is too large
Load Diff
11
public/.well-known/apple-app-site-association
Normal file
11
public/.well-known/apple-app-site-association
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"applinks": {
|
||||
"apps": [],
|
||||
"details": [
|
||||
{
|
||||
"appID": "BMY6GT6W3D.com.anonymous.hipmi-mobile",
|
||||
"paths": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
8
public/.well-known/assetlinks.json
Normal file
8
public/.well-known/assetlinks.json
Normal file
@@ -0,0 +1,8 @@
|
||||
[{
|
||||
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||
"target": {
|
||||
"namespace": "android_app",
|
||||
"package_name": "com.bip.hipmimobileapp",
|
||||
"sha256_cert_fingerprints": ["CFF8431520BFAE665025B68138774A4E64AA6338D2DF6C7D900A71F0551FFD2D"]
|
||||
}
|
||||
}]
|
||||
BIN
public/aset/logo/hiconnect.png
Normal file
BIN
public/aset/logo/hiconnect.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 509 KiB |
301
public/privacy-policy.html
Normal file
301
public/privacy-policy.html
Normal file
@@ -0,0 +1,301 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Privacy Policy</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 900px;
|
||||
margin: 40px auto;
|
||||
padding: 20px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.last-updated {
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
a {
|
||||
color: #0066cc;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.summary-box {
|
||||
background-color: #faf8e8;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin: 25px 0;
|
||||
}
|
||||
.summary-box h3 {
|
||||
margin-top: 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
address {
|
||||
margin-top: 15px;
|
||||
font-style: normal;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Privacy Policy</h1>
|
||||
<div class="last-updated">Last updated November 06, 2025</div>
|
||||
|
||||
<p>This Privacy Notice for Bali Interaktif Perkasa ("<strong>we</strong>", "<strong>us</strong>", or "<strong>our</strong>"), describes how and why we might access, collect, store, use, and/or share ("<strong>process</strong>") your personal information when you use our services ("<strong>Services</strong>"), including when you:</p>
|
||||
|
||||
<ul>
|
||||
<li>Download and use our mobile application (HIPMI Badung Connect), or any other application of ours that links to this Privacy Notice</li>
|
||||
|
||||
<li>Use HIPMI Badung Connect. HIPMI Badung Connect is an official digital platform developed to support the network of members of HIPMI (Himpunan Pengusaha Muda Indonesia – Indonesian Young Entrepreneurs Association) in Badung Regency. The app aims to strengthen collaboration, partnerships, and the business ecosystem among young entrepreneurs through a range of interactive and informative features. Key features of the app include:
|
||||
<ul style="list-style-type: none; padding-left: 0;">
|
||||
<li><strong>Profile:</strong> Displays users’ personal and professional background as HIPMI Badung members.</li>
|
||||
<li><strong>Business Portfolio:</strong> Allows users to showcase their business name, business information, and associated social media links.</li>
|
||||
<li><strong>User Search:</strong> Enables members to discover and connect with other users based on specific criteria.</li>
|
||||
<li><strong>Events:</strong> Provides information and registration for business events, seminars, workshops, and HIPMI Badung community activities.</li>
|
||||
<li><strong>Voting:</strong> Supports internal organizational decision-making through a digital voting system.</li>
|
||||
<li><strong>Collaboration Projects:</strong> Serves as a hub for initiating, managing, and participating in joint business initiatives.</li>
|
||||
<li><strong>Job Search:</strong> Offers job postings and career opportunities within the members’ business ecosystem.</li>
|
||||
<li><strong>Forum:</strong> An interactive space for members to exchange ideas, ask questions, and share solutions related to entrepreneurship.</li>
|
||||
<li><strong>Business Map (Maps):</strong> Displays the physical locations of members’ businesses to facilitate networking and in-person visits.</li>
|
||||
<li><strong>Crowdfunding:</strong> Includes two funding mechanisms—Investment (for business opportunities offering returns) and Donation (for social support with no expectation of return).</li>
|
||||
</ul>
|
||||
This app is designed to uphold user data integrity while promoting transparency, collaboration, and sustainable economic growth among young entrepreneurs in Badung. All personal and business information collected through the app is used solely to enable core functionalities and is managed in accordance with applicable privacy policies.
|
||||
</li>
|
||||
|
||||
<li>Engage with us in other related ways, including any sales, marketing, or events</li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Questions or concerns?</strong> Reading this Privacy Notice will help you understand your privacy rights and choices. We are responsible for making decisions about how your personal information is processed. If you do not agree with our policies and practices, please do not use our Services. If you still have any questions or concerns, please contact us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a>.</p>
|
||||
|
||||
<!-- SUMMARY OF KEY POINTS -->
|
||||
<div class="summary-box">
|
||||
<h3>Summary of Key Points</h3>
|
||||
<p>This summary provides key points from our Privacy Notice, but you can find out more details about any of these topics by using the table of contents below.</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>What personal information do we process?</strong> We may process personal information depending on how you interact with us and the Services, the choices you make, and the products and features you use.</li>
|
||||
<li><strong>Do we process any sensitive personal information?</strong> We do not process sensitive personal information.</li>
|
||||
<li><strong>Do we collect any information from third parties?</strong> We do not collect any information from third parties.</li>
|
||||
<li><strong>How do we process your information?</strong> To provide, improve, and administer our Services; communicate with you; for security and fraud prevention; and to comply with law.</li>
|
||||
<li><strong>In what situations and with which parties do we share personal information?</strong> We may share information in specific situations and with specific third parties.</li>
|
||||
<li><strong>How do we keep your information safe?</strong> We have adequate organizational and technical processes in place to protect your personal information.</li>
|
||||
<li><strong>What are your rights?</strong> Depending on where you are located geographically, you may have certain rights regarding your personal information.</li>
|
||||
<li><strong>How do you exercise your rights?</strong> By submitting a data subject access request, or by contacting us.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- TABLE OF CONTENTS -->
|
||||
<h3>Table of Contents</h3>
|
||||
<ol>
|
||||
<li><a href="#section1">WHAT INFORMATION DO WE COLLECT?</a></li>
|
||||
<li><a href="#section2">HOW DO WE PROCESS YOUR INFORMATION?</a></li>
|
||||
<li><a href="#section3">WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?</a></li>
|
||||
<li><a href="#section4">DO WE USE COOKIES AND OTHER TRACKING TECHNOLOGIES?</a></li>
|
||||
<li><a href="#section5">HOW LONG DO WE KEEP YOUR INFORMATION?</a></li>
|
||||
<li><a href="#section6">HOW DO WE KEEP YOUR INFORMATION SAFE?</a></li>
|
||||
<li><a href="#section7">DO WE COLLECT INFORMATION FROM MINORS?</a></li>
|
||||
<li><a href="#section8">WHAT ARE YOUR PRIVACY RIGHTS?</a></li>
|
||||
<li><a href="#section9">CONTROLS FOR DO-NOT-TRACK FEATURES</a></li>
|
||||
<li><a href="#section10">DO WE MAKE UPDATES TO THIS NOTICE?</a></li>
|
||||
<li><a href="#section11">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a></li>
|
||||
<li><a href="#section12">HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?</a></li>
|
||||
</ol>
|
||||
|
||||
<!-- SECTION 1 -->
|
||||
<div id="section1" class="section-title">1. WHAT INFORMATION DO WE COLLECT?</div>
|
||||
<h4>Personal information you disclose to us</h4>
|
||||
<p><em>In Short:</em> We collect personal information that you provide to us.</p>
|
||||
<p>We collect personal information that you voluntarily provide to us when you register on the Services, express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us.</p>
|
||||
<h4>Personal Information Provided by You.</h4>
|
||||
<p>The personal information that we collect depends on the context of your interactions with us and the Services, the choices you make, and the products and features you use. The personal information we collect may include the following:</p>
|
||||
<ul>
|
||||
<li>names</li>
|
||||
<li>phone numbers</li>
|
||||
<li>email addresses</li>
|
||||
<li>usernames</li>
|
||||
</ul>
|
||||
<h4>Sensitive Information.</h4>
|
||||
<p>We do not process sensitive information.</p>
|
||||
<h4>Application Data.</h4>
|
||||
<p>If you use our application(s), we also may collect the following information if you choose to provide us with access or permission:</p>
|
||||
<ul>
|
||||
<li><strong>Geolocation Information.</strong> We may request access or permission to track location-based information from your mobile device, either continuously or while you are using our mobile application(s), to provide certain location-based services. If you wish to change our access or permissions, you may do so in your device's settings.</li>
|
||||
<li><strong>Mobile Device Data.</strong> We automatically collect device information (such as your mobile device ID, model, and manufacturer), operating system, version information and system configuration information, device and application identification numbers, browser type and version, hardware model Internet service provider and/or mobile carrier, and Internet Protocol (IP) address (or proxy server). If you are using our application(s), we may also collect information about the phone network associated with your mobile device, your mobile device’s operating system or platform, the type of mobile device you use, your mobile device’s unique device ID, and information about the features of our application(s) you accessed.</li>
|
||||
<li><strong>Push Notifications.</strong> We may request to send you push notifications regarding your account or certain features of the application(s). If you wish to opt out from receiving these types of communications, you may turn them off in your device's settings.</li>
|
||||
</ul>
|
||||
<p>This information is primarily needed to maintain the security and operation of our application(s), for troubleshooting, and for our internal analytics and reporting purposes.</p>
|
||||
<p>All personal information that you provide to us must be true, complete, and accurate, and you must notify us of any changes to such personal information.</p>
|
||||
<h4>Information automatically collected</h4>
|
||||
<p><em>In Short:</em> Some information — such as your Internet Protocol (IP) address and/or browser and device characteristics — is collected automatically when you visit our Services.</p>
|
||||
<p>We automatically collect certain information when you visit, use, or navigate the Services. This information does not reveal your specific identity (like your name or contact information) but may include device and usage information, such as your IP address, browser and device characteristics, operating system, language preferences, referring URLs, device name, country, location, information about how and when you use our Services, and other technical information. This information is primarily needed to maintain the security and operation of our Services, and for our internal analytics and reporting purposes.</p>
|
||||
<p>Like many businesses, we also collect information through cookies and similar technologies.</p>
|
||||
<h4>The information we collect includes:</h4>
|
||||
<ul>
|
||||
<li><strong>Log and Usage Data.</strong> Log and usage data is service-related, diagnostic, usage, and performance information our servers automatically collect when you access or use our Services and which we record in log files. Depending on how you interact with us, this log data may include your IP address, device information, browser type, and settings and information about your activity in the Services (such as the date/time stamps associated with your usage, pages and files viewed, searches, and other actions you take such as which features you use), device event information (such as system activity, error reports (sometimes called "crash dumps"), and hardware settings).</li>
|
||||
<li><strong>Device Data.</strong> We collect device data such as information about your computer, phone, tablet, or other device you use to access the Services. Depending on the device used, this device data may include information such as your IP address (or proxy server), device and application identification numbers, location, browser type, hardware model, Internet service provider and/or mobile carrier, operating system, and system configuration information.</li>
|
||||
<li><strong>Location Data.</strong> We collect location data such as information about your device's location, which can be either precise or imprecise. How much information we collect depends on the type and settings of the device you use to access the Services. For example, we may use GPS and other technologies to collect geolocation data that tells us your current location (based on your IP address). You can opt out of allowing us to collect this information either by refusing access to the information or by disabling your Location setting on your device. However, if you choose to opt out, you may not be able to use certain aspects of the Services.</li>
|
||||
</ul>
|
||||
<h4>Google API</h4>
|
||||
<p>Our use of information received from Google APIs will adhere to <a href="https://developers.google.com/terms/api-services-user-data-policy" target="_blank">Google API Services User Data Policy</a>, including the <a href="https://developers.google.com/terms/api-services-user-data-policy#limited-use" target="_blank">Limited Use requirements</a>.</p>
|
||||
|
||||
<!-- SECTION 2 -->
|
||||
<div id="section2" class="section-title">2. HOW DO WE PROCESS YOUR INFORMATION?</div>
|
||||
<p><em>In Short:</em> We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent.</p>
|
||||
<p>We process your personal information for a variety of reasons, depending on how you interact with our Services, including:</p>
|
||||
<ul>
|
||||
<li><strong>To facilitate account creation and authentication and otherwise manage user accounts.</strong> We may process your information so you can create and log in to your account, as well as keep your account in working order.</li>
|
||||
<li><strong>To deliver and facilitate delivery of services to the user.</strong> We may process your information to provide you with the requested service.</li>
|
||||
<li><strong>To respond to user inquiries/offer support to users.</strong> We may process your information to respond to your inquiries and solve any potential issues you might have with the requested service.</li>
|
||||
<li><strong>To send administrative information to you.</strong> We may process your information to send you details about our products and services, changes to our terms and policies, and other similar information.</li>
|
||||
<li><strong>To enable user-to-user communications.</strong> We may process your information if you choose to use any of our offerings that allow for communication with another user.</li>
|
||||
<li><strong>To request feedback.</strong> We may process your information when necessary to request feedback and to contact you about your use of our Services.</li>
|
||||
<li><strong>To send you marketing and promotional communications.</strong> We may process the personal information you send to us for our marketing purposes, if this is in accordance with your marketing preferences. You can opt out of our marketing emails at any time. For more information, see "<a href="#section8">WHAT ARE YOUR PRIVACY RIGHTS?</a>" below.</li>
|
||||
<li><strong>To protect our Services.</strong> We may process your information as part of our efforts to keep our Services safe and secure, including fraud monitoring and prevention.</li>
|
||||
<li><strong>To evaluate and improve our Services, products, marketing, and your experience.</strong> We may process your information when we believe it is necessary to identify usage trends, determine the effectiveness of our promotional campaigns, and to evaluate and improve our Services, products, marketing, and your experience.</li>
|
||||
<li><strong>To identify usage trends.</strong> We may process information about how you use our Services to better understand how they are being used so we can improve them.</li>
|
||||
</ul>
|
||||
|
||||
<!-- SECTION 3 -->
|
||||
<div id="section3" class="section-title">3. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?</div>
|
||||
<p><em>In Short:</em> We may share information in specific situations described in this section and/or with the following third parties.</p>
|
||||
<h4>Vendors, Consultants, and Other Third-Party Service Providers.</h4>
|
||||
<p>We may share your data with third-party vendors, service providers, contractors, or agents (“<strong>third parties</strong>”) who perform services for us or on our behalf and require access to such information to do that work. We have contracts in place with our third parties, which are designed to help safeguard your personal information. This means that they cannot do anything with your personal information unless we have instructed them to do it. They will also not share your personal information with any organization apart from us. They also commit to protect the data they hold on our behalf and to retain it for the period we instruct.</p>
|
||||
<p>The third parties we may share personal information with are as follows:</p>
|
||||
<ul>
|
||||
<li><strong>Cloud Computing Services</strong>
|
||||
<ul style="list-style-type: none; padding-left: 15px;">
|
||||
<li>Google Cloud Platform</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Functionality and Infrastructure Optimization</strong>
|
||||
<ul style="list-style-type: none; padding-left: 15px;">
|
||||
<li>Firebase Realtime Database</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Web and Mobile Analytics</strong>
|
||||
<ul style="list-style-type: none; padding-left: 15px;">
|
||||
<li>Google Analytics for Firebase</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Website Performance Monitoring</strong>
|
||||
<ul style="list-style-type: none; padding-left: 15px;">
|
||||
<li>Firebase Crash Reporting</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Website Testing</strong>
|
||||
<ul style="list-style-type: none; padding-left: 15px;">
|
||||
<li>Google Play Console and TestFlight</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>We also may need to share your personal information in the following situations:</p>
|
||||
<ul>
|
||||
<li><strong>Business Transfers.</strong> We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company.</li>
|
||||
<li><strong>When we use Google Maps Platform APIs.</strong> We may share your information with certain Google Maps Platform APIs (e.g., Google Maps API, Places API). Google Maps uses GPS, Wi-Fi, and cell towers to estimate your location. GPS is accurate to about 20 meters, while Wi-Fi and cell towers help improve accuracy when GPS signals are weak, like indoors. This data helps Google Maps provide directions, but it is not always perfectly precise. We obtain and store on your device (“cache”) your location. You may revoke your consent anytime by contacting us at the contact details provided at the end of this document.</li>
|
||||
<li><strong>Business Partners.</strong> We may share your information with our business partners to offer you certain products, services, or promotions.</li>
|
||||
<li><strong>Other Users.</strong> When you share personal information (for example, by posting comments, contributions, or other content to the Services) or otherwise interact with public areas of the Services, such personal information may be viewed by all users and may be publicly made available outside the Services in perpetuity. Similarly, other users will be able to view descriptions of your activity, communicate with you within our Services, and view your profile.</li>
|
||||
</ul>
|
||||
|
||||
<!-- SECTION 4 -->
|
||||
<div id="section4" class="section-title">4. DO WE USE COOKIES AND OTHER TRACKING TECHNOLOGIES?</div>
|
||||
<p><em>In Short:</em> We may use cookies and other tracking technologies to collect and store your information.</p>
|
||||
<p>We may use cookies and similar tracking technologies (like web beacons and pixels) to gather information when you interact with our Services. Some online tracking technologies help us maintain the security of our Services and your account, prevent crashes, fix bugs, save your preferences, and assist with basic site functions.</p>
|
||||
<p>We also permit third parties and service providers to use online tracking technologies on our Services for analytics and advertising, including to help manage and display advertisements, to tailor advertisements to your interests, or to send abandoned shopping cart reminders (depending on your communication preferences). The third parties and service providers use their technology to provide advertising about products and services tailored to your interests which may appear either on our Services or on other websites.</p>
|
||||
<p>Specific information about how we use such technologies and how you can refuse certain cookies is set out in our Cookie Notice.</p>
|
||||
<h4>Google Analytics</h4>
|
||||
<p>We may share your information with Google Analytics to track and analyze the use of the Services. To opt out of being tracked by Google Analytics across the Services, visit <a href="https://tools.google.com/dlpage/gaoptout" target="_blank">https://tools.google.com/dlpage/gaoptout</a>. For more information on the privacy practices of Google, please visit the <a href="https://policies.google.com/privacy" target="_blank">Google Privacy & Terms page</a>.</p>
|
||||
|
||||
<!-- SECTION 5 -->
|
||||
<div id="section5" class="section-title">5. HOW LONG DO WE KEEP YOUR INFORMATION?</div>
|
||||
<p><em>In Short:</em> We keep your information for as long as necessary to fulfill the purposes outlined in this Privacy Notice unless otherwise required by law.</p>
|
||||
<p>We will only keep your personal information for as long as it is necessary for the purposes set out in this Privacy Notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements). No purpose in this notice will require us keeping your personal information for longer than the period of time in which users have an account with us.</p>
|
||||
<p>When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymize such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible.</p>
|
||||
|
||||
<!-- SECTION 6 -->
|
||||
<div id="section6" class="section-title">6. HOW DO WE KEEP YOUR INFORMATION SAFE?</div>
|
||||
<p><em>In Short:</em> We aim to protect your personal information through a system of organizational and technical security measures.</p>
|
||||
<p>We have implemented appropriate and reasonable technical and organizational security measures designed to protect the security of any personal information we process. However, despite our safeguards and efforts to secure your information, no electronic transmission over the Internet or information storage technology can be guaranteed to be 100% secure, so we cannot promise or guarantee that hackers, cybercriminals, or other unauthorized third parties will not be able to defeat our security and improperly collect, access, steal, or modify your information. Although we will do our best to protect your personal information, transmission of personal information to and from our Services is at your own risk. You should only access the Services within a secure environment.</p>
|
||||
|
||||
<!-- SECTION 7 -->
|
||||
<div id="section7" class="section-title">7. DO WE COLLECT INFORMATION FROM MINORS?</div>
|
||||
<p><em>In Short:</em> We do not knowingly collect data from or market to minors.</p>
|
||||
<p>HIPMI Badung Connect is not intended for use by individuals under the age of 18. We do not knowingly collect personal information from children under 18. If we become aware that we have inadvertently collected such information, we will take steps to delete it as soon as possible.</p>
|
||||
|
||||
<!-- SECTION 8 -->
|
||||
<div id="section8" class="section-title">8. WHAT ARE YOUR PRIVACY RIGHTS?</div>
|
||||
<p><em>In Short:</em> You may review, change, or terminate your account at any time, depending on your country, province, or state of residence.</p>
|
||||
<h4>Withdrawing your consent:</h4>
|
||||
<p>If we are relying on your consent to process your personal information, which may be express and/or implied consent depending on the applicable law, you have the right to withdraw your consent at any time. You can withdraw your consent at any time by contacting us by using the contact details provided in the section "<a href="#section11">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a>" below.</p>
|
||||
<p>However, please note that this will not affect the lawfulness of the processing before its withdrawal nor, when applicable law allows, will it affect the processing of your personal information conducted in reliance on lawful processing grounds other than consent.</p>
|
||||
<h4>Opting out of marketing and promotional communications:</h4>
|
||||
<p>You can unsubscribe from our marketing and promotional communications at any time by clicking on the unsubscribe link in the emails that we send, or by contacting us using the details provided in the section "<a href="#section11">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a>" below. You will then be removed from the marketing lists. However, we may still communicate with you — for example, to send you service-related messages that are necessary for the administration and use of your account, to respond to service requests, or for other non-marketing purposes.</p>
|
||||
<h4>Account Information</h4>
|
||||
<p>If you would at any time like to review or change the information in your account or terminate your account, you can:</p>
|
||||
<ul>
|
||||
<li>Log in to your account settings and update your user account.</li>
|
||||
<li>Contact us using the contact information provided.</li>
|
||||
<li><a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a></li>
|
||||
</ul>
|
||||
<p>Upon your request to terminate your account, we will deactivate or delete your account and information from our active databases. However, we may retain some information in our files to prevent fraud, troubleshoot problems, assist with any investigations, enforce our legal terms and/or comply with applicable legal requirements.</p>
|
||||
<h4>Cookies and similar technologies:</h4>
|
||||
<p>Most Web browsers are set to accept cookies by default. If you prefer, you can usually choose to set your browser to remove cookies and to reject cookies. If you choose to remove cookies or reject cookies, this could affect certain features or services of our Services.</p>
|
||||
<p>If you have questions or comments about your privacy rights, you may email us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a>.</p>
|
||||
|
||||
<!-- SECTION 9 -->
|
||||
<div id="section9" class="section-title">9. CONTROLS FOR DO-NOT-TRACK FEATURES</div>
|
||||
<p>Most web browsers and some mobile operating systems and mobile applications include a Do-Not-Track ("DNT") feature or setting you can activate to signal your privacy preference not to have data about your online browsing activities monitored and collected. At this stage, no uniform technology standard for recognizing and implementing DNT signals has been finalized. As such, we do not currently respond to DNT browser signals or any other mechanism that automatically communicates your choice not to be tracked online. If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of this Privacy Notice.</p>
|
||||
|
||||
<!-- SECTION 10 -->
|
||||
<div id="section10" class="section-title">10. DO WE MAKE UPDATES TO THIS NOTICE?</div>
|
||||
<p><em>In Short:</em> Yes, we will update this notice as necessary to stay compliant with relevant laws.</p>
|
||||
<p>We may update this Privacy Notice from time to time. The updated version will be indicated by an updated "Revised" date at the top of this Privacy Notice. If we make material changes to this Privacy Notice, we may notify you either by prominently posting a notice of such changes or by directly sending you a notification. We encourage you to review this Privacy Notice frequently to be informed of how we are protecting your information.</p>
|
||||
|
||||
<!-- SECTION 11 -->
|
||||
<div id="section11" class="section-title">11. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</div>
|
||||
<p>If you have questions or comments about this notice, you may email us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a> or contact us by post at:</p>
|
||||
<address>
|
||||
Bali Interaktif Perkasa<br>
|
||||
Park23 Creative Hub, Bali Interaktif Perkasa - Private Office<br>
|
||||
Jl. Kediri 3rd Floor, Number 01 - 02, Tuban<br>
|
||||
Badung, Bali, Indonesia 80361<br>
|
||||
Indonesia
|
||||
</address>
|
||||
|
||||
<!-- SECTION 12 -->
|
||||
<div id="section12" class="section-title">12. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?</div>
|
||||
<p>You have the right to request access to the personal information we collect from you, details about how we have processed it, correct inaccuracies, or delete your personal information. You may also have the right to withdraw your consent to our processing of your personal information. These rights may be limited in some circumstances by applicable law.</p>
|
||||
<p>To make a request, please contact us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a>.</p>
|
||||
<hr style="margin: 30px 0; border: 0; border-top: 1px solid #eee;">
|
||||
<p>© 2025 Bali Interaktif Perkasa. All rights reserved.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
110
public/terms-of-service.html
Normal file
110
public/terms-of-service.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Syarat & Ketentuan - HIPMI Badung Connect</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 800px;
|
||||
margin: 40px auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
color: #1a365d;
|
||||
}
|
||||
ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Syarat & Ketentuan Penggunaan HIPMI Badung Connect</h1>
|
||||
|
||||
<p>
|
||||
Dengan menggunakan aplikasi <strong>HIPMI Badung Connect</strong> (“Aplikasi”), Anda setuju untuk mematuhi dan terikat oleh syarat dan ketentuan berikut. Jika Anda tidak setuju dengan ketentuan ini, harap jangan gunakan Aplikasi.
|
||||
</p>
|
||||
|
||||
<h2>1. Definisi</h2>
|
||||
<p>
|
||||
<strong>HIPMI Badung Connect</strong> adalah platform digital resmi untuk anggota Himpunan Pengusaha Muda Indonesia (HIPMI) Kabupaten Badung, yang bertujuan memfasilitasi jaringan, kolaborasi, dan pertumbuhan bisnis para pengusaha muda.
|
||||
</p>
|
||||
|
||||
<h2>2. Larangan Konten Tidak Pantas</h2>
|
||||
<p>
|
||||
Anda <strong>dilarang keras</strong> memposting, mengirim, membagikan, atau mengunggah konten apa pun yang mengandung:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Ujaran kebencian, diskriminasi, atau konten SARA (Suku, Agama, Ras, Antar-golongan)</li>
|
||||
<li>Pornografi, konten seksual eksplisit, atau gambar tidak senonoh</li>
|
||||
<li>Ancaman, pelecehan, bullying, atau perilaku melecehkan</li>
|
||||
<li>Informasi palsu, hoaks, spam, atau konten menyesatkan</li>
|
||||
<li>Konten ilegal, melanggar hukum, atau melanggar hak kekayaan intelektual pihak lain</li>
|
||||
<li>Promosi narkoba, perjudian, atau aktivitas ilegal lainnya</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. Tanggung Jawab Pengguna</h2>
|
||||
<p>
|
||||
Anda bertanggung jawab penuh atas setiap konten yang Anda unggah atau bagikan melalui fitur-fitur berikut:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Profil (bio, foto, portofolio)</li>
|
||||
<li>Forum diskusi</li>
|
||||
<li>Chat pribadi atau grup</li>
|
||||
<li>Lowongan kerja, investasi, dan donasi</li>
|
||||
</ul>
|
||||
<p>
|
||||
Konten yang melanggar ketentuan ini dapat dihapus kapan saja tanpa pemberitahuan.
|
||||
</p>
|
||||
|
||||
<h2>4. Tindakan terhadap Pelanggaran</h2>
|
||||
<p>
|
||||
Jika kami menerima laporan atau menemukan konten yang melanggar ketentuan ini, kami akan:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Segera menghapus konten tersebut</li>
|
||||
<li>Memberikan peringatan atau memblokir akun pengguna</li>
|
||||
<li>Dalam kasus berat, melaporkan ke pihak berwajib sesuai hukum yang berlaku</li>
|
||||
</ul>
|
||||
<p>
|
||||
Tim kami berkomitmen untuk menanggapi laporan konten tidak pantas <strong>dalam waktu 24 jam</strong>.
|
||||
</p>
|
||||
|
||||
<h2>5. Mekanisme Pelaporan</h2>
|
||||
<p>
|
||||
Anda dapat melaporkan konten atau pengguna yang mencurigakan melalui:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Tombol <strong>“Laporkan”</strong> di setiap posting forum atau pesan chat</li>
|
||||
<li>Tombol <strong>“Blokir Pengguna”</strong> di profil pengguna</li>
|
||||
</ul>
|
||||
<p>
|
||||
Setiap laporan akan ditangani secara rahasia dan segera.
|
||||
</p>
|
||||
|
||||
<h2>6. Perubahan Ketentuan</h2>
|
||||
<p>
|
||||
Kami berhak memperbarui Syarat & Ketentuan ini sewaktu-waktu. Versi terbaru akan dipublikasikan di halaman ini dengan tanggal revisi yang diperbarui.
|
||||
</p>
|
||||
|
||||
<h2>7. Kontak</h2>
|
||||
<p>
|
||||
Jika Anda memiliki pertanyaan tentang ketentuan ini, silakan hubungi kami di:
|
||||
<strong>bip.baliinteraktifperkasa@gmail.com</strong>
|
||||
</p>
|
||||
|
||||
<footer>
|
||||
<p>© 2025 Bali Interaktif Perkasa. All rights reserved.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
30
sendWhatsapp.js
Normal file
30
sendWhatsapp.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// sendWhatsapp.js
|
||||
|
||||
// --- INPUT MANUAL ---
|
||||
let phoneNumber = "6282340374412";
|
||||
const codeOtp = "3546";
|
||||
// ---------------------
|
||||
|
||||
phoneNumber = phoneNumber.replace(/\D/g, "");
|
||||
|
||||
// Format pesan
|
||||
const message =
|
||||
`HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n` +
|
||||
`>> Kode OTP anda: ${codeOtp}.`;
|
||||
|
||||
const encodedMessage = encodeURIComponent(message);
|
||||
|
||||
const waLink = `https://wa.wibudev.com/code?nom=${phoneNumber}&text=${encodedMessage}`;
|
||||
|
||||
console.log("Mengirim request ke server...\n");
|
||||
|
||||
// Jalankan HTTP GET
|
||||
fetch(waLink)
|
||||
.then(res => res.text())
|
||||
.then(data => {
|
||||
console.log("Response dari server:");
|
||||
console.log(data);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Terjadi error:", err);
|
||||
});
|
||||
153
src/app/(support)/delete-account/page.tsx
Normal file
153
src/app/(support)/delete-account/page.tsx
Normal file
@@ -0,0 +1,153 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Grid,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import Image from "next/image";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function DeleteAccount() {
|
||||
const [phoneNumber, setPhoneNumber] = useState<string>("");
|
||||
const [data, setData] = useState({
|
||||
description: "",
|
||||
});
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Hanya di client, setelah mount
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const phone = urlParams.get("phone");
|
||||
if (phone) {
|
||||
setPhoneNumber(phone);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
if (!phoneNumber) {
|
||||
return notifications.show({
|
||||
title: "Error",
|
||||
message: "Please check your phone number",
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
|
||||
if (!data.description) {
|
||||
return notifications.show({
|
||||
title: "Error",
|
||||
message: "Please fill in description with 'Delete Account'",
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
|
||||
if (data.description !== "Delete Account") {
|
||||
return notifications.show({
|
||||
title: "Error",
|
||||
message: "Please fill in description with 'Delete Account'",
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await fetch("/api/helper/delete-account", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
number: phoneNumber,
|
||||
description: data.description,
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
notifications.show({
|
||||
title: "Success",
|
||||
message: "Account will process to delete",
|
||||
color: "green",
|
||||
});
|
||||
|
||||
setData({
|
||||
description: "",
|
||||
});
|
||||
}
|
||||
|
||||
if (!result.success) {
|
||||
notifications.show({
|
||||
title: "Error",
|
||||
message: result.error || "Failed to delete account.",
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
backgroundColor: "#f5f5f5",
|
||||
padding: "20px",
|
||||
}}
|
||||
>
|
||||
<Paper withBorder shadow="md" p={"lg"}>
|
||||
<Stack align="center">
|
||||
<Image
|
||||
src="/aset/logo/hiconnect.png"
|
||||
alt="logo"
|
||||
width={100}
|
||||
height={100}
|
||||
/>
|
||||
<Title>Delete Account</Title>
|
||||
<Stack spacing={0} align="center">
|
||||
<Text align="center" fw={"lighter"}>
|
||||
To delete your account with phone number{" "}
|
||||
{phoneNumber ? `+${phoneNumber}` : ""}.
|
||||
</Text>
|
||||
<Text align="center" fw={"lighter"}>
|
||||
Type your message with subject ‘Delete Account’
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
<Grid w={"100%"}>
|
||||
<Grid.Col span={8}>
|
||||
<TextInput
|
||||
value={data.description}
|
||||
w={"100%"}
|
||||
placeholder="Type your subject here"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
description: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4}>
|
||||
<Button onClick={handlerSubmit} w={"100%"} loading={isLoading}>
|
||||
Submit
|
||||
</Button>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
202
src/app/(support)/support-center/page.tsx
Normal file
202
src/app/(support)/support-center/page.tsx
Normal file
@@ -0,0 +1,202 @@
|
||||
"use client";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
Textarea,
|
||||
TextInput,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { IconBrandGmail, IconLocation } from "@tabler/icons-react";
|
||||
import Image from "next/image";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function SupportCenter() {
|
||||
const [data, setData] = useState({
|
||||
email: "",
|
||||
title: "",
|
||||
description: "",
|
||||
});
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!data.email || !data.title || !data.description) {
|
||||
return notifications.show({
|
||||
title: "Error",
|
||||
color: "red",
|
||||
message: "Please fill in all fields.",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const response = await fetch("/api/helper/support-center", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
notifications.show({
|
||||
title: "Success",
|
||||
color: "green",
|
||||
message: "Message sent successfully.",
|
||||
});
|
||||
|
||||
setData({
|
||||
email: "",
|
||||
title: "",
|
||||
description: "",
|
||||
});
|
||||
}
|
||||
|
||||
if (!result.success) {
|
||||
notifications.show({
|
||||
title: "Error",
|
||||
color: "red",
|
||||
message: result.error || "Failed to send message.",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
backgroundColor: "#f5f5f5",
|
||||
padding: "20px",
|
||||
}}
|
||||
>
|
||||
<Stack spacing={"lg"}>
|
||||
<Stack align="center">
|
||||
<Stack spacing={"xs"} align="center">
|
||||
<Group>
|
||||
<Image
|
||||
src="/aset/logo/hiconnect.png"
|
||||
alt="logo"
|
||||
width={50}
|
||||
height={50}
|
||||
/>
|
||||
|
||||
<Title>Support Center</Title>
|
||||
</Group>
|
||||
<Text align="center">
|
||||
Send us a message and we'll get back to you as soon as possible.
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Paper style={{ padding: "20px" }} withBorder shadow="md">
|
||||
<SimpleGrid
|
||||
cols={2}
|
||||
// verticalSpacing={50}
|
||||
spacing={50}
|
||||
breakpoints={[
|
||||
{ maxWidth: "md", cols: 2, spacing: "md" },
|
||||
{ maxWidth: "sm", cols: 2, spacing: "sm" },
|
||||
{ maxWidth: "xs", cols: 1, spacing: "sm" },
|
||||
]}
|
||||
>
|
||||
<Stack>
|
||||
<Stack spacing={0}>
|
||||
<Title order={2}>Contact Information</Title>
|
||||
<Text>For general inquiries, please contact us !</Text>
|
||||
</Stack>
|
||||
<Group>
|
||||
<IconBrandGmail
|
||||
size={40}
|
||||
style={{
|
||||
backgroundColor: "gray",
|
||||
borderRadius: "10%",
|
||||
padding: "5px",
|
||||
}}
|
||||
/>
|
||||
<Stack spacing={0}>
|
||||
<Text fw={"bold"}>Email</Text>
|
||||
<Text>bip.baliinteraktifperkasa@gmail.com</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<IconLocation
|
||||
size={40}
|
||||
style={{
|
||||
backgroundColor: "gray",
|
||||
borderRadius: "10%",
|
||||
padding: "5px",
|
||||
}}
|
||||
/>
|
||||
<Stack spacing={0}>
|
||||
<Text fw={"bold"}>Location</Text>
|
||||
<Text>Bali, Indonesia</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<Title order={2}>Send a Message</Title>
|
||||
|
||||
<TextInput
|
||||
label="Email"
|
||||
placeholder="Email"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
email: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Title"
|
||||
placeholder="Title"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
title: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label="Description"
|
||||
placeholder="Description"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
description: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
loading={isLoading}
|
||||
color="yellow"
|
||||
onClick={() => handleSubmit()}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Stack>
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -29,11 +29,12 @@ export async function POST(req: Request) {
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%5Cn%5Cn%3E%3E%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
// const encodedMsg = encodeURIComponent(msg);
|
||||
|
||||
const res = await fetch(
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.
|
||||
\n
|
||||
>> Kode OTP anda: ${codeOtp}.
|
||||
`
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
const sendWa = await res.json();
|
||||
@@ -62,7 +63,5 @@ export async function POST(req: Request) {
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
82
src/app/api/auth/mobile-login/route.ts
Normal file
82
src/app/api/auth/mobile-login/route.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { prisma } from "@/lib";
|
||||
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const codeOtp = randomOTP();
|
||||
const body = await req.json();
|
||||
console.log("[Masuk API]", body);
|
||||
const { nomor } = body;
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
nomor: nomor,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["cek user", user]);
|
||||
console.log(["cek nomor", nomor]);
|
||||
|
||||
if (!user)
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "User tidak ditemukan",
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const createOtpId = await prisma.kodeOtp.create({
|
||||
data: {
|
||||
nomor: nomor,
|
||||
otp: codeOtp,
|
||||
},
|
||||
});
|
||||
|
||||
if (!createOtpId)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
// const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPAADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n\n> Kode OTP anda: ${codeOtp}.`;
|
||||
// const encodedMsg = encodeURIComponent(msg);
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
|
||||
const res = await fetch(
|
||||
`https://cld-dkr-prod-wajs-server.wibudev.com/api/wa/code?nom=${nomor}&text=${msg}`,
|
||||
{
|
||||
cache: "no-cache",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WA_SERVER_TOKEN}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (res.status !== 200)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
const sendWa = await res.text();
|
||||
console.log("WA Response:", sendWa);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Kode verifikasi terkirim",
|
||||
kodeId: createOtpId.id,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Terjadi masalah saat login",
|
||||
reason: error as Error,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
109
src/app/api/auth/mobile-register/route.ts
Normal file
109
src/app/api/auth/mobile-register/route.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import { sessionCreate } from "@/app/(auth)/_lib/session_create";
|
||||
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (req.method !== "POST") {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Method Not Allowed" },
|
||||
{ status: 405 }
|
||||
);
|
||||
}
|
||||
|
||||
const { data } = await req.json();
|
||||
console.log("data >>", data);
|
||||
const codeOtp = randomOTP();
|
||||
try {
|
||||
const cekUsername = await prisma.user.findUnique({
|
||||
where: {
|
||||
username: data.username,
|
||||
},
|
||||
});
|
||||
|
||||
if (cekUsername)
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "Username sudah digunakan",
|
||||
});
|
||||
|
||||
// ✅ Validasi wajib setuju Terms
|
||||
if (data.termsOfServiceAccepted !== true) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "You must agree to the Terms of Service",
|
||||
});
|
||||
}
|
||||
|
||||
const createUser = await prisma.user.create({
|
||||
data: {
|
||||
username: data.username,
|
||||
nomor: data.nomor,
|
||||
active: false,
|
||||
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||
acceptedTermsAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
if (!createUser)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal Registrasi" },
|
||||
{ status: 500 }
|
||||
);
|
||||
|
||||
// const token = await sessionCreate({
|
||||
// sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||
// encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||
// user: createUser as any,
|
||||
// });
|
||||
|
||||
const createOtpId = await prisma.kodeOtp.create({
|
||||
data: {
|
||||
nomor: data.nomor,
|
||||
otp: codeOtp,
|
||||
},
|
||||
});
|
||||
|
||||
if (!createOtpId)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
// const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPAADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n\n> Kode OTP anda: ${codeOtp}.`;
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
// // const encodedMsg = encodeURIComponent(msg);
|
||||
|
||||
const res = await fetch(
|
||||
`https://wa.wibudev.com/code?nom=${data.nomor}&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
const sendWa = await res.json();
|
||||
|
||||
if (sendWa.status !== "success")
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Registrasi Berhasil",
|
||||
// token: token,
|
||||
kodeId: createOtpId.id,
|
||||
},
|
||||
{ status: 201 }
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Maaf, Terjadi Keselahan",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
82
src/app/api/auth/mobile-validasi/route.ts
Normal file
82
src/app/api/auth/mobile-validasi/route.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { sessionCreate } from "@/app/(auth)/_lib/session_create";
|
||||
import prisma from "@/lib/prisma";
|
||||
import backendLogger from "@/util/backendLogger";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (req.method !== "POST") {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Method Not Allowed" },
|
||||
{ status: 405 }
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const { nomor } = await req.json();
|
||||
|
||||
const dataUser = await prisma.user.findUnique({
|
||||
where: {
|
||||
nomor: nomor,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
nomor: true,
|
||||
username: true,
|
||||
active: true,
|
||||
masterUserRoleId: true,
|
||||
termsOfServiceAccepted: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (dataUser == null)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Nomor Belum Terdaftar" },
|
||||
{ status: 200 }
|
||||
);
|
||||
|
||||
const token = await sessionCreate({
|
||||
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||
user: dataUser as any,
|
||||
});
|
||||
|
||||
if (!token) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal membuat session" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
// Buat response dengan token dalam cookie
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Berhasil Login",
|
||||
roleId: dataUser.masterUserRoleId,
|
||||
active: dataUser.active,
|
||||
termsOfServiceAccepted: dataUser.termsOfServiceAccepted,
|
||||
token: token,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
|
||||
// Set cookie dengan token yang sudah dipastikan tidak null
|
||||
response.cookies.set(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, token, {
|
||||
path: "/",
|
||||
sameSite: "lax",
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
maxAge: 30 * 24 * 60 * 60, // 30 hari dalam detik (1 bulan)
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
backendLogger.log("API Error or Server Error", error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Maaf, Terjadi Keselahan",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ export async function POST(req: Request) {
|
||||
try {
|
||||
const { data } = await req.json();
|
||||
|
||||
console.log("data >>", data);
|
||||
|
||||
const cekUsername = await prisma.user.findUnique({
|
||||
where: {
|
||||
username: data.username,
|
||||
@@ -26,11 +28,20 @@ export async function POST(req: Request) {
|
||||
message: "Username sudah digunakan",
|
||||
});
|
||||
|
||||
// ✅ Validasi wajib setuju Terms
|
||||
if (data.termsOfServiceAccepted !== true) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "You must agree to the Terms of Service",
|
||||
});
|
||||
}
|
||||
|
||||
const createUser = await prisma.user.create({
|
||||
data: {
|
||||
username: data.username,
|
||||
nomor: data.nomor,
|
||||
active: false,
|
||||
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -51,7 +62,7 @@ export async function POST(req: Request) {
|
||||
success: true,
|
||||
message: "Registrasi Berhasil, Anda Sedang Login",
|
||||
token: token,
|
||||
// data: createUser,
|
||||
// data: createUser,x
|
||||
},
|
||||
{ status: 201 }
|
||||
);
|
||||
@@ -65,7 +76,5 @@ export async function POST(req: Request) {
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,15 @@ export async function POST(req: Request) {
|
||||
const body = await req.json();
|
||||
const { nomor } = body;
|
||||
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%5Cn%5Cn%3E%3E%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
|
||||
const res = await fetch(
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.
|
||||
\n
|
||||
>> Kode OTP anda: ${codeOtp}.
|
||||
`
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
const sendWa = await res.json();
|
||||
|
||||
if (sendWa.status !== "success")
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
29
src/app/api/auth/term-service/route.ts
Normal file
29
src/app/api/auth/term-service/route.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const { data } = await req.json();
|
||||
console.log("data >>", data);
|
||||
|
||||
const updateTermService = await prisma.user.update({
|
||||
where: {
|
||||
id: data.id,
|
||||
},
|
||||
data: {
|
||||
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Berhasil",
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("error >>", error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "Gagal",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ export async function POST(req: Request) {
|
||||
username: true,
|
||||
active: true,
|
||||
masterUserRoleId: true,
|
||||
termsOfServiceAccepted: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -52,6 +53,7 @@ export async function POST(req: Request) {
|
||||
message: "Berhasil Login",
|
||||
roleId: dataUser.masterUserRoleId,
|
||||
active: dataUser.active,
|
||||
termsOfServiceAccepted: dataUser.termsOfServiceAccepted,
|
||||
token: token,
|
||||
},
|
||||
{ status: 200 }
|
||||
@@ -76,7 +78,5 @@ export async function POST(req: Request) {
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
41
src/app/api/helper/delete-account/route.ts
Normal file
41
src/app/api/helper/delete-account/route.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { Resend } from "resend";
|
||||
|
||||
const resend = new Resend(process.env.RESEND_APIKEY);
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const body = await req.json();
|
||||
|
||||
try {
|
||||
const { number } = body;
|
||||
|
||||
if (!number) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Missing required fields.",
|
||||
});
|
||||
}
|
||||
|
||||
const data = await resend.emails.send({
|
||||
from: `+${number} <onboarding@resend.dev>`,
|
||||
to: ["bagasbanuna02@gmail.com"], // ganti sesuai email kamu
|
||||
// cc: ["bip.baliinteraktifperkasa@gmail.com"],
|
||||
subject: "Delete Account",
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; font-size: 16px; color: #333;">
|
||||
<h3>New Message to Delete Account</h3>
|
||||
<p><strong>User with phone number +${number}</strong></p>
|
||||
<p><strong>Description: Want to delete account !!</strong></p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true, data });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
42
src/app/api/helper/support-center/route.ts
Normal file
42
src/app/api/helper/support-center/route.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { Resend } from "resend";
|
||||
|
||||
const resend = new Resend(process.env.RESEND_APIKEY);
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const body = await req.json();
|
||||
|
||||
try {
|
||||
const { email, title, description } = body;
|
||||
|
||||
if (!email || !title || !description) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Missing required fields.",
|
||||
});
|
||||
}
|
||||
|
||||
const data = await resend.emails.send({
|
||||
from: `${email} <onboarding@resend.dev>`,
|
||||
to: ["bagasbanuna02@gmail.com"],
|
||||
// to: ["bip.baliinteraktifperkasa@gmail.com"],
|
||||
subject: title,
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; font-size: 16px; color: #333;">
|
||||
<h3>New Message Received</h3>
|
||||
<p><strong>Email:</strong> ${email}</p>
|
||||
<p><strong>Title:</strong> ${title}</p>
|
||||
<p><strong>Description:</strong><br/>${description.replace(/\n/g, "<br/>")}</p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true, data });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import _ from "lodash";
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export { GET };
|
||||
|
||||
@@ -12,7 +13,6 @@ async function GET(request: Request) {
|
||||
const skipData = Number(page) * takeData - takeData;
|
||||
console.log("[CATEGORY]", category);
|
||||
let fixData;
|
||||
|
||||
|
||||
try {
|
||||
if (category === "dashboard") {
|
||||
|
||||
@@ -29,6 +29,11 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Event: {
|
||||
select: {
|
||||
tanggal: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ async function GET(request: Request) {
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
tanggal: true,
|
||||
Author: {
|
||||
select: {
|
||||
id: true,
|
||||
|
||||
70
src/app/api/mobile/admin/investment/[id]/investor/route.ts
Normal file
70
src/app/api/mobile/admin/investment/[id]/investor/route.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import _ from "lodash";
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export async function GET(
|
||||
request: Request,
|
||||
{ params }: { params: { id: string } }
|
||||
) {
|
||||
try {
|
||||
let fixData;
|
||||
const { id } = params;
|
||||
const { searchParams } = new URL(request.url);
|
||||
const page = searchParams.get("page");
|
||||
const status = searchParams.get("status");
|
||||
const takeData = 10;
|
||||
const skipData = Number(page) * takeData - takeData;
|
||||
|
||||
const fixStatus = _.startCase(status ? status : "");
|
||||
|
||||
const checkStatus = await prisma.investasiMaster_StatusInvoice.findFirst({
|
||||
where: {
|
||||
name: fixStatus,
|
||||
},
|
||||
});
|
||||
|
||||
const data = await prisma.investasi_Invoice.findMany({
|
||||
take: page ? takeData : undefined,
|
||||
skip: page ? skipData : undefined,
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
where: {
|
||||
investasiId: id,
|
||||
isActive: true,
|
||||
StatusInvoice: {
|
||||
name: {
|
||||
contains: checkStatus?.name,
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
Author: true,
|
||||
StatusInvoice: true,
|
||||
},
|
||||
});
|
||||
|
||||
fixData = data;
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Success get status transaksi",
|
||||
data: fixData,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Eror get status transaksi", error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error get status transaksi",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
178
src/app/api/mobile/admin/investment/[id]/invoice/route.ts
Normal file
178
src/app/api/mobile/admin/investment/[id]/invoice/route.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib";
|
||||
|
||||
export { GET, PUT };
|
||||
|
||||
async function GET(req: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
|
||||
try {
|
||||
const data = await prisma.investasi_Invoice.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
investasiId: true,
|
||||
nominal: true,
|
||||
createdAt: true,
|
||||
Author: true,
|
||||
StatusInvoice: true,
|
||||
imageId: true,
|
||||
MasterBank: true,
|
||||
lembarTerbeli: true,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Berhasil mendapatkan data",
|
||||
data: data,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error get detail Investasi",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function PUT(req: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
const { data } = await req.json();
|
||||
const { searchParams } = new URL(req.url);
|
||||
const category = searchParams.get("category");
|
||||
|
||||
console.log("[ID]", id);
|
||||
console.log("[DATA]", data);
|
||||
console.log("[CATEGORY]", category);
|
||||
|
||||
let fixData;
|
||||
try {
|
||||
if (category === "deny") {
|
||||
const updt = await prisma.investasi_Invoice.update({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
data: {
|
||||
statusInvoiceId: "4",
|
||||
},
|
||||
// select: {
|
||||
// StatusInvoice: true,
|
||||
// authorId: true,
|
||||
// },
|
||||
});
|
||||
|
||||
fixData = updt;
|
||||
} else if (category === "accept") {
|
||||
const dataInvestasi: any = await prisma.investasi.findFirst({
|
||||
where: {
|
||||
id: data.investasiId,
|
||||
},
|
||||
select: {
|
||||
totalLembar: true,
|
||||
sisaLembar: true,
|
||||
lembarTerbeli: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Hitung TOTAL SISA LEMBAR
|
||||
const investasi_sisaLembar = Number(dataInvestasi?.sisaLembar);
|
||||
const invoice_lembarTerbeli = Number(data.lembarTerbeli);
|
||||
const resultSisaLembar = investasi_sisaLembar - invoice_lembarTerbeli;
|
||||
|
||||
// TAMBAH LEMBAR TERBELI
|
||||
const investasi_lembarTerbeli = Number(dataInvestasi?.lembarTerbeli);
|
||||
const resultLembarTerbeli =
|
||||
investasi_lembarTerbeli + invoice_lembarTerbeli;
|
||||
|
||||
// Progress
|
||||
const investasi_totalLembar = Number(dataInvestasi?.totalLembar);
|
||||
const progress = (resultLembarTerbeli / investasi_totalLembar) * 100;
|
||||
const resultProgres = Number(progress).toFixed(2);
|
||||
|
||||
const updt = await prisma.investasi_Invoice.update({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
data: {
|
||||
statusInvoiceId: "1",
|
||||
},
|
||||
});
|
||||
|
||||
if (!updt) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Gagal Update Status",
|
||||
reason: "Update status failed",
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
const updateInvestasi = await prisma.investasi.update({
|
||||
where: {
|
||||
id: data.investasiId,
|
||||
},
|
||||
data: {
|
||||
sisaLembar: resultSisaLembar.toString(),
|
||||
lembarTerbeli: resultLembarTerbeli.toString(),
|
||||
progress: resultProgres,
|
||||
},
|
||||
include: {
|
||||
MasterStatusInvestasi: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!updateInvestasi) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Gagal Update Data Investasi",
|
||||
reason: "Update data investasi failed",
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
fixData = updt;
|
||||
} else {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Invalid category",
|
||||
reason: "Invalid category",
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Berhasil update data",
|
||||
data: fixData,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error update detail Investasi",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
137
src/app/api/mobile/admin/investment/[id]/route.ts
Normal file
137
src/app/api/mobile/admin/investment/[id]/route.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib";
|
||||
|
||||
export { GET, PUT };
|
||||
|
||||
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
|
||||
try {
|
||||
const data = await prisma.investasi.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
select: {
|
||||
imageId: true,
|
||||
prospektusFileId: true,
|
||||
id: true,
|
||||
author: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
nomor: true,
|
||||
Profile: true,
|
||||
},
|
||||
},
|
||||
title: true,
|
||||
authorId: true,
|
||||
hargaLembar: true,
|
||||
targetDana: true,
|
||||
totalLembar: true,
|
||||
sisaLembar: true,
|
||||
lembarTerbeli: true,
|
||||
progress: true,
|
||||
roi: true,
|
||||
active: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
catatan: true,
|
||||
imagesId: true,
|
||||
MasterStatusInvestasi: true,
|
||||
BeritaInvestasi: true,
|
||||
DokumenInvestasi: true,
|
||||
ProspektusInvestasi: true,
|
||||
MasterPembagianDeviden: true,
|
||||
MasterPencarianInvestor: true,
|
||||
MasterPeriodeDeviden: true,
|
||||
MasterProgresInvestasi: true,
|
||||
masterStatusInvestasiId: true,
|
||||
countDown: true,
|
||||
Investasi_Invoice: {
|
||||
where: {
|
||||
statusInvoiceId: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Success get data investment",
|
||||
data: data,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error get data investment",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
const { data } = await request.json();
|
||||
const { searchParams } = new URL(request.url);
|
||||
const status = searchParams.get("status");
|
||||
|
||||
console.log("[=======Start Investment console=======]");
|
||||
console.log("[ID]", id);
|
||||
console.log("[DATA]", data);
|
||||
console.log("[STATUS]", status);
|
||||
console.log("[=======End Investment console=======]");
|
||||
|
||||
const publishTime = new Date();
|
||||
|
||||
try {
|
||||
if (status === "reject") {
|
||||
const updatedData = await prisma.investasi.update({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
data: {
|
||||
catatan: data,
|
||||
masterStatusInvestasiId: "4",
|
||||
},
|
||||
});
|
||||
|
||||
console.log("[UPDATE REJECT]", updatedData);
|
||||
} else if (status === "publish") {
|
||||
const updatedData = await prisma.investasi.update({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
data: {
|
||||
masterStatusInvestasiId: "1",
|
||||
masterProgresInvestasiId: "1",
|
||||
countDown: publishTime,
|
||||
},
|
||||
});
|
||||
|
||||
console.log("[UPDATE PUBLISH]", updatedData);
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Success update data investment",
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error update data investment",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
104
src/app/api/mobile/admin/investment/route.ts
Normal file
104
src/app/api/mobile/admin/investment/route.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import _ from "lodash";
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib";
|
||||
|
||||
export { GET };
|
||||
|
||||
async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const category = searchParams.get("category");
|
||||
const search = searchParams.get("search");
|
||||
const page = searchParams.get("page");
|
||||
const takeData = 10;
|
||||
const skipData = Number(page) * takeData - takeData;
|
||||
|
||||
console.log("[CATEGORY]", category);
|
||||
console.log("[PAGE]", page);
|
||||
|
||||
let fixData;
|
||||
try {
|
||||
if (category === "dashboard") {
|
||||
const publish = await prisma.investasi.count({
|
||||
where: {
|
||||
MasterStatusInvestasi: {
|
||||
name: "Publish",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const review = await prisma.investasi.count({
|
||||
where: {
|
||||
MasterStatusInvestasi: {
|
||||
name: "Review",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const reject = await prisma.investasi.count({
|
||||
where: {
|
||||
MasterStatusInvestasi: {
|
||||
name: "Reject",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
fixData = {
|
||||
publish,
|
||||
review,
|
||||
reject,
|
||||
};
|
||||
} else {
|
||||
const fixCategoryToStatus = _.startCase(category || "");
|
||||
console.log("[STATUS]", fixCategoryToStatus);
|
||||
|
||||
const data = await prisma.investasi.findMany({
|
||||
take: page ? takeData : undefined,
|
||||
skip: page ? skipData : undefined,
|
||||
orderBy: {
|
||||
updatedAt: "desc",
|
||||
},
|
||||
where: {
|
||||
active: true,
|
||||
MasterStatusInvestasi: {
|
||||
name: fixCategoryToStatus,
|
||||
},
|
||||
title: {
|
||||
contains: search || "",
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
author: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
fixData = data;
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Success get data investment",
|
||||
data: fixData,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("[ERROR GET DATA INVESTMENT]", error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error get data investment",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
69
src/app/api/mobile/admin/master/donation/[id]/route.ts
Normal file
69
src/app/api/mobile/admin/master/donation/[id]/route.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export { GET, PUT };
|
||||
|
||||
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
let fixData;
|
||||
|
||||
try {
|
||||
fixData = await prisma.donasiMaster_Kategori.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
active: true,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Master berhasil diambil",
|
||||
data: fixData,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Gagal mengambil data master",
|
||||
reason: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
const { data } = await request.json();
|
||||
|
||||
console.log("id", id);
|
||||
console.log("data", data);
|
||||
|
||||
try {
|
||||
const updateData = await prisma.donasiMaster_Kategori.update({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
data: {
|
||||
name: data.name,
|
||||
active: data.active,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Master berhasil diupdate",
|
||||
data: updateData,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Gagal mengupdate data master",
|
||||
reason: (error as Error).message,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
105
src/app/api/mobile/admin/master/donation/route.ts
Normal file
105
src/app/api/mobile/admin/master/donation/route.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export { GET, POST };
|
||||
|
||||
async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
// const category = searchParams.get("category");
|
||||
let fixData;
|
||||
|
||||
try {
|
||||
fixData = await prisma.donasiMaster_Kategori.findMany({
|
||||
orderBy: {
|
||||
createdAt: "asc",
|
||||
},
|
||||
});
|
||||
|
||||
// if (category === "category") {
|
||||
// fixData = await prisma.donasiMaster_Kategori.findMany({
|
||||
// orderBy: {
|
||||
// createdAt: "asc",
|
||||
// },
|
||||
// where: {
|
||||
// active: true,
|
||||
// },
|
||||
// });
|
||||
// } else if (category === "duration") {
|
||||
// fixData = await prisma.donasiMaster_Durasi.findMany({
|
||||
// orderBy: {
|
||||
// createdAt: "asc",
|
||||
// },
|
||||
// where: {
|
||||
// active: true,
|
||||
// },
|
||||
// });
|
||||
// } else {
|
||||
// const category = await prisma.donasiMaster_Kategori.findMany({
|
||||
// orderBy: {
|
||||
// createdAt: "asc",
|
||||
// },
|
||||
// where: {
|
||||
// active: true,
|
||||
// },
|
||||
// });
|
||||
|
||||
// const duration = await prisma.donasiMaster_Durasi.findMany({
|
||||
// orderBy: {
|
||||
// createdAt: "asc",
|
||||
// },
|
||||
// where: {
|
||||
// active: true,
|
||||
// },
|
||||
// });
|
||||
|
||||
// fixData = {
|
||||
// category: category,
|
||||
// duration: duration,
|
||||
// };
|
||||
// }
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Master berhasil diambil",
|
||||
data: fixData,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Gagal mengambil data master",
|
||||
reason: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function POST(request: Request) {
|
||||
const { data } = await request.json();
|
||||
|
||||
console.log("data", data);
|
||||
|
||||
try {
|
||||
const count = await prisma.donasiMaster_Kategori.count();
|
||||
const createNewId = count + 1;
|
||||
|
||||
const createData = await prisma.donasiMaster_Kategori.create({
|
||||
data: {
|
||||
id: createNewId.toString(),
|
||||
name: data.name,
|
||||
active: data.active,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Master berhasil ditambahkan",
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Gagal menambah data master",
|
||||
reason: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
82
src/app/api/mobile/auth/login/route.ts
Normal file
82
src/app/api/mobile/auth/login/route.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { prisma } from "@/lib";
|
||||
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (req.method !== "POST") {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Method Not Allowed" },
|
||||
{ status: 405 }
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const codeOtp = randomOTP();
|
||||
const body = await req.json();
|
||||
const { nomor } = body;
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
nomor: nomor,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["cek user", user]);
|
||||
console.log(["cek nomor", nomor]);
|
||||
|
||||
if (!user)
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "User tidak ditemukan",
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const createOtpId = await prisma.kodeOtp.create({
|
||||
data: {
|
||||
nomor: nomor,
|
||||
otp: codeOtp,
|
||||
},
|
||||
});
|
||||
|
||||
if (!createOtpId)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
// const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPAADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n\n> Kode OTP anda: ${codeOtp}.`;
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
// // const encodedMsg = encodeURIComponent(msg);
|
||||
|
||||
const res = await fetch(
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
const sendWa = await res.json();
|
||||
|
||||
if (sendWa.status !== "success")
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Kode verifikasi terkirim",
|
||||
kodeId: createOtpId.id,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Terjadi masalah saat login",
|
||||
reason: error as Error,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
108
src/app/api/mobile/auth/register/route.ts
Normal file
108
src/app/api/mobile/auth/register/route.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { sessionCreate } from "@/app/(auth)/_lib/session_create";
|
||||
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (req.method !== "POST") {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Method Not Allowed" },
|
||||
{ status: 405 }
|
||||
);
|
||||
}
|
||||
|
||||
const { data } = await req.json();
|
||||
console.log("data >>", data);
|
||||
const codeOtp = randomOTP();
|
||||
try {
|
||||
const cekUsername = await prisma.user.findUnique({
|
||||
where: {
|
||||
username: data.username,
|
||||
},
|
||||
});
|
||||
|
||||
if (cekUsername)
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "Username sudah digunakan",
|
||||
});
|
||||
|
||||
// ✅ Validasi wajib setuju Terms
|
||||
if (data.termsOfServiceAccepted !== true) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "You must agree to the Terms of Service",
|
||||
});
|
||||
}
|
||||
|
||||
const createUser = await prisma.user.create({
|
||||
data: {
|
||||
username: data.username,
|
||||
nomor: data.nomor,
|
||||
active: false,
|
||||
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||
},
|
||||
});
|
||||
|
||||
if (!createUser)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal Registrasi" },
|
||||
{ status: 500 }
|
||||
);
|
||||
|
||||
// const token = await sessionCreate({
|
||||
// sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||
// encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||
// user: createUser as any,
|
||||
// });
|
||||
|
||||
const createOtpId = await prisma.kodeOtp.create({
|
||||
data: {
|
||||
nomor: data.nomor,
|
||||
otp: codeOtp,
|
||||
},
|
||||
});
|
||||
|
||||
if (!createOtpId)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
// const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPAADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n\n> Kode OTP anda: ${codeOtp}.`;
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
// // const encodedMsg = encodeURIComponent(msg);
|
||||
|
||||
const res = await fetch(
|
||||
`https://wa.wibudev.com/code?nom=${data.nomor}&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
const sendWa = await res.json();
|
||||
|
||||
if (sendWa.status !== "success")
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Registrasi Berhasil",
|
||||
// token: token,
|
||||
kodeId: createOtpId.id,
|
||||
},
|
||||
{ status: 201 }
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Maaf, Terjadi Keselahan",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
82
src/app/api/mobile/auth/validasi/route.ts
Normal file
82
src/app/api/mobile/auth/validasi/route.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { sessionCreate } from "@/app/(auth)/_lib/session_create";
|
||||
import prisma from "@/lib/prisma";
|
||||
import backendLogger from "@/util/backendLogger";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (req.method !== "POST") {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Method Not Allowed" },
|
||||
{ status: 405 }
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const { nomor } = await req.json();
|
||||
|
||||
const dataUser = await prisma.user.findUnique({
|
||||
where: {
|
||||
nomor: nomor,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
nomor: true,
|
||||
username: true,
|
||||
active: true,
|
||||
masterUserRoleId: true,
|
||||
termsOfServiceAccepted: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (dataUser == null)
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Nomor Belum Terdaftar" },
|
||||
{ status: 200 }
|
||||
);
|
||||
|
||||
const token = await sessionCreate({
|
||||
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||
user: dataUser as any,
|
||||
});
|
||||
|
||||
if (!token) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Gagal membuat session" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
// Buat response dengan token dalam cookie
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Berhasil Login",
|
||||
roleId: dataUser.masterUserRoleId,
|
||||
active: dataUser.active,
|
||||
termsOfServiceAccepted: dataUser.termsOfServiceAccepted,
|
||||
token: token,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
|
||||
// Set cookie dengan token yang sudah dipastikan tidak null
|
||||
response.cookies.set(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, token, {
|
||||
path: "/",
|
||||
sameSite: "lax",
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
maxAge: 30 * 24 * 60 * 60, // 30 hari dalam detik (1 bulan)
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
backendLogger.log("API Error or Server Error", error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Maaf, Terjadi Keselahan",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
78
src/app/api/mobile/block-user/[id]/route.tsx
Normal file
78
src/app/api/mobile/block-user/[id]/route.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export { GET, DELETE };
|
||||
|
||||
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
console.log("[ID] >>", id);
|
||||
|
||||
try {
|
||||
const data = await prisma.blockedUser.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
select: {
|
||||
blocked: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
Profile: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
menuFeature: {
|
||||
select: {
|
||||
name: true,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return NextResponse.json({
|
||||
status: 200,
|
||||
success: true,
|
||||
message: "success",
|
||||
data: data,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR GET BLOCK USER] >>", error);
|
||||
return NextResponse.json({
|
||||
status: 500,
|
||||
success: false,
|
||||
message: "error",
|
||||
reason: (error as Error).message || error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function DELETE(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
console.log("[ID] >>", id);
|
||||
|
||||
try {
|
||||
const data = await prisma.blockedUser.delete({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
});
|
||||
return NextResponse.json({
|
||||
status: 200,
|
||||
success: true,
|
||||
message: "success",
|
||||
data: data,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR DELETE BLOCK USER] >>", error);
|
||||
return NextResponse.json({
|
||||
status: 500,
|
||||
success: false,
|
||||
message: "error",
|
||||
reason: (error as Error).message || error,
|
||||
});
|
||||
}
|
||||
}
|
||||
109
src/app/api/mobile/block-user/route.ts
Normal file
109
src/app/api/mobile/block-user/route.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import _ from "lodash";
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export { POST, GET };
|
||||
|
||||
async function POST(request: Request) {
|
||||
const { data } = await request.json();
|
||||
|
||||
console.log("data >>", data);
|
||||
console.log("menuFeature masuk>>", data.menuFeature);
|
||||
|
||||
try {
|
||||
const nameApp = _.lowerCase(data.menuFeature);
|
||||
const menuFeature = await prisma.masterKategoriApp.findFirst({
|
||||
where: { value: nameApp },
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(" fix menuFeature >>", menuFeature);
|
||||
|
||||
const blockUser = await prisma.blockedUser.create({
|
||||
data: {
|
||||
blockerId: data.blockerId,
|
||||
blockedId: data.blockedId,
|
||||
menuFeatureId: menuFeature?.id as any,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
status: 200,
|
||||
success: true,
|
||||
message: "success",
|
||||
// data: blockUser,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR BLOCK USER] >>", error);
|
||||
return NextResponse.json({
|
||||
status: 500,
|
||||
success: false,
|
||||
message: "error",
|
||||
reason: (error as Error).message || error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const id = searchParams.get("id");
|
||||
const page = Number(searchParams.get("page"));
|
||||
const search = searchParams.get("search");
|
||||
|
||||
const takeData = 10;
|
||||
const skipData = page * takeData - takeData;
|
||||
|
||||
try {
|
||||
const data = await prisma.blockedUser.findMany({
|
||||
take: page ? takeData : undefined,
|
||||
skip: page ? skipData : undefined,
|
||||
where: {
|
||||
blockerId: id as any,
|
||||
menuFeature: {
|
||||
id: {
|
||||
contains: search || "",
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
blocked: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
Profile: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
menuFeature: {
|
||||
select: {
|
||||
name: true,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
status: 200,
|
||||
success: true,
|
||||
message: "success",
|
||||
data: data,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR GET BLOCK USER] >>", error);
|
||||
return NextResponse.json({
|
||||
status: 500,
|
||||
success: false,
|
||||
message: "error",
|
||||
reason: (error as Error).message || error,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,8 @@ async function POST(request: Request) {
|
||||
},
|
||||
});
|
||||
|
||||
console.log("[DATA DONASI]", dataDonasi);
|
||||
|
||||
if (!dataDonasi)
|
||||
return NextResponse.json({
|
||||
status: 400,
|
||||
@@ -68,6 +70,8 @@ async function POST(request: Request) {
|
||||
},
|
||||
});
|
||||
|
||||
console.log("[DATA CERITA]", dataCerita);
|
||||
|
||||
if (!dataCerita)
|
||||
return NextResponse.json({
|
||||
status: 400,
|
||||
|
||||
@@ -11,6 +11,24 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
||||
console.log("[ID]", id);
|
||||
|
||||
try {
|
||||
const content = await prisma.forum_Komentar.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
});
|
||||
|
||||
const reportList = await prisma.forumMaster_KategoriReport.findUnique({
|
||||
where: {
|
||||
id: data.categoryId,
|
||||
},
|
||||
});
|
||||
|
||||
const msg = `Report Komentar: "${content?.komentar}" dengan kategori \n\n\n${reportList?.title} : \n\n${reportList?.deskripsi}`;
|
||||
const res = await fetch(
|
||||
`https://cld-dkr-prod-wajs-server.wibudev.com/api/wa/code?nom=6282340374412&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
if (data.categoryId) {
|
||||
fixData = await prisma.forum_ReportKomentar.create({
|
||||
data: {
|
||||
|
||||
@@ -11,6 +11,18 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
||||
console.log("[ID]", id);
|
||||
|
||||
try {
|
||||
const content = await prisma.forum_Posting.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
});
|
||||
|
||||
const msg = `Report Postingan: "${content?.diskusi}"`;
|
||||
const res = await fetch(
|
||||
`https://cld-dkr-prod-wajs-server.wibudev.com/api/wa/code?nom=6282340374412&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
if (data.categoryId) {
|
||||
fixData = await prisma.forum_ReportPosting.create({
|
||||
data: {
|
||||
|
||||
@@ -36,11 +36,109 @@ async function GET(request: Request) {
|
||||
let fixData;
|
||||
const { searchParams } = new URL(request.url);
|
||||
const authorId = searchParams.get("authorId");
|
||||
const userLoginId = searchParams.get("userLoginId");
|
||||
const search = searchParams.get("search");
|
||||
const category = searchParams.get("category");
|
||||
const page = searchParams.get("page");
|
||||
const takeData = 5;
|
||||
const skipData = (Number(page) - 1) * takeData;
|
||||
|
||||
|
||||
// console.log("authorId", authorId);
|
||||
// console.log("userLoginId", userLoginId);
|
||||
// console.log("search", search);
|
||||
// console.log("category", category);
|
||||
console.log("page", page);
|
||||
|
||||
try {
|
||||
if (authorId) {
|
||||
if (category === "beranda") {
|
||||
const blockUserId = await prisma.blockedUser
|
||||
.findMany({
|
||||
where: {
|
||||
blockerId: userLoginId as string,
|
||||
},
|
||||
select: {
|
||||
blockedId: true,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
return res.map((item) => item.blockedId);
|
||||
});
|
||||
|
||||
console.log("blockUserId", blockUserId);
|
||||
|
||||
const data = await prisma.forum_Posting.findMany({
|
||||
take: page ? takeData : undefined,
|
||||
skip: page ? skipData : undefined,
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
where: {
|
||||
isActive: true,
|
||||
diskusi: {
|
||||
mode: "insensitive",
|
||||
contains: search || "",
|
||||
},
|
||||
authorId: {
|
||||
notIn: blockUserId,
|
||||
},
|
||||
},
|
||||
|
||||
select: {
|
||||
id: true,
|
||||
diskusi: true,
|
||||
createdAt: true,
|
||||
isActive: true,
|
||||
authorId: true,
|
||||
Author: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
Profile: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Forum_Komentar: {
|
||||
where: {
|
||||
isActive: true,
|
||||
},
|
||||
},
|
||||
ForumMaster_StatusPosting: {
|
||||
select: {
|
||||
id: true,
|
||||
status: true,
|
||||
},
|
||||
},
|
||||
forumMaster_StatusPostingId: true,
|
||||
},
|
||||
});
|
||||
|
||||
const newData = data.map((item) => {
|
||||
const count = item.Forum_Komentar?.length ?? 0;
|
||||
return {
|
||||
..._.omit(item, ["Forum_Komentar"]),
|
||||
count,
|
||||
};
|
||||
});
|
||||
|
||||
fixData = newData;
|
||||
} else if (category === "forumku") {
|
||||
|
||||
const count = await prisma.forum_Posting.count({
|
||||
where: {
|
||||
isActive: true,
|
||||
authorId: authorId,
|
||||
},
|
||||
})
|
||||
|
||||
const data = await prisma.forum_Posting.findMany({
|
||||
take: page ? takeData : undefined,
|
||||
skip: page ? skipData : undefined,
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
@@ -90,62 +188,18 @@ async function GET(request: Request) {
|
||||
};
|
||||
});
|
||||
|
||||
fixData = newData;
|
||||
const dataFix = {
|
||||
data: newData,
|
||||
count,
|
||||
}
|
||||
|
||||
fixData = dataFix;
|
||||
} else {
|
||||
const data = await prisma.forum_Posting.findMany({
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
where: {
|
||||
isActive: true,
|
||||
diskusi: {
|
||||
mode: "insensitive",
|
||||
contains: search || "",
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
diskusi: true,
|
||||
createdAt: true,
|
||||
isActive: true,
|
||||
authorId: true,
|
||||
Author: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
Profile: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Forum_Komentar: {
|
||||
where: {
|
||||
isActive: true,
|
||||
},
|
||||
},
|
||||
ForumMaster_StatusPosting: {
|
||||
select: {
|
||||
id: true,
|
||||
status: true,
|
||||
},
|
||||
},
|
||||
forumMaster_StatusPostingId: true,
|
||||
},
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: "Gagal mendapatkan data",
|
||||
reason: "Kategori tidak ditemukan",
|
||||
});
|
||||
|
||||
const newData = data.map((item) => {
|
||||
const count = item.Forum_Komentar?.length ?? 0;
|
||||
return {
|
||||
..._.omit(item, ["Forum_Komentar"]),
|
||||
count,
|
||||
};
|
||||
});
|
||||
|
||||
fixData = newData;
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
@@ -153,7 +207,6 @@ async function GET(request: Request) {
|
||||
message: "Berhasil mendapatkan data",
|
||||
data: fixData,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
return NextResponse.json({
|
||||
|
||||
48
src/app/api/mobile/investment/[id]/investor/route.ts
Normal file
48
src/app/api/mobile/investment/[id]/investor/route.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export { GET };
|
||||
|
||||
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
|
||||
try {
|
||||
const data = await prisma.investasi_Invoice.findMany({
|
||||
where: {
|
||||
investasiId: id,
|
||||
statusInvoiceId: "1",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
nominal: true,
|
||||
Author: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
Profile: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
status: 200,
|
||||
success: true,
|
||||
message: "Berhasil Mendapatkan Data",
|
||||
data: data,
|
||||
});
|
||||
} catch (error) {
|
||||
return NextResponse.json({
|
||||
status: 500,
|
||||
success: false,
|
||||
message: "Error Mendapatkan Data",
|
||||
reason: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,9 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
const category = searchParams.get("category");
|
||||
const authorId = searchParams.get("authorId");
|
||||
|
||||
console.log("[ID INVOICE]", id);
|
||||
|
||||
|
||||
let fixData;
|
||||
|
||||
try {
|
||||
@@ -80,6 +83,8 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
},
|
||||
});
|
||||
|
||||
console.log("[DATA INVOICE]", data ? true : false);
|
||||
|
||||
const { ...allData } = data;
|
||||
const Investor = data?.Investasi?.Investasi_Invoice;
|
||||
fixData = { ...allData, Investor };
|
||||
|
||||
@@ -24,18 +24,18 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
||||
});
|
||||
|
||||
fixData = createWithFile;
|
||||
} else {
|
||||
const createWitOutFile = await prisma.beritaInvestasi.create({
|
||||
data: {
|
||||
investasiId: id,
|
||||
title: _.startCase(data.title),
|
||||
deskripsi: data.deskripsi,
|
||||
},
|
||||
});
|
||||
|
||||
fixData = createWitOutFile;
|
||||
}
|
||||
|
||||
const createWitOutFile = await prisma.beritaInvestasi.create({
|
||||
data: {
|
||||
investasiId: id,
|
||||
title: _.startCase(data.title),
|
||||
deskripsi: data.deskripsi,
|
||||
},
|
||||
});
|
||||
|
||||
fixData = createWitOutFile;
|
||||
|
||||
return NextResponse.json({
|
||||
status: 201,
|
||||
success: true,
|
||||
|
||||
@@ -17,7 +17,11 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||
Profile: true,
|
||||
},
|
||||
},
|
||||
Investasi_Invoice: true,
|
||||
Investasi_Invoice: {
|
||||
where: {
|
||||
statusInvoiceId: "1"
|
||||
}
|
||||
},
|
||||
MasterStatusInvestasi: true,
|
||||
BeritaInvestasi: true,
|
||||
DokumenInvestasi: true,
|
||||
|
||||
@@ -4,6 +4,7 @@ import prisma from "@/lib/prisma";
|
||||
import moment from "moment";
|
||||
|
||||
export { POST, GET };
|
||||
|
||||
async function POST(request: Request) {
|
||||
const { data } = await request.json();
|
||||
console.log(["DATA INVESTASI"], data);
|
||||
@@ -46,82 +47,112 @@ async function POST(request: Request) {
|
||||
}
|
||||
|
||||
async function GET(request: Request) {
|
||||
let fixData;
|
||||
const { searchParams } = new URL(request.url);
|
||||
const category = searchParams.get("category");
|
||||
const authorId = searchParams.get("authorId");
|
||||
|
||||
console.log("[CATEGORY]", category);
|
||||
console.log("[AUTHOR ID]", authorId);
|
||||
let fixData;
|
||||
try {
|
||||
const data = await prisma.investasi.findMany({
|
||||
where: {
|
||||
masterStatusInvestasiId: "1",
|
||||
masterProgresInvestasiId: "1",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
MasterPencarianInvestor: true,
|
||||
countDown: true,
|
||||
progress: true,
|
||||
},
|
||||
});
|
||||
if (category === "bursa") {
|
||||
const data = await prisma.investasi.findMany({
|
||||
where: {
|
||||
masterStatusInvestasiId: "1",
|
||||
masterProgresInvestasiId: "1",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
MasterPencarianInvestor: true,
|
||||
countDown: true,
|
||||
progress: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (let a of data) {
|
||||
if (
|
||||
(a.MasterPencarianInvestor?.name as any) -
|
||||
moment(new Date()).diff(new Date(a.countDown as any), "days") <=
|
||||
0
|
||||
) {
|
||||
await prisma.investasi.update({
|
||||
where: {
|
||||
id: a.id,
|
||||
},
|
||||
data: {
|
||||
masterProgresInvestasiId: "3",
|
||||
},
|
||||
});
|
||||
for (let a of data) {
|
||||
if (
|
||||
(a.MasterPencarianInvestor?.name as any) -
|
||||
moment(new Date()).diff(new Date(a.countDown as any), "days") <=
|
||||
0
|
||||
) {
|
||||
await prisma.investasi.update({
|
||||
where: {
|
||||
id: a.id,
|
||||
},
|
||||
data: {
|
||||
masterProgresInvestasiId: "3",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (a.progress === "100") {
|
||||
await prisma.investasi.update({
|
||||
where: {
|
||||
id: a.id,
|
||||
},
|
||||
data: {
|
||||
masterProgresInvestasiId: "2",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (a.progress === "100") {
|
||||
await prisma.investasi.update({
|
||||
where: {
|
||||
id: a.id,
|
||||
},
|
||||
data: {
|
||||
masterProgresInvestasiId: "2",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const dataAwal = await prisma.investasi.findMany({
|
||||
orderBy: [
|
||||
{
|
||||
masterProgresInvestasiId: "asc",
|
||||
const dataAwal = await prisma.investasi.findMany({
|
||||
orderBy: [
|
||||
{
|
||||
masterProgresInvestasiId: "asc",
|
||||
},
|
||||
{
|
||||
countDown: "desc",
|
||||
},
|
||||
],
|
||||
where: {
|
||||
masterStatusInvestasiId: "1",
|
||||
},
|
||||
{
|
||||
countDown: "desc",
|
||||
},
|
||||
],
|
||||
where: {
|
||||
masterStatusInvestasiId: "1",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
title: true,
|
||||
progress: true,
|
||||
countDown: true,
|
||||
MasterPencarianInvestor: {
|
||||
select: {
|
||||
name: true,
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
title: true,
|
||||
progress: true,
|
||||
countDown: true,
|
||||
MasterPencarianInvestor: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
fixData = dataAwal.map((v: any) => ({
|
||||
..._.omit(v, ["MasterPencarianInvestor"]),
|
||||
pencarianInvestor: v.MasterPencarianInvestor.name,
|
||||
}));
|
||||
fixData = dataAwal.map((v: any) => ({
|
||||
..._.omit(v, ["MasterPencarianInvestor"]),
|
||||
pencarianInvestor: v.MasterPencarianInvestor.name,
|
||||
}));
|
||||
} else if (category === "my-holding") {
|
||||
const data = await prisma.investasi_Invoice.findMany({
|
||||
where: {
|
||||
authorId: authorId,
|
||||
statusInvoiceId: "1",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
investasiId: true,
|
||||
nominal: true,
|
||||
lembarTerbeli: true,
|
||||
Investasi: {
|
||||
select: {
|
||||
title: true,
|
||||
progress: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
fixData = data.map((v: any) => ({
|
||||
..._.omit(v, ["Investasi"]),
|
||||
title: v.Investasi.title,
|
||||
progress: v.Investasi.progress,
|
||||
}));
|
||||
}
|
||||
return NextResponse.json({
|
||||
status: 200,
|
||||
success: true,
|
||||
|
||||
28
src/app/api/mobile/master/app-category/route.ts
Normal file
28
src/app/api/mobile/master/app-category/route.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export { GET };
|
||||
|
||||
async function GET(request: Request) {
|
||||
try {
|
||||
const data = await prisma.masterKategoriApp.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
return NextResponse.json({
|
||||
status: 200,
|
||||
success: true,
|
||||
message: "success",
|
||||
data: data,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("[ERROR GET APP CATEGORY] >>", error);
|
||||
return NextResponse.json({
|
||||
status: 500,
|
||||
success: false,
|
||||
message: "error",
|
||||
reason: (error as Error).message || error,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ async function DELETE(request: Request, context: { params: { id: string } }) {
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
if (data?.logoId != null) {
|
||||
@@ -134,7 +134,7 @@ async function DELETE(request: Request, context: { params: { id: string } }) {
|
||||
}
|
||||
}
|
||||
|
||||
if (data?.BusinessMaps) {
|
||||
if (data?.BusinessMaps !== null) {
|
||||
const pinId = data?.BusinessMaps?.pinId;
|
||||
|
||||
if (pinId) {
|
||||
@@ -172,24 +172,23 @@ async function DELETE(request: Request, context: { params: { id: string } }) {
|
||||
}
|
||||
}
|
||||
|
||||
const deletePortoMedsos = await prisma.portofolio_MediaSosial.delete({
|
||||
const deleteMap = await prisma.businessMaps.delete({
|
||||
where: {
|
||||
portofolioId: id,
|
||||
id: data?.BusinessMaps?.id,
|
||||
},
|
||||
});
|
||||
|
||||
const deleteMap = await prisma.businessMaps.delete({
|
||||
const deletePortoMedsos = await prisma.portofolio_MediaSosial.delete({
|
||||
where: {
|
||||
portofolioId: id,
|
||||
portofolioId: data?.id,
|
||||
},
|
||||
});
|
||||
|
||||
const deletePortofolio = await prisma.portofolio.delete({
|
||||
where: {
|
||||
id: id,
|
||||
id: data?.id,
|
||||
},
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error delete logo", error);
|
||||
}
|
||||
|
||||
@@ -32,3 +32,717 @@ export async function GET(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function DELETE(
|
||||
request: Request,
|
||||
{ params }: { params: { id: string } }
|
||||
) {
|
||||
const { id } = params;
|
||||
console.log("[ID USER", id);
|
||||
try {
|
||||
console.log("[START DELETE ALL >>>]");
|
||||
const checkUser = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
select: {
|
||||
// EVENT START
|
||||
Event: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
Event_Peserta: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
// EVENT END
|
||||
|
||||
// COLLABORATION START
|
||||
ProjectCollaboration: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
ProjectCollaboration_Partisipasi: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
ProjectCollaboration_RoomChat: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
ProjectCollaboration_AnggotaRoomChat: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
ProjectCollaboration_Message: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
// COLLABORATION END
|
||||
|
||||
// VOTING START
|
||||
Voting: {
|
||||
select: {
|
||||
id: true,
|
||||
Voting_DaftarNamaVote: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Voting_Kontributor: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
|
||||
// VOTING END
|
||||
|
||||
// JOB START
|
||||
Job: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
// JOB END
|
||||
|
||||
// FORUM START
|
||||
Forum_Posting: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
Forum_Komentar: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
Forum_ReportKomentar: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
Forum_ReportPosting: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
// FORUM END
|
||||
|
||||
// INVITATION START
|
||||
Investasi: {
|
||||
select: {
|
||||
id: true,
|
||||
prospektusFileId: true,
|
||||
imageId: true,
|
||||
BeritaInvestasi: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
DokumenInvestasi: {
|
||||
select: {
|
||||
id: true,
|
||||
fileId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Investasi_Invoice: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
|
||||
// INVITATION END
|
||||
|
||||
// DONATION START
|
||||
Donasi: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
CeritaDonasi: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
Donasi_Kabar: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
Donasi_PencairanDana: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Donasi_Invoice: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
|
||||
// DONATION END
|
||||
|
||||
// PROFILE & PORTOFOLOIO START
|
||||
Profile: {
|
||||
select: {
|
||||
id: true,
|
||||
Portofolio: {
|
||||
select: {
|
||||
id: true,
|
||||
logoId: true,
|
||||
BusinessMaps: {
|
||||
select: {
|
||||
id: true,
|
||||
imageId: true,
|
||||
},
|
||||
},
|
||||
Portofolio_MediaSosial: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// PROFILE & PORTOFOLOIO END
|
||||
},
|
||||
});
|
||||
|
||||
// =================================================== //
|
||||
// ================ START DELETE ALL ================= //
|
||||
// =================================================== //
|
||||
|
||||
// EVENT DELETE START
|
||||
for (let event of checkUser?.Event_Peserta as any) {
|
||||
const deleteEvent = await prisma.event_Peserta.delete({
|
||||
where: {
|
||||
id: event.id,
|
||||
},
|
||||
select: {
|
||||
Event: {
|
||||
select: {
|
||||
title: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE EVENT PESERTA", deleteEvent]);
|
||||
}
|
||||
|
||||
for (let event of checkUser?.Event as any) {
|
||||
const deleteEvent = await prisma.event.delete({
|
||||
where: {
|
||||
id: event.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE EVENT", deleteEvent]);
|
||||
}
|
||||
// EVENT DELETE END
|
||||
|
||||
// COLLABORATION START
|
||||
|
||||
for (let project of checkUser?.ProjectCollaboration_Partisipasi as any) {
|
||||
const deleteProject =
|
||||
await prisma.projectCollaboration_Partisipasi.delete({
|
||||
where: {
|
||||
id: project.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE PROJECT PARTISIPASI", deleteProject]);
|
||||
}
|
||||
|
||||
for (let project of checkUser?.ProjectCollaboration_RoomChat as any) {
|
||||
const deleteProject = await prisma.projectCollaboration_RoomChat.delete({
|
||||
where: {
|
||||
id: project.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE PROJECT ROOMCHAT", deleteProject]);
|
||||
}
|
||||
|
||||
for (let project of checkUser?.ProjectCollaboration_AnggotaRoomChat as any) {
|
||||
const deleteProject =
|
||||
await prisma.projectCollaboration_AnggotaRoomChat.delete({
|
||||
where: {
|
||||
id: project.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE PROJECT ANGGOTA ROOMCHAT", deleteProject]);
|
||||
}
|
||||
|
||||
for (let project of checkUser?.ProjectCollaboration_Message as any) {
|
||||
const deleteProject = await prisma.projectCollaboration_Message.delete({
|
||||
where: {
|
||||
id: project.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE PROJECT MESSAGE", deleteProject]);
|
||||
}
|
||||
|
||||
for (let project of checkUser?.ProjectCollaboration as any) {
|
||||
const deleteProject = await prisma.projectCollaboration.delete({
|
||||
where: {
|
||||
id: project.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE PROJECT", deleteProject]);
|
||||
}
|
||||
|
||||
// COLLABORATION END
|
||||
|
||||
// VOTING START
|
||||
for (let voting of checkUser?.Voting_Kontributor as any) {
|
||||
const deleteVotingKontributor = await prisma.voting_Kontributor.delete({
|
||||
where: {
|
||||
id: voting.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE VOTING KONTRIBUTOR", deleteVotingKontributor]);
|
||||
}
|
||||
|
||||
for (let voting of checkUser?.Voting as any) {
|
||||
for (let id of voting?.Voting_DaftarNamaVote as any) {
|
||||
const deleteVotingListName = await prisma.voting_DaftarNamaVote.delete({
|
||||
where: {
|
||||
id: id.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE VOTING LIST NAME", deleteVotingListName]);
|
||||
}
|
||||
|
||||
const deleteVoting = await prisma.voting.delete({
|
||||
where: {
|
||||
id: voting.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE VOTING", deleteVoting]);
|
||||
}
|
||||
// VOTING END
|
||||
|
||||
// JOB START
|
||||
for (let job of checkUser?.Job as any) {
|
||||
if (job.imageId) {
|
||||
const deleteJobImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${job.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteJobImage.ok) {
|
||||
console.log("Success delete job image");
|
||||
}
|
||||
}
|
||||
|
||||
const deleteJob = await prisma.job.delete({
|
||||
where: {
|
||||
id: job.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE JOB", deleteJob]);
|
||||
}
|
||||
// JOB END
|
||||
|
||||
// FORUM START
|
||||
|
||||
for (let forum of checkUser?.Forum_ReportKomentar as any) {
|
||||
const deleteForum = await prisma.forum_ReportKomentar.delete({
|
||||
where: {
|
||||
id: forum.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE FORUM REPORT KOMENTAR", deleteForum]);
|
||||
}
|
||||
|
||||
for (let forum of checkUser?.Forum_ReportPosting as any) {
|
||||
const deleteForum = await prisma.forum_ReportPosting.delete({
|
||||
where: {
|
||||
id: forum.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE FORUM REPORT POSTING", deleteForum]);
|
||||
}
|
||||
|
||||
for (let forum of checkUser?.Forum_Komentar as any) {
|
||||
const deleteForum = await prisma.forum_Komentar.delete({
|
||||
where: {
|
||||
id: forum.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE FORUM KOMENTAR", deleteForum]);
|
||||
}
|
||||
|
||||
for (let forum of checkUser?.Forum_Posting as any) {
|
||||
const deleteForum = await prisma.forum_Posting.delete({
|
||||
where: {
|
||||
id: forum.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE FORUM POSTING", deleteForum]);
|
||||
}
|
||||
// FORUM END
|
||||
|
||||
// INVESTASI START
|
||||
|
||||
for (let invoice of checkUser?.Investasi_Invoice as any) {
|
||||
if (invoice?.imageId) {
|
||||
const deleteInvoiceImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${invoice.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteInvoiceImage.ok) {
|
||||
console.log("Success delete invoice image");
|
||||
}
|
||||
}
|
||||
|
||||
const deleteInvoice = await prisma.investasi_Invoice.delete({
|
||||
where: {
|
||||
id: invoice.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE INVOICE INVESTASI", deleteInvoice]);
|
||||
}
|
||||
|
||||
for (let investasi of checkUser?.Investasi as any) {
|
||||
for (let berita of investasi?.BeritaInvestasi as any) {
|
||||
if (berita?.imageId) {
|
||||
const deleteBeritaImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${berita.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteBeritaImage.ok) {
|
||||
console.log("Success delete image berita investasi");
|
||||
}
|
||||
}
|
||||
const deleteBerita = await prisma.beritaInvestasi.delete({
|
||||
where: {
|
||||
id: berita.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE BERITA INVESTASI", deleteBerita]);
|
||||
}
|
||||
|
||||
for (let dokumen of investasi?.DokumenInvestasi as any) {
|
||||
if (dokumen?.fileId) {
|
||||
const deleteDokumenImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${dokumen.fileId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteDokumenImage.ok) {
|
||||
console.log("Success delete image dokumen investasi");
|
||||
}
|
||||
}
|
||||
const deleteDokumen = await prisma.dokumenInvestasi.delete({
|
||||
where: {
|
||||
id: dokumen.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE DOKUMEN INVESTASI", deleteDokumen]);
|
||||
}
|
||||
|
||||
if (investasi?.prospektusFileId) {
|
||||
const deleteProspektusFile = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${investasi.prospektusFileId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteProspektusFile.ok) {
|
||||
console.log("Success delete prospektus file investasi");
|
||||
}
|
||||
}
|
||||
|
||||
if (investasi?.imageId) {
|
||||
const deleteInvestasiImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${investasi.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteInvestasiImage.ok) {
|
||||
console.log("Success delete image investasi");
|
||||
}
|
||||
}
|
||||
|
||||
const deleteInvestasi = await prisma.investasi.delete({
|
||||
where: {
|
||||
id: investasi.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE INVESTASI", deleteInvestasi]);
|
||||
}
|
||||
// INVESTASI END
|
||||
|
||||
// DONASI START
|
||||
|
||||
for (let donasiInvoice of checkUser?.Donasi_Invoice as any) {
|
||||
if (donasiInvoice?.imageId) {
|
||||
const deleteInvoiceImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${donasiInvoice.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteInvoiceImage.ok) {
|
||||
console.log("Success delete invoice image");
|
||||
}
|
||||
}
|
||||
const deleteInvoice = await prisma.donasi_Invoice.delete({
|
||||
where: {
|
||||
id: donasiInvoice.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE INVOICE DONASI", deleteInvoice]);
|
||||
}
|
||||
|
||||
for (let donasi of checkUser?.Donasi as any) {
|
||||
for (let kabar of donasi?.Donasi_Kabar as any) {
|
||||
if (kabar?.imageId) {
|
||||
const deleteKabarImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${kabar.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteKabarImage.ok) {
|
||||
console.log("Success delete kabar image");
|
||||
}
|
||||
}
|
||||
const deleteKabar = await prisma.donasi_Kabar.delete({
|
||||
where: {
|
||||
id: kabar.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE KABAR DONASI", deleteKabar]);
|
||||
}
|
||||
|
||||
for (let pencairanDana of donasi?.Donasi_PencairanDana as any) {
|
||||
if (pencairanDana?.imageId) {
|
||||
const deletePencairanDanaImage = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${pencairanDana.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deletePencairanDanaImage.ok) {
|
||||
console.log("Success delete pencairan dana image");
|
||||
}
|
||||
}
|
||||
|
||||
const deletePencairanDana = await prisma.donasi_PencairanDana.delete({
|
||||
where: {
|
||||
id: pencairanDana.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE PENCAIRAN DANA DONASI", deletePencairanDana]);
|
||||
}
|
||||
|
||||
const deleteImageCerita = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${donasi?.CeritaDonasi?.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteImageCerita.ok) {
|
||||
console.log("Success delete image cerita donasi");
|
||||
}
|
||||
|
||||
const deleteCerita = await prisma.donasi_Cerita.delete({
|
||||
where: {
|
||||
donasiId: donasi.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE CERITA DONASI", deleteCerita]);
|
||||
|
||||
const deleteImageDonasi = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${donasi?.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteImageDonasi.ok) {
|
||||
console.log("Success delete image donasi");
|
||||
}
|
||||
|
||||
const deleteDonasi = await prisma.donasi.delete({
|
||||
where: {
|
||||
id: donasi.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE DONASI", deleteDonasi]);
|
||||
}
|
||||
|
||||
// DONASI END
|
||||
|
||||
// PORTOFOLIO DELETE START
|
||||
for (const portofolio of checkUser?.Profile?.Portofolio as any) {
|
||||
if (portofolio?.BusinessMaps?.id) {
|
||||
const deleteLogo = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${portofolio?.BusinessMaps?.imageId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteLogo.ok) {
|
||||
console.log("Success delete logo");
|
||||
}
|
||||
|
||||
const deleteMaps = await prisma.businessMaps.delete({
|
||||
where: {
|
||||
id: portofolio?.BusinessMaps?.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE MAPS", deleteMaps]);
|
||||
}
|
||||
|
||||
if (portofolio?.Portofolio_MediaSosial?.id) {
|
||||
const deleteSosialMedia = await prisma.portofolio_MediaSosial.delete({
|
||||
where: {
|
||||
portofolioId: portofolio.id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE SOSIAL MEDIA", deleteSosialMedia]);
|
||||
}
|
||||
|
||||
if (portofolio?.logoId) {
|
||||
const deleteLogo = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${portofolio?.logoId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (deleteLogo.ok) {
|
||||
console.log("Success delete logo");
|
||||
}
|
||||
}
|
||||
|
||||
const deletePortofolio = await prisma.portofolio.delete({
|
||||
where: {
|
||||
id: portofolio.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(["DELETE PORTOFOLIO", deletePortofolio]);
|
||||
}
|
||||
|
||||
const deleteProfile = await prisma.profile.delete({
|
||||
where: {
|
||||
userId: id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE PROFILE", deleteProfile]);
|
||||
// PORTOFOLIO DELETE END
|
||||
|
||||
const deleteUser = await prisma.user.delete({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
});
|
||||
console.log(["DELETE USER", deleteUser]);
|
||||
|
||||
console.log("[END DELETE ALL >>>]");
|
||||
|
||||
return NextResponse.json(
|
||||
{ success: true, message: "Berhasil menghapus data" },
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(["ERROR DELETE ALL", error]);
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error delete data from API ",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
68
src/app/api/mobile/user/[id]/terms-of-app/route.ts
Normal file
68
src/app/api/mobile/user/[id]/terms-of-app/route.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib";
|
||||
|
||||
export { POST };
|
||||
|
||||
async function POST(request: Request, { params }: { params: { id: string } }) {
|
||||
const { id } = params;
|
||||
const { searchParams } = new URL(request.url);
|
||||
const category = searchParams.get("category");
|
||||
|
||||
console.log("[ID USER", id);
|
||||
console.log("[SEARCH PARAMS", category);
|
||||
|
||||
try {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "User not found",
|
||||
},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
const updateUser = await prisma.user.update({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
data: {
|
||||
acceptedForumTermsAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
if (!updateUser) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Gagal mengupdate data",
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: true,
|
||||
message: "Syarat dan Ketentuan berhasil diterima",
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Error update data from API ",
|
||||
reason: (error as Error).message,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -65,14 +65,23 @@ async function GET(request: Request) {
|
||||
const search = searchParams.get("search");
|
||||
const category = searchParams.get("category");
|
||||
const authorId = searchParams.get("authorId");
|
||||
const userLoginId = searchParams.get("userLoginId");
|
||||
|
||||
console.log("userLoginId >>", userLoginId);
|
||||
|
||||
let fixData;
|
||||
|
||||
try {
|
||||
if (category === "beranda") {
|
||||
fixData = await prisma.voting.findMany({
|
||||
if (!userLoginId) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "User ID required" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
const data = await prisma.voting.findMany({
|
||||
orderBy: {
|
||||
updatedAt: "desc",
|
||||
awalVote: "asc",
|
||||
},
|
||||
where: {
|
||||
voting_StatusId: "1",
|
||||
@@ -85,6 +94,13 @@ async function GET(request: Request) {
|
||||
contains: search || "",
|
||||
mode: "insensitive",
|
||||
},
|
||||
NOT: {
|
||||
Voting_Kontributor: {
|
||||
some: {
|
||||
authorId: userLoginId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
Voting_DaftarNamaVote: {
|
||||
|
||||
@@ -60,12 +60,14 @@ async function seederUser() {
|
||||
username: i.name,
|
||||
masterUserRoleId: i.masterUserRoleId,
|
||||
active: i.active,
|
||||
termsOfServiceAccepted: i.termsOfServiceAccepted,
|
||||
},
|
||||
update: {
|
||||
nomor: i.nomor,
|
||||
username: i.name,
|
||||
masterUserRoleId: i.masterUserRoleId,
|
||||
active: i.active,
|
||||
termsOfServiceAccepted: i.termsOfServiceAccepted,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -564,10 +566,12 @@ async function masterKategoriApp() {
|
||||
create: {
|
||||
id: a.id,
|
||||
name: a.name,
|
||||
value: a.value,
|
||||
},
|
||||
update: {
|
||||
id: a.id,
|
||||
name: a.name,
|
||||
value: a.value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ export async function adminInvestasi_funAcceptTransaksiById({
|
||||
invoiceId: string;
|
||||
investasiId: string;
|
||||
lembarTerbeli: string;
|
||||
}) {
|
||||
console.log("Ini invoiceid", invoiceId)
|
||||
console.log("Ini investasid", investasiId)
|
||||
console.log("Ini lembar terbeli", lembarTerbeli)
|
||||
}) {
|
||||
console.log("Ini invoiceid", invoiceId);
|
||||
console.log("Ini investasid", investasiId);
|
||||
console.log("Ini lembar terbeli", lembarTerbeli);
|
||||
|
||||
const dataInvestasi: any = await prisma.investasi.findFirst({
|
||||
where: {
|
||||
@@ -50,7 +50,6 @@ export async function adminInvestasi_funAcceptTransaksiById({
|
||||
statusInvoiceId: "1",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
if (!updt) {
|
||||
return { status: 400, message: "Gagal Update Status" };
|
||||
@@ -87,6 +86,3 @@ export async function adminInvestasi_funAcceptTransaksiById({
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Software Developer"
|
||||
"name": "Software Development"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
|
||||
@@ -1,30 +1,37 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Event"
|
||||
"name": "Event",
|
||||
"value": "event"
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Job"
|
||||
"name": "Job",
|
||||
"value": "job"
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"name": "Voting"
|
||||
"name": "Voting",
|
||||
"value": "voting"
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"name": "Donasi"
|
||||
"name": "Donasi",
|
||||
"value": "donasi"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"name": "Investasi"
|
||||
"name": "Investasi",
|
||||
"value": "investasi"
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"name": "Forum"
|
||||
"name": "Forum",
|
||||
"value": "forum"
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"name": "Collaboration"
|
||||
"name": "Collaboration",
|
||||
"value": "collaboration"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
[
|
||||
{
|
||||
"name": "bagas_admin",
|
||||
"name": "default_user",
|
||||
"nomor": "6282340374412",
|
||||
"masterUserRoleId": "1",
|
||||
"active": true,
|
||||
"termsOfServiceAccepted": false
|
||||
},
|
||||
{
|
||||
"name": "admin_911",
|
||||
"nomor": "6281339158911",
|
||||
"masterUserRoleId": "3",
|
||||
"active": true
|
||||
"active": true,
|
||||
"termsOfServiceAccepted": false
|
||||
},
|
||||
{
|
||||
"name": "fahmi_admin",
|
||||
"nomor": "628123833845",
|
||||
"masterUserRoleId": "2",
|
||||
"active": true
|
||||
"active": true,
|
||||
"termsOfServiceAccepted": false
|
||||
}
|
||||
]
|
||||
|
||||
@@ -18,6 +18,10 @@ const CONFIG: MiddlewareConfig = {
|
||||
userPath: "/dev/home",
|
||||
publicRoutes: [
|
||||
"/",
|
||||
"/.well-known/*",
|
||||
"/terms-of-service.html",
|
||||
"/privacy-policy.html",
|
||||
"/api/helper/*",
|
||||
"/api/not-user/*",
|
||||
"/api/voting/*",
|
||||
"/api/collaboration/*",
|
||||
@@ -36,6 +40,8 @@ const CONFIG: MiddlewareConfig = {
|
||||
"/register",
|
||||
"/validasi",
|
||||
"/splash",
|
||||
"/support-center",
|
||||
"/delete-account",
|
||||
"/invalid-user",
|
||||
"/job-vacancy/*",
|
||||
"/preview-image",
|
||||
@@ -45,6 +51,7 @@ const CONFIG: MiddlewareConfig = {
|
||||
"/zCoba/*",
|
||||
"/aset/global/main_background.png",
|
||||
"/aset/logo/logo-hipmi.png",
|
||||
"/aset/logo/hiconnect.png",
|
||||
],
|
||||
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||
|
||||
@@ -23,6 +23,6 @@
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/app_modules/investasi/proses_transaksi/view.jsx", "src/app/api/investasi/midtrans/[id]/route.ts", "src/app_modules/job/create/TextEdit.tsx"],
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/app_modules/investasi/proses_transaksi/view.jsx", "src/app/api/investasi/midtrans/[id]/route.ts", "src/app_modules/job/create/TextEdit.tsx", "src/app/api/mobile/forum/[id]/report-comment/route.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
4
types/env.d.ts
vendored
4
types/env.d.ts
vendored
@@ -9,7 +9,7 @@ declare namespace NodeJS {
|
||||
NEXT_PUBLIC_WIBU_REALTIME_TOKEN?: string;
|
||||
NEXT_PUBLIC_BASE_TOKEN_KEY?: string;
|
||||
NEXT_PUBLIC_BASE_SESSION_KEY?: string;
|
||||
NEXT_PUBLIC_API_URL?: string;
|
||||
RESEND_APIKEY?: string;
|
||||
WA_SERVER_TOKEN?: string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user