Merge pull request #13 from bipprojectbali/stg

Stg
This commit is contained in:
2026-04-06 11:34:48 +08:00
committed by GitHub
4 changed files with 63 additions and 26 deletions

View File

@@ -11,6 +11,9 @@ SEAFILE_PUBLIC_SHARE_TOKEN=your_seafile_public_share_token
WIBU_UPLOAD_DIR=uploads WIBU_UPLOAD_DIR=uploads
WIBU_DOWNLOAD_DIR=./download WIBU_DOWNLOAD_DIR=./download
# WhatsApp Server Configuration
WA_SERVER_TOKEN=your_whatsapp_server_token
# Application Configuration # Application Configuration
# IMPORTANT: For staging/production, set this to your actual domain # IMPORTANT: For staging/production, set this to your actual domain
# Local development: NEXT_PUBLIC_BASE_URL=http://localhost:3000 # Local development: NEXT_PUBLIC_BASE_URL=http://localhost:3000

View File

@@ -0,0 +1,32 @@
// app/api/auth/_lib/sendCodeOtp.ts
const sendCodeOtp = async ({
nomor,
codeOtp,
newMessage,
}: {
nomor: string;
codeOtp?: string | number;
newMessage?: string;
}) => {
const msg =
newMessage ||
`Website Desa Darmasaba - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun Admin lainnya.\n\n>> Kode OTP anda: ${codeOtp}.`;
const enCode = msg;
const res = await fetch(`https://otp.wibudev.com/api/wa/send-text`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.WA_SERVER_TOKEN}`,
},
body: JSON.stringify({
number: nomor,
text: enCode,
}),
});
return res;
};
export { sendCodeOtp };

View File

@@ -2,16 +2,10 @@
import prisma from "@/lib/prisma"; import prisma from "@/lib/prisma";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { randomOTP } from "../_lib/randomOTP"; import { randomOTP } from "../_lib/randomOTP";
import { sendCodeOtp } from "../_lib/sendCodeOtp";
import { cookies } from "next/headers"; import { cookies } from "next/headers";
export async function POST(req: Request) { export async function POST(req: Request) {
if (req.method !== "POST") {
return NextResponse.json(
{ success: false, message: "Method Not Allowed" },
{ status: 405 }
);
}
try { try {
const { nomor } = await req.json(); const { nomor } = await req.json();
@@ -35,26 +29,33 @@ export async function POST(req: Request) {
console.log(`🔑 DEBUG OTP [${nomor}]: ${codeOtp}`); console.log(`🔑 DEBUG OTP [${nomor}]: ${codeOtp}`);
const waMessage = `Website Desa Darmasaba - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun Admin lainnya.\n\n>> Kode OTP anda: ${codeOtp}.`;
const waUrl = `https://wa.wibudev.com/code?nom=${encodeURIComponent(nomor)}&text=${encodeURIComponent(waMessage)}`;
console.log("🔍 Debug WA URL:", waUrl);
try { try {
const res = await fetch(waUrl); const waResponse = await sendCodeOtp({
if (!res.ok) { nomor,
console.error(`⚠️ WA Service HTTP Error: ${res.status} ${res.statusText}. Continuing since OTP is logged.`); codeOtp,
});
if (!waResponse.ok) {
console.error(
`⚠️ WA Service HTTP Error: ${waResponse.status} ${waResponse.statusText}. Continuing since OTP is logged.`
);
console.log(`💡 Use this OTP to login: ${codeOtp}`); console.log(`💡 Use this OTP to login: ${codeOtp}`);
} else { } else {
const sendWa = await res.json(); const sendWa = await waResponse.json();
console.log("📱 WA Response:", sendWa); console.log("📱 WA Response:", sendWa);
if (sendWa.status !== "success") { if (sendWa.status !== "success") {
console.error("⚠️ WA Service Logic Error:", sendWa); console.error("⚠️ WA Service Logic Error:", sendWa);
} }
} }
} catch (waError: unknown) { } catch (waError: unknown) {
const errorMessage = waError instanceof Error ? waError.message : String(waError); const errorMessage =
console.error("⚠️ WA Connection Exception. Continuing since OTP is logged.", errorMessage); waError instanceof Error ? waError.message : String(waError);
console.error(
"⚠️ WA Connection Exception. Continuing since OTP is logged.",
errorMessage
);
} }
const createOtpId = await prisma.kodeOtp.create({ const createOtpId = await prisma.kodeOtp.create({
@@ -62,12 +63,12 @@ export async function POST(req: Request) {
}); });
const cookieStore = await cookies(); const cookieStore = await cookies();
cookieStore.set('auth_flow', 'login', { cookieStore.set("auth_flow", "login", {
httpOnly: true, httpOnly: true,
secure: process.env.NODE_ENV === 'production', secure: process.env.NODE_ENV === "production",
sameSite: 'lax', sameSite: "lax",
maxAge: 60 * 5, // 5 menit maxAge: 60 * 5,
path: '/' path: "/",
}); });
return NextResponse.json({ return NextResponse.json({
@@ -85,6 +86,7 @@ export async function POST(req: Request) {
} }
} catch (error) { } catch (error) {
console.error("❌ Error Login:", error); console.error("❌ Error Login:", error);
return NextResponse.json( return NextResponse.json(
{ success: false, message: "Terjadi kesalahan saat login" }, { success: false, message: "Terjadi kesalahan saat login" },
{ status: 500 } { status: 500 }

View File

@@ -1,4 +1,4 @@
import { Paper, Title, Progress, Stack, Text, Group, Box } from '@mantine/core' import { Paper, Title, Progress, Stack, Text, Group, Box, type MantineColor } from '@mantine/core'
import { IconArrowUpRight, IconArrowDownRight } from '@tabler/icons-react' import { IconArrowUpRight, IconArrowDownRight } from '@tabler/icons-react'
import { APBDes, APBDesItem } from '../types/apbdes' import { APBDes, APBDesItem } from '../types/apbdes'
@@ -106,7 +106,7 @@ function Summary({ title, data, icon }: SummaryProps) {
<Text <Text
fz="xs" fz="xs"
c={statusMessage.color} c={statusMessage.color as MantineColor}
fw={600} fw={600}
style={{ style={{
backgroundColor: `var(--mantine-color-${statusMessage.color}-0)`, backgroundColor: `var(--mantine-color-${statusMessage.color}-0)`,