Fix: validasi
Deksripsi: - Penambahan fitur kirim ulang kode ## No Issue
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hipmi",
|
||||
"version": "1.0.12",
|
||||
"version": "1.1.0",
|
||||
"private": true,
|
||||
"prisma": {
|
||||
"seed": "npx tsx prisma/seed.ts"
|
||||
@@ -88,7 +88,6 @@
|
||||
"utf-8-validate": "^6.0.3",
|
||||
"uuid": "^9.0.1",
|
||||
"wibu": "bipproduction/wibu",
|
||||
"wibu-realtime": "bipproduction/wibu-realtime",
|
||||
"yaml": "^2.3.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
||||
export default async function Page({ params }: { params: { id: string } }) {
|
||||
let kodeId = params.id;
|
||||
const dataOtp = await auth_getCodeOtpByNumber({ kodeId: kodeId });
|
||||
if (dataOtp === null) return redirect(RouterAuth.login);
|
||||
// if (dataOtp === null) return redirect(RouterAuth.login);
|
||||
|
||||
return <Validasi dataOtp={dataOtp} />;
|
||||
return <Validasi dataOtp={dataOtp as any} />;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import ComponentGlobal_HeaderTamplate from "@/app_modules/_global/header_tamplate";
|
||||
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
|
||||
import Coba_TestLoading from "@/app_modules/zCoba";
|
||||
import { Text } from "@mantine/core";
|
||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
||||
import { CobaRealtime } from "@/app_modules/zCoba/coba_realtime";
|
||||
|
||||
export default async function Page() {
|
||||
await new Promise((a, b) => {
|
||||
setTimeout(a, 3000);
|
||||
});
|
||||
|
||||
const userLoginId = await funGetUserIdByToken();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Coba_TestLoading />
|
||||
<CobaRealtime userLoginId={userLoginId} />
|
||||
{/* <Coba_TestLoading userLoginId={userLoginId} /> */}
|
||||
{/* <ComponentGlobal_UI_LayoutTamplate /> */}
|
||||
</>
|
||||
);
|
||||
|
||||
40
src/app_modules/auth/fun/fun_resend_code.ts
Normal file
40
src/app_modules/auth/fun/fun_resend_code.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
import { randomOTP } from "./rondom_otp";
|
||||
|
||||
export async function auth_funResendCode({ nomor }: { nomor: string }) {
|
||||
const codeOtp = randomOTP();
|
||||
|
||||
try {
|
||||
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}.
|
||||
`
|
||||
);
|
||||
|
||||
const sendWa = await res.json();
|
||||
if (sendWa.status !== "success")
|
||||
return { status: 400, message: "WA Tidak Terdaftar", kodeId: {} };
|
||||
|
||||
const createOtpId = await prisma.kodeOtp.create({
|
||||
data: {
|
||||
nomor: nomor,
|
||||
otp: codeOtp,
|
||||
},
|
||||
});
|
||||
|
||||
if (!createOtpId)
|
||||
return { status: 400, message: "Gagal Membuat Kode OTP", kodeId: {} };
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
message: "Kode Verifikasi Dikirim",
|
||||
kodeId: createOtpId.id,
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return { status: 500, message: "Server Error !!!", kodeId: {} };
|
||||
}
|
||||
}
|
||||
3
src/app_modules/auth/fun/index.ts
Normal file
3
src/app_modules/auth/fun/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { auth_funResendCode } from "./fun_resend_code";
|
||||
|
||||
export { auth_funResendCode };
|
||||
@@ -3,15 +3,16 @@
|
||||
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
|
||||
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
||||
import { GlobalEnv } from "@/app/lib/token";
|
||||
import {
|
||||
AccentColor,
|
||||
MainColor,
|
||||
} from "@/app_modules/_global/color/color_pallet";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
||||
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
||||
import {
|
||||
ActionIcon,
|
||||
BackgroundImage,
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
@@ -20,23 +21,33 @@ import {
|
||||
Text,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { useFocusTrap } from "@mantine/hooks";
|
||||
import { useFocusTrap, useShallowEffect } from "@mantine/hooks";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { IconChevronLeft } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { auth_funResendCode } from "../fun";
|
||||
import { auth_funDeleteAktivasiKodeOtpById } from "../fun/fun_edit_aktivasi_kode_otp_by_id";
|
||||
import { auth_funValidasi } from "../fun/fun_validasi";
|
||||
import { GlobalEnv } from "@/app/lib/token";
|
||||
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
||||
|
||||
export default function Validasi({ dataOtp }: { dataOtp: any }) {
|
||||
export default function Validasi({
|
||||
dataOtp,
|
||||
}: {
|
||||
dataOtp: Prisma.KodeOtpSelect;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [nomor, setnomor] = useState(dataOtp.nomor);
|
||||
const [code, setCode] = useState(dataOtp.otp);
|
||||
const nomor = dataOtp.nomor as any;
|
||||
const code = dataOtp.otp as any;
|
||||
const [inputCode, setInputOtp] = useState("");
|
||||
const focusTrapRef = useFocusTrap();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const [counter, setCounter] = useState(60);
|
||||
|
||||
useShallowEffect(() => {
|
||||
counter > 0 && setTimeout(() => setCounter(counter - 1), 1000);
|
||||
}, [counter]);
|
||||
|
||||
async function onVerifikasi() {
|
||||
if (!inputCode)
|
||||
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Kode");
|
||||
@@ -48,7 +59,9 @@ export default function Validasi({ dataOtp }: { dataOtp: any }) {
|
||||
HIPMI_PWD: GlobalEnv.value?.WIBU_PWD as string,
|
||||
});
|
||||
if (res.status === 200) {
|
||||
const resAktivasi = await auth_funDeleteAktivasiKodeOtpById(dataOtp.id);
|
||||
const resAktivasi = await auth_funDeleteAktivasiKodeOtpById(
|
||||
dataOtp.id as any
|
||||
);
|
||||
if (resAktivasi.status === 200) {
|
||||
if (res.role === "1") {
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
||||
@@ -85,6 +98,16 @@ export default function Validasi({ dataOtp }: { dataOtp: any }) {
|
||||
router.back();
|
||||
}
|
||||
|
||||
async function onResendCode() {
|
||||
const res = await auth_funResendCode({ nomor: nomor });
|
||||
if (res.status === 200) {
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
|
||||
router.push(RouterAuth.validasi + res.kodeId, { scroll: false });
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutDefault>
|
||||
@@ -102,24 +125,25 @@ export default function Validasi({ dataOtp }: { dataOtp: any }) {
|
||||
</ActionIcon>
|
||||
</Box>
|
||||
|
||||
<Stack align="center" justify="center" h={"100vh"} spacing={70}>
|
||||
<Stack align="center" justify="center" h={"100vh"} spacing={50}>
|
||||
<Title order={2} color={MainColor.yellow}>
|
||||
Verifikasi Kode OTP
|
||||
</Title>
|
||||
|
||||
<Stack spacing={0} align="center">
|
||||
<Text fz={"xs"} c={"white"}>
|
||||
Masukan 4 digit kode otp
|
||||
</Text>
|
||||
<Text fz={"xs"} c={"white"}>
|
||||
Yang dikirim ke{" "}
|
||||
<Text span inherit fw={"bold"}>
|
||||
{" "}
|
||||
+{nomor}
|
||||
<Stack spacing={"md"} align="center">
|
||||
<Stack spacing={0} align="center">
|
||||
<Text c={"white"}>Masukan 4 digit kode otp</Text>
|
||||
<Text c={"white"}>
|
||||
Yang dikirim ke{" "}
|
||||
<Text span inherit fw={"bold"}>
|
||||
{" "}
|
||||
+{nomor}
|
||||
</Text>
|
||||
</Text>
|
||||
</Text>
|
||||
</Stack>
|
||||
<Center>
|
||||
<PinInput
|
||||
size="xl"
|
||||
type={"number"}
|
||||
ref={focusTrapRef}
|
||||
spacing={"md"}
|
||||
@@ -129,6 +153,19 @@ export default function Validasi({ dataOtp }: { dataOtp: any }) {
|
||||
}}
|
||||
/>
|
||||
</Center>
|
||||
|
||||
<Text fs="italic" mt={"sm"} c={"white"}>
|
||||
Tidak menerima kode ?{" "}
|
||||
{counter > 0 ? (
|
||||
<Text fw={"bold"} inherit span>
|
||||
{counter + "s"}
|
||||
</Text>
|
||||
) : (
|
||||
<Text inherit span onClick={() => onResendCode()}>
|
||||
Kirim ulang
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Button
|
||||
w={300}
|
||||
|
||||
@@ -11,15 +11,15 @@ export function CheckCookies_UiLayout({
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
useShallowEffect(() => {
|
||||
onCheckCookies();
|
||||
}, []);
|
||||
// useShallowEffect(() => {
|
||||
// onCheckCookies();
|
||||
// }, []);
|
||||
|
||||
async function onCheckCookies() {
|
||||
const cek = await fetch("/api/check-cookies");
|
||||
const result = await cek.json();
|
||||
if (result.success === false) {
|
||||
router.push(RouterAuth.login);
|
||||
router.push(RouterAuth.login, { scroll: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
48
src/app_modules/zCoba/coba_realtime.tsx
Normal file
48
src/app_modules/zCoba/coba_realtime.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
"use client";
|
||||
|
||||
import { useWibuRealtime, WibuRealtime } from "wibu";
|
||||
import { v4 } from "uuid";
|
||||
import { Stack, Title, Button } from "@mantine/core";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import Countdown from "react-countdown";
|
||||
|
||||
export function CobaRealtime({ userLoginId }: { userLoginId: string }) {
|
||||
const WIBU_REALTIME_TOKEN: any = process.env.NEXT_PUBLIC_WIBU_REALTIME_TOKEN;
|
||||
|
||||
// const [dataRealTime, setDataRealTime] = useWibuRealtime({
|
||||
// WIBU_REALTIME_TOKEN: WIBU_REALTIME_TOKEN,
|
||||
// project: "hipmi",
|
||||
// });
|
||||
|
||||
useShallowEffect(() => {
|
||||
// WibuRealtime.init({
|
||||
// WIBU_REALTIME_TOKEN: WIBU_REALTIME_TOKEN,
|
||||
// project: "hipmi",
|
||||
// onData(data) {
|
||||
// console.log(data);
|
||||
// },
|
||||
// });
|
||||
// return () => {
|
||||
// WibuRealtime.cleanup();
|
||||
// };
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack w={200} p={"lg"}>
|
||||
<Title order={6}>User {userLoginId}</Title>
|
||||
<Button
|
||||
onClick={() => {
|
||||
// WibuRealtime.setData({
|
||||
// id: v4(),
|
||||
// name: "bagas",
|
||||
// age: 28,
|
||||
// });
|
||||
}}
|
||||
>
|
||||
Cek
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,17 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Button,
|
||||
Stack
|
||||
} from "@mantine/core";
|
||||
import { ActionIcon, Box, Button, Stack, Title } from "@mantine/core";
|
||||
import { useState } from "react";
|
||||
|
||||
import { IconPencilPlus } from "@tabler/icons-react";
|
||||
import _ from "lodash";
|
||||
import UIGlobal_LayoutTamplate from "../_global/ui/ui_layout_tamplate";
|
||||
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { WibuRealtime } from "wibu";
|
||||
import { v4 } from "uuid";
|
||||
|
||||
const newData = Array(20)
|
||||
.fill(0)
|
||||
@@ -35,89 +32,84 @@ const data2 = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function Coba_TestLoading() {
|
||||
const [data, setData] = useState(data2);
|
||||
export default function Coba_TestLoading({
|
||||
userLoginId,
|
||||
}: {
|
||||
userLoginId: string;
|
||||
}) {
|
||||
// const [data, setData] = useState(data2);
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [newData, setNewData] = useState({});
|
||||
|
||||
useShallowEffect(() => {
|
||||
WibuRealtime.init({
|
||||
WIBU_REALTIME_TOKEN: process.env.WIBU_REALTIME_KEY as any,
|
||||
project: "hipmi",
|
||||
onData(data) {
|
||||
console.log(data);
|
||||
},
|
||||
});
|
||||
|
||||
return () => {
|
||||
WibuRealtime.cleanup();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate>
|
||||
{/* <CreateButton /> */}
|
||||
<Button onClick={() => setOpenDrawer(true)}>Click</Button>
|
||||
</UIGlobal_LayoutTamplate>
|
||||
|
||||
<Stack w={200} p={"lg"}>
|
||||
<Title>User {userLoginId}</Title>
|
||||
<Button
|
||||
onClick={() => {
|
||||
WibuRealtime.setData({
|
||||
id: v4(),
|
||||
userId: userLoginId,
|
||||
data: `Ini dari user ${userLoginId}`,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Cek
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
|
||||
// return (
|
||||
// <>
|
||||
// <UIGlobal_LayoutTamplate>
|
||||
// {/* <CreateButton /> */}
|
||||
// <Button onClick={() => setOpenDrawer(true)}>Click</Button>
|
||||
// </UIGlobal_LayoutTamplate>
|
||||
// </>
|
||||
// );
|
||||
|
||||
// Clone data
|
||||
return (
|
||||
<>
|
||||
<Box mt={"lg"}>
|
||||
<Stack>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const clone = _.clone(data);
|
||||
const dataBaru = clone.map(
|
||||
(e) => (
|
||||
e.id === 1,
|
||||
{
|
||||
...e,
|
||||
name: e.id === 1 ? "firman" : e.name,
|
||||
age: e.id === 1 ? 30 : e.age,
|
||||
}
|
||||
)
|
||||
);
|
||||
setData(dataBaru);
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</Stack>
|
||||
// return (
|
||||
// <>
|
||||
// <Box mt={"lg"}>
|
||||
// <Stack>
|
||||
// <Button
|
||||
// onClick={() => {
|
||||
// const clone = _.clone(data);
|
||||
// const dataBaru = clone.map(
|
||||
// (e) => (
|
||||
// e.id === 1,
|
||||
// {
|
||||
// ...e,
|
||||
// name: e.id === 1 ? "firman" : e.name,
|
||||
// age: e.id === 1 ? 30 : e.age,
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
// setData(dataBaru);
|
||||
// }}
|
||||
// >
|
||||
// Update
|
||||
// </Button>
|
||||
// </Stack>
|
||||
|
||||
<pre>{JSON.stringify(data, null, 2)}</pre>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function CreateButton() {
|
||||
return (
|
||||
<>
|
||||
<ActionIcon
|
||||
p={3}
|
||||
variant="filled"
|
||||
radius={"xl"}
|
||||
size={"xl"}
|
||||
style={{
|
||||
position: "absolute",
|
||||
zIndex: 1,
|
||||
bottom: 150,
|
||||
right: 30,
|
||||
}}
|
||||
>
|
||||
<IconPencilPlus size={30} />
|
||||
</ActionIcon>
|
||||
|
||||
{/* <Affix
|
||||
bg={"blue"}
|
||||
withinPortal
|
||||
portalProps={{}}
|
||||
position={{ bottom: rem(150), right: rem(30) }}
|
||||
>
|
||||
<ActionIcon
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
border: `1px solid ${AccentColor.skyblue}`,
|
||||
}}
|
||||
bg={AccentColor.blue}
|
||||
size={"xl"}
|
||||
radius={"xl"}
|
||||
variant="transparent"
|
||||
onClick={() => {}}
|
||||
>
|
||||
<IconPencilPlus color="white" />
|
||||
</ActionIcon>
|
||||
</Affix> */}
|
||||
</>
|
||||
);
|
||||
// <pre>{JSON.stringify(data, null, 2)}</pre>
|
||||
// </Box>
|
||||
// </>
|
||||
// );
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ Client_KEY : process.env.Client_KEY,
|
||||
Server_KEY : process.env.Server_KEY,
|
||||
MAPBOX_TOKEN : process.env.MAPBOX_TOKEN,
|
||||
WS_APIKEY : process.env.WS_APIKEY,
|
||||
WIBU_REALTIME_KEY : process.env.WIBU_REALTIME_KEY
|
||||
NEXT_PUBLIC_WIBU_REALTIME_TOKEN : process.env.NEXT_PUBLIC_WIBU_REALTIME_TOKEN
|
||||
}
|
||||
Reference in New Issue
Block a user