Compare commits

...

29 Commits

Author SHA1 Message Date
6ee0b98f07 Fix Apple Reject
Add:
- prisma/migrations/20251208042529_add_accepted_terms_at/
- prisma/schema.prisma.backup
- src/app/api/mobile/user/[id]/terms-of-app/

Fix:

prisma/schema.prisma
src/app/api/auth/mobile-register/route.ts
src/app/api/mobile/forum/[id]/report-commentar/route.ts
src/app/api/mobile/forum/[id]/report-posting/route.ts

### No Issue
2025-12-08 15:29:12 +08:00
cc78d82ca4 chore(release): 1.5.24 2025-12-08 15:23:52 +08:00
3c2a8b3543 Fix QC Admin ( Inno )
- app.config.js
- app/(application)/(user)/forum/[id]/edit.tsx
- app/(application)/(user)/forum/[id]/index.tsx
- app/(application)/(user)/forum/create.tsx
- ios/HIPMIBadungConnect/Info.plist

### No Issue
2025-12-05 17:12:15 +08:00
276cf9e970 Fix QC Inno:
Fix:
- src/app/api/mobile/investment/[id]/news/route.ts

Add:
- src/app/api/mobile/admin/master/donation/

### No Issue
2025-12-04 17:43:09 +08:00
8ccf722c90 Fix wa server 2025-12-03 16:25:53 +08:00
7ad7b3496a chore(release): 1.5.22 2025-12-03 16:25:52 +08:00
c9c39f319c chore(release): 1.5.21 2025-12-03 14:58:17 +08:00
c976e6beaf Fix reject Apple :
Add:
src/app/api/auth/mobile-login/
        src/app/api/auth/mobile-register/
        src/app/api/auth/mobile-validasi/

Fix:
 modified:   bun.lock
        modified:   package.json
        modified:   src/app/api/mobile/voting/route.ts

### No Issue
2025-12-03 14:58:03 +08:00
4b21084748 Perubahan flow auth:
User ada : Login > Kode OTP > home
User tidak ada : Login > Register > Kote OTP > home

Add:
src/app/api/mobile/auth

### No Issue
2025-12-02 14:06:52 +08:00
3277d8cb19 chore(release): 1.5.20 2025-12-02 14:04:17 +08:00
b951c698c5 QC : Pak jun dan Inno
Fix:
modified:   src/app/api/mobile/portofolio/[id]/route.ts
modified:   src/app/api/mobile/voting/route.ts
modified:   src/bin/seeder/colab/master_industri.json

### No Issue
2025-12-01 17:39:42 +08:00
ad91a48d82 chore(release): 1.5.19 2025-12-01 17:37:19 +08:00
a06036cab7 Fix version 1.5.18 2025-11-28 11:46:41 +08:00
c3d8ccd490 chore(release): 1.5.18 2025-11-28 11:46:04 +08:00
ba6a83f61d Merge pull request 'Push Staging V 1.5.17' (#18) from push-staging/28-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/18
2025-11-28 11:24:15 +08:00
dc05c4ef7e Push Staging
### No Issue
2025-11-28 11:20:42 +08:00
d56a00a92b Merge pull request 'Penambahan fitur open blockir' (#17) from apple-reject/28-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/17
2025-11-28 10:49:04 +08:00
43deddca43 Penambahan fitur open blockir
Add:
- src/app/api/mobile/block-user/[id]/

Fix:
-src/app/api/mobile/block-user/route.ts

### No Issue
2025-11-28 10:48:18 +08:00
1e647c0391 Merge pull request 'Fix Apple Rejected' (#16) from fix-mobile/26-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/16
2025-11-27 12:18:18 +08:00
6f10ff7c3e API mobile forum
### No Issue
2025-11-26 16:16:08 +08:00
09be7739d5 Fix rejected Apple:
Penambahan fitur checklist terms of service dan penambahan database blockuser

Add:
- prisma/migrations/20251124061947_add_terms_of_service_accepted/
- prisma/migrations/20251124081155_add_blocked_user_and_menu_feature/
- prisma/migrations/20251124083155_fix_master_kategori_app_and_delete_menu_feature/
- public/terms-of-service.html
- src/app/api/auth/term-service/

Fix:
- prisma/schema.prisma
- src/app/api/auth/register/route.ts
- src/app/api/auth/validasi/route.ts
- src/app_modules/_global/fun/generate_seeder.ts
- src/bin/seeder/master/master_kategori_app.json
- src/bin/seeder/user_seeder.json
- src/middleware.tsx

### No Issue
2025-11-24 16:44:00 +08:00
38734cda8c chore(release): 1.5.17 2025-11-24 11:48:20 +08:00
94dc780ead Merge pull request 'Fix Rejected Apple' (#15) from fix-mobile/20-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/15
2025-11-20 15:40:50 +08:00
c710ca60b7 Merge pull request 'Route: Delete Account' (#14) from fix-mobile/19-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/14
2025-11-19 17:49:17 +08:00
4164092100 Merge pull request 'Delete Account & Support Center fix' (#13) from fix-mobile/18-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/13
2025-11-18 14:04:14 +08:00
b118a6425c Merge pull request 'Fix Apple Rejected' (#12) from fix-mobile/17-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/12
2025-11-17 17:48:05 +08:00
09e1f702e1 Merge pull request 'fix-mobile/17-nov-25' (#11) from fix-mobile/17-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/11
2025-11-17 11:30:49 +08:00
ba5620bcc5 Merge pull request 'QRCode Mobile' (#10) from mobile-qrcode/13-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/10
2025-11-13 17:14:03 +08:00
24e6fcd0f7 Merge pull request 'Penambahan akses untuk metode scan QRCode:' (#9) from mobile-access/12-nov-25 into staging
Reviewed-on: http://wibugit.wibudev.com/wibu/hipmi/pulls/9
2025-11-12 16:38:49 +08:00
41 changed files with 2585 additions and 100 deletions

View File

@@ -2,6 +2,25 @@
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)

View File

@@ -41,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",
@@ -1388,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=="],
@@ -3474,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=="],
@@ -3482,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=="],
@@ -3640,6 +3645,8 @@
"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=="],
@@ -4074,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=="],

View File

@@ -1,6 +1,6 @@
{
"name": "hipmi",
"version": "1.5.16",
"version": "1.5.24",
"private": true,
"prisma": {
"seed": "bun prisma/seed.ts"
@@ -52,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",

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "acceptedForumTermsAt" TIMESTAMP(3),
ADD COLUMN "acceptedTermsAt" TIMESTAMP(3);

View File

@@ -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

File diff suppressed because it is too large Load Diff

View 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>

View 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 }
);
}
}

View 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 }
);
}
}

View 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 }
);
}
}

View File

@@ -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();
}
}

View 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",
});
}
}

View File

@@ -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();
}
}

View File

@@ -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") {

View File

@@ -29,6 +29,11 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
},
},
},
Event: {
select: {
tanggal: true,
},
},
},
});

View File

@@ -153,6 +153,7 @@ async function GET(request: Request) {
select: {
id: true,
title: true,
tanggal: true,
Author: {
select: {
id: true,

View 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,
});
}
}

View 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,
});
}
}

View 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 }
);
}
}

View 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 }
);
}
}

View 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 }
);
}
}

View 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,
});
}
}

View 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,
});
}
}

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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({

View File

@@ -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,

View 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,
});
}
}

View File

@@ -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);
}

View 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 }
);
}
}

View File

@@ -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: {

View File

@@ -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,
},
});
}

View File

@@ -1,7 +1,7 @@
[
{
"id": 1,
"name": "Software Developer"
"name": "Software Development"
},
{
"id": 2,

View File

@@ -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"
}
]

View File

@@ -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
}
]

View File

@@ -19,6 +19,7 @@ const CONFIG: MiddlewareConfig = {
publicRoutes: [
"/",
"/.well-known/*",
"/terms-of-service.html",
"/privacy-policy.html",
"/api/helper/*",
"/api/not-user/*",

View File

@@ -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
View File

@@ -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;
}
}