Compare commits

...

18 Commits

Author SHA1 Message Date
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
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
11 changed files with 439 additions and 15 deletions

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "hipmi",
"version": "1.5.17",
"version": "1.5.20",
"private": true,
"prisma": {
"seed": "bun prisma/seed.ts"

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

@@ -2,7 +2,7 @@ import _ from "lodash";
import { NextResponse } from "next/server";
import prisma from "@/lib/prisma";
export { POST };
export { POST, GET };
async function POST(request: Request) {
const { data } = await request.json();
@@ -45,3 +45,65 @@ async function POST(request: Request) {
});
}
}
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

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

@@ -72,7 +72,7 @@ async function GET(request: Request) {
if (category === "beranda") {
fixData = await prisma.voting.findMany({
orderBy: {
updatedAt: "desc",
awalVote: "asc"
},
where: {
voting_StatusId: "1",

View File

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

View File

@@ -1,16 +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,
"termsOfServiceAccepted": true
"termsOfServiceAccepted": false
},
{
"name": "fahmi_admin",
"nomor": "628123833845",
"masterUserRoleId": "2",
"active": true,
"termsOfServiceAccepted": true
"termsOfServiceAccepted": false
}
]