67
CHANGELOG.md
67
CHANGELOG.md
@@ -2,6 +2,73 @@
|
|||||||
|
|
||||||
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.
|
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.2.19](https://github.com/bipproduction/hipmi/compare/v1.2.18...v1.2.19) (2024-12-06)
|
||||||
|
|
||||||
|
## [1.2.18](https://github.com/bipproduction/hipmi/compare/v1.2.17...v1.2.18) (2024-12-04)
|
||||||
|
|
||||||
|
## [1.2.17](https://github.com/bipproduction/hipmi/compare/v1.2.16...v1.2.17) (2024-12-04)
|
||||||
|
|
||||||
|
## [1.2.16](https://github.com/bipproduction/hipmi/compare/v1.2.15...v1.2.16) (2024-12-03)
|
||||||
|
|
||||||
|
## [1.2.15](https://github.com/bipproduction/hipmi/compare/v1.2.14...v1.2.15) (2024-12-03)
|
||||||
|
|
||||||
|
## [1.2.14](https://github.com/bipproduction/hipmi/compare/v1.2.13...v1.2.14) (2024-12-03)
|
||||||
|
|
||||||
|
## [1.2.13](https://github.com/bipproduction/hipmi/compare/v1.2.12...v1.2.13) (2024-12-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* event ([fc38813](https://github.com/bipproduction/hipmi/commit/fc388133a638d4288314dd3faeddfcce61fe7292))
|
||||||
|
* version 1.2.12 ([932735f](https://github.com/bipproduction/hipmi/commit/932735f9238db07b331b1b26328624247371c3d6))
|
||||||
|
|
||||||
|
## [1.2.12](https://github.com/bipproduction/hipmi/compare/v1.2.11...v1.2.12) (2024-12-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* version 1.2.11 ([7afcc9c](https://github.com/bipproduction/hipmi/commit/7afcc9ced02eafab1df669fd71fdbcd4556bb322))
|
||||||
|
|
||||||
|
## [1.2.11](https://github.com/bipproduction/hipmi/compare/v1.2.10...v1.2.11) (2024-12-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* version 1.2.10 ([08eed15](https://github.com/bipproduction/hipmi/commit/08eed15b798d549146b035ffd9a44cea5e55b283))
|
||||||
|
|
||||||
|
## [1.2.10](https://github.com/bipproduction/hipmi/compare/v1.2.9...v1.2.10) (2024-12-02)
|
||||||
|
|
||||||
|
## [1.2.9](https://github.com/bipproduction/hipmi/compare/v1.2.8...v1.2.9) (2024-12-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* version 1.2.8 ([378b2c1](https://github.com/bipproduction/hipmi/commit/378b2c19ff7a7fb07647c6a093d803d299c091f7))
|
||||||
|
* version 1.2.8 ([23edb2d](https://github.com/bipproduction/hipmi/commit/23edb2d6317f2a8344ac3190f492f718c05b65c9))
|
||||||
|
|
||||||
|
## [1.2.8](https://github.com/bipproduction/hipmi/compare/v1.2.7...v1.2.8) (2024-12-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* version 1.2.7 ([1b83de0](https://github.com/bipproduction/hipmi/commit/1b83de0189b4581a8511cc58af2de0d5c613646b))
|
||||||
|
|
||||||
|
## [1.2.7](https://github.com/bipproduction/hipmi/compare/v1.2.6...v1.2.7) (2024-12-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* version 1.2.6 ([13142f2](https://github.com/bipproduction/hipmi/commit/13142f283d804fead233cf6bff6a41e4732a3ec0))
|
||||||
|
|
||||||
|
## [1.2.6](https://github.com/bipproduction/hipmi/compare/v1.2.5...v1.2.6) (2024-12-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Donasi ([517b2bb](https://github.com/bipproduction/hipmi/commit/517b2bb9b0e256d31d7a10332a6e7880c58ad48f))
|
||||||
|
* Event ([45279cd](https://github.com/bipproduction/hipmi/commit/45279cd37fb4b2a293012c9cb1a8d6e977d0edb3))
|
||||||
|
* middleware ([31124c5](https://github.com/bipproduction/hipmi/commit/31124c5500d10a4d831c45c0da1a46a1dee995db))
|
||||||
|
|
||||||
## [1.2.5](https://github.com/bipproduction/hipmi/compare/v1.2.4...v1.2.5) (2024-11-28)
|
## [1.2.5](https://github.com/bipproduction/hipmi/compare/v1.2.4...v1.2.5) (2024-11-28)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
reactStrictMode: false,
|
reactStrictMode: false,
|
||||||
experimental: {
|
experimental: {
|
||||||
serverActions: true
|
serverActions: true,
|
||||||
},
|
},
|
||||||
|
output: "standalone"
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig;
|
||||||
|
|||||||
17
package.json
17
package.json
@@ -1,16 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "hipmi",
|
"name": "hipmi",
|
||||||
"version": "1.2.5",
|
"version": "1.2.19",
|
||||||
"private": true,
|
"private": true,
|
||||||
"prisma": {
|
"prisma": {
|
||||||
"seed": "npx tsx prisma/seed.ts --yes"
|
"seed": "npx tsx prisma/seed.ts --yes"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --experimental-https",
|
"dev": "bun --bun run next dev --experimental-https",
|
||||||
"build": "next build",
|
"build": "NODE_OPTIONS='--max-old-space-size=2048' bun --bun run next build",
|
||||||
"start": "next start",
|
"build:dev": "bun --bun run next build",
|
||||||
"lint": "next lint",
|
"start": "bun --bun run next start",
|
||||||
"ver": "npx commit-and-tag-version -- --prerelease"
|
"lint": "bun --bun run next lint",
|
||||||
|
"ver": "bunx commit-and-tag-version -- --prerelease"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bounceapp/iframe": "^0.3.0",
|
"@bounceapp/iframe": "^0.3.0",
|
||||||
@@ -79,6 +80,7 @@
|
|||||||
"react-international-phone": "^4.2.6",
|
"react-international-phone": "^4.2.6",
|
||||||
"react-map-gl": "^7.1.7",
|
"react-map-gl": "^7.1.7",
|
||||||
"react-pdf": "^9.1.0",
|
"react-pdf": "^9.1.0",
|
||||||
|
"react-qr-code": "^2.0.15",
|
||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-responsive-carousel": "^3.2.23",
|
"react-responsive-carousel": "^3.2.23",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
@@ -89,6 +91,7 @@
|
|||||||
"utf-8-validate": "^6.0.3",
|
"utf-8-validate": "^6.0.3",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"wibu": "bipproduction/wibu",
|
"wibu": "bipproduction/wibu",
|
||||||
|
"wibu-cli": "^1.0.91",
|
||||||
"wibu-pkg": "^1.0.3",
|
"wibu-pkg": "^1.0.3",
|
||||||
"yaml": "^2.3.2"
|
"yaml": "^2.3.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ model User {
|
|||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
username String @unique
|
username String @unique
|
||||||
nomor String @unique
|
nomor String @unique
|
||||||
active Boolean @default(true)
|
active Boolean @default(false)
|
||||||
createdAt DateTime? @default(now())
|
createdAt DateTime? @default(now())
|
||||||
updatedAt DateTime? @updatedAt
|
updatedAt DateTime? @updatedAt
|
||||||
MasterUserRole MasterUserRole @relation(fields: [masterUserRoleId], references: [id])
|
MasterUserRole MasterUserRole @relation(fields: [masterUserRoleId], references: [id])
|
||||||
@@ -573,16 +573,19 @@ model Donasi_PencairanDana {
|
|||||||
// ========================================= EVENT ========================================= //
|
// ========================================= EVENT ========================================= //
|
||||||
|
|
||||||
model Event {
|
model Event {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
title String
|
title String
|
||||||
lokasi String
|
lokasi String
|
||||||
tanggal DateTime
|
tanggal DateTime?
|
||||||
deskripsi String
|
deskripsi String
|
||||||
active Boolean @default(true)
|
active Boolean @default(true)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
catatan String?
|
catatan String?
|
||||||
|
|
||||||
|
tanggalSelesai DateTime?
|
||||||
|
isArsip Boolean? @default(false)
|
||||||
|
|
||||||
Author User? @relation(fields: [authorId], references: [id])
|
Author User? @relation(fields: [authorId], references: [id])
|
||||||
authorId String?
|
authorId String?
|
||||||
EventMaster_Status EventMaster_Status? @relation(fields: [eventMaster_StatusId], references: [id])
|
EventMaster_Status EventMaster_Status? @relation(fields: [eventMaster_StatusId], references: [id])
|
||||||
@@ -615,6 +618,7 @@ model Event_Peserta {
|
|||||||
active Boolean @default(true)
|
active Boolean @default(true)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
isPresent Boolean @default(false)
|
||||||
|
|
||||||
Event Event? @relation(fields: [eventId], references: [id])
|
Event Event? @relation(fields: [eventId], references: [id])
|
||||||
eventId String?
|
eventId String?
|
||||||
|
|||||||
BIN
public/aset/home/home-hipmi-new.png
Normal file
BIN
public/aset/home/home-hipmi-new.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
@@ -1,4 +1,4 @@
|
|||||||
import { funCheckCookies } from "@/app_modules/_global/fun/get/fun_check_cookies";
|
|
||||||
import { Login } from "@/app_modules/auth";
|
import { Login } from "@/app_modules/auth";
|
||||||
import versionUpdate from "../../../../package.json";
|
import versionUpdate from "../../../../package.json";
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import { Register } from "@/app_modules/auth";
|
|
||||||
import { auth_getCodeOtpByNumber } from "@/app_modules/auth/fun/get_kode_otp_by_id";
|
|
||||||
|
|
||||||
export default async function Page({ params }: { params: { id: string } }) {
|
|
||||||
let otpId = params.id;
|
|
||||||
const dataOtp = await auth_getCodeOtpByNumber({ kodeId: otpId });
|
|
||||||
return <Register dataOtp={dataOtp} />;
|
|
||||||
}
|
|
||||||
5
src/app/(user)/register/page.tsx
Normal file
5
src/app/(user)/register/page.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { Register } from "@/app_modules/auth";
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
return <Register />;
|
||||||
|
}
|
||||||
7
src/app/(user)/splash/page.tsx
Normal file
7
src/app/(user)/splash/page.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { SplashScreen } from "@/app_modules/auth";
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
return <>
|
||||||
|
<SplashScreen/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { Validasi } from "@/app_modules/auth";
|
|
||||||
import { auth_getCodeOtpByNumber } from "@/app_modules/auth/fun/get_kode_otp_by_id";
|
|
||||||
|
|
||||||
export default async function Page({ params }: { params: { id: string } }) {
|
|
||||||
let kodeId = params.id;
|
|
||||||
const dataOtp = await auth_getCodeOtpByNumber({ kodeId: kodeId });
|
|
||||||
|
|
||||||
return <Validasi dataOtp={dataOtp as any} />;
|
|
||||||
}
|
|
||||||
5
src/app/(user)/validasi/page.tsx
Normal file
5
src/app/(user)/validasi/page.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { Validasi } from "@/app_modules/auth";
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
return <Validasi />;
|
||||||
|
}
|
||||||
19
src/app/(user)/waiting-room/page.tsx
Normal file
19
src/app/(user)/waiting-room/page.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
||||||
|
import { funGlobal_checkActivationUseById } from "@/app_modules/_global/fun/get/fun_check_activation_use_by_id";
|
||||||
|
import WaitingRoom_View from "@/app_modules/waiting_room/view";
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
const userLoginId = await funGetUserIdByToken();
|
||||||
|
const activationUser = await funGlobal_checkActivationUseById({
|
||||||
|
userId: userLoginId as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<WaitingRoom_View
|
||||||
|
activationUser={activationUser as boolean}
|
||||||
|
userLoginId={userLoginId as string}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
21
src/app/api/auth/check/route.ts
Normal file
21
src/app/api/auth/check/route.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { prisma } from "@/app/lib";
|
||||||
|
import { data } from "autoprefixer";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const id = searchParams.get("id");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.kodeOtp.findFirst({
|
||||||
|
where: {
|
||||||
|
id: id as string,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return new Response(JSON.stringify({ data }), { status: 200 });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(JSON.stringify({ data: null }), { status: 404 });
|
||||||
|
}
|
||||||
@@ -1,31 +1,64 @@
|
|||||||
|
import { prisma } from "@/app/lib";
|
||||||
|
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
if (req.method === "POST") {
|
if (req.method === "POST") {
|
||||||
|
const codeOtp = randomOTP();
|
||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
// console.log(body);
|
const { nomor } = body;
|
||||||
|
|
||||||
if (body.nomor === "1234567890") {
|
try {
|
||||||
return NextResponse.json({
|
const res = await fetch(
|
||||||
success: true,
|
`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.
|
||||||
status: 200,
|
\n
|
||||||
message: "Login Success",
|
>> Kode OTP anda: ${codeOtp}.
|
||||||
});
|
`
|
||||||
} else {
|
);
|
||||||
try {
|
|
||||||
await fetch(
|
const sendWa = await res.json();
|
||||||
`https://wa.wibudev.com/code?nom=${body.nomor}&text=Masukan Kode OTP:${body.otp}`
|
if (sendWa.status !== "success")
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Nomor Whatsapp Tidak Aktif",
|
||||||
|
}),
|
||||||
|
{ status: 400 }
|
||||||
);
|
);
|
||||||
return NextResponse.json({
|
|
||||||
body,
|
const createOtpId = await prisma.kodeOtp.create({
|
||||||
status: 200,
|
data: {
|
||||||
message: "Login Success",
|
nomor: nomor,
|
||||||
});
|
otp: codeOtp,
|
||||||
} catch (error) {
|
},
|
||||||
return NextResponse.json({ status: 500, message: "Server Error !!!" });
|
});
|
||||||
}
|
|
||||||
|
if (!createOtpId)
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal Membuat Kode OTP",
|
||||||
|
}),
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: "Kode Verifikasi Dikirim",
|
||||||
|
kodeId: createOtpId.id,
|
||||||
|
}),
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Server Whatsapp Error !!",
|
||||||
|
}),
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NextResponse.json({ success: false });
|
return NextResponse.json({ success: false });
|
||||||
|
|||||||
@@ -1,12 +1,28 @@
|
|||||||
|
import { prisma } from "@/app/lib";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import { NextResponse } from "next/server";
|
export async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const id = searchParams.get("id");
|
||||||
|
|
||||||
export async function GET() {
|
const delToken = await prisma.userSession.delete({
|
||||||
cookies().set({
|
where: {
|
||||||
name: "mySession",
|
userId: id as string,
|
||||||
value: "",
|
},
|
||||||
maxAge: 0,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return NextResponse.json({ status: 200, message: "Logout" });
|
const del = cookies().delete(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!);
|
||||||
|
return new Response(JSON.stringify({ success: true, message: "Logout Berhasil" }), {status: 200});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// import { cookies } from "next/headers";
|
||||||
|
// import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
// export async function GET() {
|
||||||
|
// cookies().set({
|
||||||
|
// name: "mySession",
|
||||||
|
// value: "",
|
||||||
|
// maxAge: 0,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return NextResponse.json({ status: 200, message: "Logout" });
|
||||||
|
// }
|
||||||
|
|||||||
@@ -1,51 +1,70 @@
|
|||||||
|
import { sessionCreate } from "@/app/auth/_lib/session_create";
|
||||||
import prisma from "@/app/lib/prisma";
|
import prisma from "@/app/lib/prisma";
|
||||||
import { ServerEnv } from "@/app/lib/server_env";
|
|
||||||
import { sealData } from "iron-session";
|
|
||||||
import { cookies } from "next/headers";
|
|
||||||
import { NextResponse } from "next/server";
|
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
if (req.method === "POST") {
|
if (req.method === "POST") {
|
||||||
const body = await req.json();
|
const { data } = await req.json();
|
||||||
// MyConsole(body);
|
|
||||||
|
|
||||||
const cekUsername = await prisma.user.findUnique({
|
const cekUsername = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
username: body.username,
|
username: data.username,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (cekUsername)
|
if (cekUsername)
|
||||||
return NextResponse.json({ status: 400, message: "Username sudah ada" });
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Username sudah digunakan",
|
||||||
|
}),
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
const data = await prisma.user.create({
|
const createUser = await prisma.user.create({
|
||||||
data: {
|
data: {
|
||||||
username: body.username,
|
username: data.username,
|
||||||
nomor: body.nomor,
|
nomor: data.nomor,
|
||||||
|
active: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data) {
|
const token = await sessionCreate({
|
||||||
const seal = await sealData(
|
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||||
JSON.stringify({
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
id: data.id,
|
user: createUser as any,
|
||||||
username: data.username,
|
});
|
||||||
}),
|
|
||||||
{
|
|
||||||
password: ServerEnv.value?.WIBU_PWD as string,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
cookies().set({
|
try {
|
||||||
name: "mySession",
|
const createUserSession = await prisma.userSession.create({
|
||||||
value: seal,
|
data: {
|
||||||
maxAge: 60 * 60 * 24 * 7,
|
token: token as string,
|
||||||
|
userId: createUser.id,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({ status: 201 });
|
if (!createUserSession)
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal Membuat Session",
|
||||||
|
}),
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({ success: true });
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil Login",
|
||||||
|
}),
|
||||||
|
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return NextResponse.json({ success: false });
|
return new Response(
|
||||||
|
JSON.stringify({ success: false, message: "Method Not Allowed" }),
|
||||||
|
{ status: 405 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/app/api/auth/resend/route.ts
Normal file
65
src/app/api/auth/resend/route.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { prisma } from "@/app/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") {
|
||||||
|
const codeOtp = randomOTP();
|
||||||
|
const body = await req.json();
|
||||||
|
const { nomor } = body;
|
||||||
|
|
||||||
|
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 new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Nomor Whatsapp Tidak Aktif",
|
||||||
|
}),
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const createOtpId = await prisma.kodeOtp.create({
|
||||||
|
data: {
|
||||||
|
nomor: nomor,
|
||||||
|
otp: codeOtp,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createOtpId)
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal Membuat Kode OTP",
|
||||||
|
}),
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: "Kode Verifikasi Dikirim",
|
||||||
|
kodeId: createOtpId.id,
|
||||||
|
}),
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
message: "Server Whatsapp Error !!",
|
||||||
|
}),
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NextResponse.json({ success: false });
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { sessionCreate } from "@/app/auth/_lib/session_create";
|
||||||
import prisma from "@/app/lib/prisma";
|
import prisma from "@/app/lib/prisma";
|
||||||
import { ServerEnv } from "@/app/lib/server_env";
|
import { ServerEnv } from "@/app/lib/server_env";
|
||||||
import { sealData } from "iron-session";
|
import { sealData } from "iron-session";
|
||||||
@@ -7,45 +8,100 @@ import { NextResponse } from "next/server";
|
|||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
if (req.method === "POST") {
|
if (req.method === "POST") {
|
||||||
const body = await req.json();
|
const { nomor } = await req.json();
|
||||||
|
|
||||||
const data = await prisma.user.findUnique({
|
const dataUser = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
nomor: body.nomor,
|
nomor: nomor,
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
nomor: true,
|
nomor: true,
|
||||||
username: true,
|
username: true,
|
||||||
active: true,
|
active: true,
|
||||||
|
masterUserRoleId: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!data) return NextResponse.json({ status: 404 });
|
|
||||||
|
|
||||||
if (data) {
|
if (dataUser === null)
|
||||||
const res = await sealData(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({ success: false, message: "Nomor Belum Terdaftar" }),
|
||||||
id: data.id,
|
{ status: 404 }
|
||||||
username: data.username,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
password: ServerEnv.value?.WIBU_PWD as string,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
cookies().set({
|
const token = await sessionCreate({
|
||||||
name: "mySession",
|
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||||
value: res,
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
maxAge: 60 * 60 * 24 * 7,
|
user: dataUser as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
const cekSessionUser = await prisma.userSession.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: dataUser.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cekSessionUser !== null) {
|
||||||
|
await prisma.userSession.delete({
|
||||||
|
where: {
|
||||||
|
userId: dataUser.id,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
revalidatePath("/dev/home");
|
|
||||||
|
|
||||||
return NextResponse.json({ status: 200, data });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({ success: true });
|
try {
|
||||||
|
const createUserSession = await prisma.userSession.create({
|
||||||
|
data: {
|
||||||
|
token: token as string,
|
||||||
|
userId: dataUser.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createUserSession)
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({ success: false, message: "Gagal Membuat Session" }),
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (data) {
|
||||||
|
// const res = await sealData(
|
||||||
|
// JSON.stringify({
|
||||||
|
// id: data.id,
|
||||||
|
// username: data.username,
|
||||||
|
// }),
|
||||||
|
// {
|
||||||
|
// password: ServerEnv.value?.WIBU_PWD as string,
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// cookies().set({
|
||||||
|
// name: "mySession",
|
||||||
|
// value: res,
|
||||||
|
// maxAge: 60 * 60 * 24 * 7,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// revalidatePath("/dev/home");
|
||||||
|
|
||||||
|
// return NextResponse.json({ status: 200, data });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return NextResponse.json({ success: true });
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil Login",
|
||||||
|
roleId: dataUser.masterUserRoleId,
|
||||||
|
active: dataUser.active,
|
||||||
|
}),
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return NextResponse.json({ success: false });
|
return new Response(
|
||||||
|
JSON.stringify({ success: false, message: "Method Not Allowed" }),
|
||||||
|
{ status: 405 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/app/api/event/check-kehadiran/route.ts
Normal file
15
src/app/api/event/check-kehadiran/route.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { event_funCheckKehadiran } from "@/app_modules/event/fun";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(req: Request) {
|
||||||
|
const { searchParams } = new URL(req.url);
|
||||||
|
const userId = searchParams.get("userId");
|
||||||
|
const eventId = searchParams.get("eventId");
|
||||||
|
|
||||||
|
const res = await event_funCheckKehadiran({
|
||||||
|
eventId: eventId as string,
|
||||||
|
userId: userId as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(res, { status: 200 });
|
||||||
|
}
|
||||||
15
src/app/api/event/check-peserta/route.ts
Normal file
15
src/app/api/event/check-peserta/route.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { event_funCheckPesertaByUserId } from "@/app_modules/event/fun";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(req: Request) {
|
||||||
|
const { searchParams } = new URL(req.url);
|
||||||
|
const userId = searchParams.get("userId");
|
||||||
|
const eventId = searchParams.get("eventId");
|
||||||
|
|
||||||
|
const res = await event_funCheckPesertaByUserId({
|
||||||
|
eventId: eventId as string,
|
||||||
|
userId: userId as string,
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(res, { status: 200 });
|
||||||
|
}
|
||||||
12
src/app/api/event/get-all/route.ts
Normal file
12
src/app/api/event/get-all/route.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { event_getListAllPublish } from "@/app_modules/event/fun/get/get_list_all_publish";
|
||||||
|
import { toNumber } from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(params: Request) {
|
||||||
|
const { searchParams } = new URL(params.url);
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
|
||||||
|
const data = await event_getListAllPublish({ page: toNumber(page) });
|
||||||
|
|
||||||
|
return NextResponse.json({ data });
|
||||||
|
}
|
||||||
21
src/app/api/event/get-one-by-id/route.ts
Normal file
21
src/app/api/event/get-one-by-id/route.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(params: Request) {
|
||||||
|
const { searchParams } = new URL(params.url);
|
||||||
|
const eventId = searchParams.get("eventId");
|
||||||
|
|
||||||
|
const res = await event_getOneById(eventId as string);
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ message: "Event Not Found", data: null },
|
||||||
|
{ status: 404 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{ message: "Event Found", data: res },
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
}
|
||||||
16
src/app/api/event/list-peserta/route.ts
Normal file
16
src/app/api/event/list-peserta/route.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { event_newGetListPesertaById } from "@/app_modules/event/fun";
|
||||||
|
import { toNumber } from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(req: Request) {
|
||||||
|
const { searchParams } = new URL(req.url);
|
||||||
|
const eventId = searchParams.get("eventId");
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
|
||||||
|
const res = await event_newGetListPesertaById({
|
||||||
|
eventId: eventId as string,
|
||||||
|
page: toNumber(page),
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(res, { status: 200 });
|
||||||
|
}
|
||||||
68
src/app/api/new/home/route.ts
Normal file
68
src/app/api/new/home/route.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import { prisma } from "@/app/lib";
|
||||||
|
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
|
||||||
|
// GET DATA HOME
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
try {
|
||||||
|
let fixData
|
||||||
|
const { searchParams } = new URL(request.url)
|
||||||
|
const kategori = searchParams.get("cat")
|
||||||
|
|
||||||
|
const userLoginId = await funGetUserIdByToken()
|
||||||
|
if (userLoginId == null) {
|
||||||
|
return NextResponse.json({ success: false, message: "Gagal mendapatkan data, user id tidak ada" }, { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kategori == "job") {
|
||||||
|
fixData = await prisma.job.findMany({
|
||||||
|
take: 2,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
masterStatusId: "1"
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
title: true,
|
||||||
|
deskripsi: true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (kategori == "cek_profile") {
|
||||||
|
const data = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id: userLoginId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
imageId: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = {
|
||||||
|
profile: data?.Profile?.id,
|
||||||
|
imageId: data?.Profile?.imageId
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", data: fixData }, { status: 200 });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ success: false, message: "Gagal mendapatkan data, coba lagi nanti ", reason: (error as Error).message, }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/app/api/new/portofolio/route.ts
Normal file
59
src/app/api/new/portofolio/route.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { prisma } from "@/app/lib";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
|
||||||
|
// GET ALL DATA PORTOFOLIO BY PROFILE ID
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
try {
|
||||||
|
let fixData
|
||||||
|
const { searchParams } = new URL(request.url)
|
||||||
|
const profile = searchParams.get("profile")
|
||||||
|
const kategori_halaman = searchParams.get("cat")
|
||||||
|
const page = searchParams.get("page")
|
||||||
|
const dataSkip = Number(page) * 10 - 10;
|
||||||
|
|
||||||
|
if (kategori_halaman == "profile") {
|
||||||
|
fixData = await prisma.portofolio.findMany({
|
||||||
|
take: 2,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
profileId: profile,
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
id_Portofolio: true,
|
||||||
|
namaBisnis: true,
|
||||||
|
profileId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (kategori_halaman == "portofolio") {
|
||||||
|
fixData = await prisma.portofolio.findMany({
|
||||||
|
skip: dataSkip,
|
||||||
|
take: 10,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
profileId: profile,
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
id_Portofolio: true,
|
||||||
|
namaBisnis: true,
|
||||||
|
profileId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", data: fixData }, { status: 200 });
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ success: false, message: "Gagal mendapatkan data, coba lagi nanti ", reason: (error as Error).message, }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/app/api/new/user/route.ts
Normal file
58
src/app/api/new/user/route.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { prisma } from "@/app/lib";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
|
||||||
|
// GET ONE DATA USER PROFILE BY PROFILE ID
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
try {
|
||||||
|
const { searchParams } = new URL(request.url)
|
||||||
|
const profile = searchParams.get("profile")
|
||||||
|
|
||||||
|
const data = await prisma.profile.findUnique({
|
||||||
|
where: {
|
||||||
|
id: String(profile),
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
email: true,
|
||||||
|
alamat: true,
|
||||||
|
jenisKelamin: true,
|
||||||
|
imageId: true,
|
||||||
|
imageBackgroundId: true,
|
||||||
|
userId: true,
|
||||||
|
User: {
|
||||||
|
select: {
|
||||||
|
username: true,
|
||||||
|
nomor: true,
|
||||||
|
active: true,
|
||||||
|
masterUserRoleId: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataFix = {
|
||||||
|
id: data?.userId,
|
||||||
|
username: data?.User?.username,
|
||||||
|
nomor: data?.User?.nomor,
|
||||||
|
active: data?.User?.active,
|
||||||
|
masterUserRoleId: data?.User?.masterUserRoleId,
|
||||||
|
idProfile: data?.id,
|
||||||
|
name: data?.name,
|
||||||
|
email: data?.email,
|
||||||
|
alamat: data?.alamat,
|
||||||
|
jenisKelamin: data?.jenisKelamin,
|
||||||
|
imageId: data?.imageId,
|
||||||
|
imageBackgroundId: data?.imageBackgroundId
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", data: dataFix, }, { status: 200 });
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ success: false, message: "Gagal mendapatkan data, coba lagi nanti ", reason: (error as Error).message, }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/app/api/origin-url/route.ts
Normal file
6
src/app/api/origin-url/route.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { headers } from "next/headers";
|
||||||
|
export async function GET(req: Request) {
|
||||||
|
const origin = new URL(req.url).origin;
|
||||||
|
|
||||||
|
return new Response(JSON.stringify({ success: true, origin }));
|
||||||
|
}
|
||||||
41
src/app/api/user/route.ts
Normal file
41
src/app/api/user/route.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { jwtVerify } from "jose";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
// const data = await req.text();
|
||||||
|
// console.log(data);
|
||||||
|
const c = cookies().get(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!);
|
||||||
|
|
||||||
|
if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) {
|
||||||
|
return NextResponse.json({ status: 401, message: "Unauthorized" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = c.value;
|
||||||
|
const dataUser = await decrypt({
|
||||||
|
token: token,
|
||||||
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({ status: 200, message: "OK", data: dataUser });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function decrypt({
|
||||||
|
token,
|
||||||
|
encodedKey,
|
||||||
|
}: {
|
||||||
|
token: string;
|
||||||
|
encodedKey: string;
|
||||||
|
}): Promise<Record<string, any> | null> {
|
||||||
|
try {
|
||||||
|
const enc = new TextEncoder().encode(encodedKey);
|
||||||
|
const { payload } = await jwtVerify(token, enc, {
|
||||||
|
algorithms: ["HS256"],
|
||||||
|
});
|
||||||
|
return (payload.user as Record<string, any>) || null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Gagal verifikasi session", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/app/api/validasi/route.ts
Normal file
7
src/app/api/validasi/route.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export async function GET(req: Request) {
|
||||||
|
const auth = req.headers.get("Authorization");
|
||||||
|
const token = auth?.split(" ")[1];
|
||||||
|
if (!token)
|
||||||
|
return new Response(JSON.stringify({ success: false }), { status: 401 });
|
||||||
|
return new Response(JSON.stringify({ success: true }));
|
||||||
|
}
|
||||||
22
src/app/auth/_lib/decrypt.ts
Normal file
22
src/app/auth/_lib/decrypt.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { jwtVerify } from "jose";
|
||||||
|
|
||||||
|
export async function decrypt({
|
||||||
|
token,
|
||||||
|
encodedKey,
|
||||||
|
}: {
|
||||||
|
token: string;
|
||||||
|
encodedKey: string;
|
||||||
|
}): Promise<Record<string, any> | null> {
|
||||||
|
try {
|
||||||
|
const enc = new TextEncoder().encode(encodedKey);
|
||||||
|
const { payload } = await jwtVerify(token, enc, {
|
||||||
|
algorithms: ["HS256"],
|
||||||
|
});
|
||||||
|
return (payload.user as Record<string, any>) || null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Gagal verifikasi session", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wibu:0.2.82
|
||||||
25
src/app/auth/_lib/encrypt.ts
Normal file
25
src/app/auth/_lib/encrypt.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { SignJWT } from "jose";
|
||||||
|
|
||||||
|
export async function encrypt({
|
||||||
|
user,
|
||||||
|
exp = "7 year",
|
||||||
|
encodedKey,
|
||||||
|
}: {
|
||||||
|
user: Record<string, any>;
|
||||||
|
exp?: string;
|
||||||
|
encodedKey: string;
|
||||||
|
}): Promise<string | null> {
|
||||||
|
try {
|
||||||
|
const enc = new TextEncoder().encode(encodedKey);
|
||||||
|
return new SignJWT({ user })
|
||||||
|
.setProtectedHeader({ alg: "HS256" })
|
||||||
|
.setIssuedAt()
|
||||||
|
.setExpirationTime(exp)
|
||||||
|
.sign(enc);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Gagal mengenkripsi", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wibu:0.2.82
|
||||||
35
src/app/auth/_lib/session_create.ts
Normal file
35
src/app/auth/_lib/session_create.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { cookies } from "next/headers";
|
||||||
|
import { encrypt } from "./encrypt";
|
||||||
|
|
||||||
|
export async function sessionCreate({
|
||||||
|
sessionKey,
|
||||||
|
exp = "7 year",
|
||||||
|
encodedKey,
|
||||||
|
user,
|
||||||
|
}: {
|
||||||
|
sessionKey: string;
|
||||||
|
exp?: string;
|
||||||
|
encodedKey: string;
|
||||||
|
user: Record<string, unknown>;
|
||||||
|
}) {
|
||||||
|
const token = await encrypt({
|
||||||
|
exp,
|
||||||
|
encodedKey,
|
||||||
|
user,
|
||||||
|
});
|
||||||
|
|
||||||
|
const cookie: any = {
|
||||||
|
key: sessionKey,
|
||||||
|
value: token,
|
||||||
|
options: {
|
||||||
|
httpOnly: true,
|
||||||
|
sameSite: "lax",
|
||||||
|
path: "/",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
cookies().set(cookie.key, cookie.value, { ...cookie.options });
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wibu:0.2.82
|
||||||
27
src/app/auth/api/login/route.ts
Normal file
27
src/app/auth/api/login/route.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { prisma } from "@/app/lib";
|
||||||
|
import { sessionCreate } from "../../_lib/session_create";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
nomor: "6281339158911",
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
nomor: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({ success: false, message: "User not found" }), {status: 404}
|
||||||
|
);
|
||||||
|
|
||||||
|
const token = await sessionCreate({
|
||||||
|
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||||
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
|
user: user as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(JSON.stringify({ success: true, token }));
|
||||||
|
}
|
||||||
5
src/app/auth/api/logout/route.ts
Normal file
5
src/app/auth/api/logout/route.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { cookies } from "next/headers";
|
||||||
|
export async function GET() {
|
||||||
|
const del = cookies().delete(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!);
|
||||||
|
return new Response(JSON.stringify({ success: true }));
|
||||||
|
}
|
||||||
39
src/app/auth/login/page.tsx
Normal file
39
src/app/auth/login/page.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
"use client";
|
||||||
|
import { Button } from "@mantine/core";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
async function login() {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await fetch("/auth/api/login", {
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataText = await res.text();
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
console.error(dataText);
|
||||||
|
throw new Error(res.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataJson = JSON.parse(dataText);
|
||||||
|
console.log(dataJson);
|
||||||
|
// window.location.replace("/dev/home");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button loading={loading} onClick={login}>
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
21
src/app/dev/(user)/home/page.tsx
Normal file
21
src/app/dev/(user)/home/page.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { HomeViewNew } from "@/app_modules/home";
|
||||||
|
import notifikasi_countUserNotifikasi from "@/app_modules/notifikasi/fun/count/fun_count_by_id";
|
||||||
|
|
||||||
|
export default async function PageHome() {
|
||||||
|
// const userLoginId = await funGetUserIdByToken();
|
||||||
|
// const dataUser = await user_getOneByUserId(userLoginId as string);
|
||||||
|
// const dataJob = await job_getTwoForHomeView();
|
||||||
|
const countNotifikasi = await notifikasi_countUserNotifikasi();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* <HomeView
|
||||||
|
dataUser={dataUser as any}
|
||||||
|
dataJob={dataJob as any}
|
||||||
|
countNotifikasi={countNotifikasi}
|
||||||
|
/> */}
|
||||||
|
<HomeViewNew countNotifikasi={countNotifikasi} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import { AdminEvent_TablePublish } from "@/app_modules/admin/event";
|
import { AdminEvent_TablePublish } from "@/app_modules/admin/event";
|
||||||
import { adminEvent_funGetListPublish } from "@/app_modules/admin/event/fun";
|
import { adminEvent_funGetListPublish } from "@/app_modules/admin/event/fun";
|
||||||
import { AdminEvent_getListTableByStatusId } from "@/app_modules/admin/event/fun/get/get_list_table_by_status_id";
|
|
||||||
|
|
||||||
export default async function Page() {
|
async function Page() {
|
||||||
const listPublish = await adminEvent_funGetListPublish({page: 1});
|
const listPublish = await adminEvent_funGetListPublish({ page: 1 });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -11,3 +10,5 @@ export default async function Page() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Page;
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import adminNotifikasi_countNotifikasi from "@/app_modules/admin/notifikasi/fun/
|
|||||||
import adminNotifikasi_getByUserId from "@/app_modules/admin/notifikasi/fun/get/get_notifikasi_by_user_id";
|
import adminNotifikasi_getByUserId from "@/app_modules/admin/notifikasi/fun/get/get_notifikasi_by_user_id";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import versionUpdate from "../../../../package.json";
|
import versionUpdate from "../../../../package.json";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
export default async function Layout({
|
export default async function Layout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -14,10 +15,14 @@ export default async function Layout({
|
|||||||
const userLoginId = await funGetUserIdByToken();
|
const userLoginId = await funGetUserIdByToken();
|
||||||
const version = versionUpdate.version;
|
const version = versionUpdate.version;
|
||||||
|
|
||||||
const dataUser = await funGlobal_getUserById({ userId: userLoginId as string});
|
const dataUser = await funGlobal_getUserById({
|
||||||
const listNotifikasi = await adminNotifikasi_getByUserId({page: 1});
|
userId: userLoginId as string,
|
||||||
|
});
|
||||||
|
const listNotifikasi = await adminNotifikasi_getByUserId({ page: 1 });
|
||||||
const countNotifikasi = await adminNotifikasi_countNotifikasi();
|
const countNotifikasi = await adminNotifikasi_countNotifikasi();
|
||||||
|
|
||||||
|
if (dataUser?.masterUserRoleId == "1") return redirect("/dev/home");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Admin_NewLayout
|
<Admin_NewLayout
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import { redirect } from "next/navigation";
|
|||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const version = versionUpdate.version;
|
const version = versionUpdate.version;
|
||||||
|
|
||||||
const checkCookies = await funCheckCookies();
|
// const checkCookies = await funCheckCookies();
|
||||||
console.log(checkCookies, "ini halaman login");
|
// console.log(checkCookies, "ini halaman login");
|
||||||
if (!checkCookies) return redirect("/");
|
// if (!checkCookies) return redirect("/");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ import { auth_getCodeOtpByNumber } from "@/app_modules/auth/fun/get_kode_otp_by_
|
|||||||
export default async function Page({ params }: { params: { id: string } }) {
|
export default async function Page({ params }: { params: { id: string } }) {
|
||||||
let otpId = params.id;
|
let otpId = params.id;
|
||||||
const dataOtp = await auth_getCodeOtpByNumber({ kodeId: otpId });
|
const dataOtp = await auth_getCodeOtpByNumber({ kodeId: otpId });
|
||||||
return <Register dataOtp={dataOtp} />;
|
return <Register />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { SplashScreen } from "@/app_modules/auth";
|
|||||||
export default async function PageSplash() {
|
export default async function PageSplash() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SplashScreen checkCookies/>
|
<SplashScreen />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,5 @@ export default async function Page({ params }: { params: { id: string } }) {
|
|||||||
let kodeId = params.id;
|
let kodeId = params.id;
|
||||||
const dataOtp = await auth_getCodeOtpByNumber({ kodeId: kodeId });
|
const dataOtp = await auth_getCodeOtpByNumber({ kodeId: kodeId });
|
||||||
|
|
||||||
|
return <Validasi />;
|
||||||
return <Validasi dataOtp={dataOtp as any} />;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ import { CheckCookies_UiView } from "@/app_modules/check_cookies";
|
|||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const userLoginId = await funGetUserIdByToken();
|
// const userLoginId = await funGetUserIdByToken();
|
||||||
const dataUser = await funGlobal_getUserById({ userId: userLoginId });
|
// const dataUser = await funGlobal_getUserById({ userId: userLoginId });
|
||||||
|
|
||||||
if (dataUser?.masterUserRoleId === "1") {
|
// if (dataUser?.masterUserRoleId === "1") {
|
||||||
return redirect(RouterHome.main_home);
|
// return redirect(RouterHome.main_home);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (dataUser?.masterUserRoleId !== "1") {
|
// if (dataUser?.masterUserRoleId !== "1") {
|
||||||
return redirect(RouterAdminDashboard.splash_admin);
|
// return redirect(RouterAdminDashboard.splash_admin);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// return <CheckCookies_UiView />;
|
// return <CheckCookies_UiView />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
|
||||||
import { Event_Create } from "@/app_modules/event";
|
import { Event_Create } from "@/app_modules/event";
|
||||||
import { Event_getMasterTipeAcara } from "@/app_modules/event/fun/master/get_tipe_acara";
|
import { Event_getMasterTipeAcara } from "@/app_modules/event/fun/master/get_tipe_acara";
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const userLoginId = await funGetUserIdByToken();
|
const userLoginId = await newFunGetUserId();
|
||||||
const listTipeAcara = await Event_getMasterTipeAcara();
|
const listTipeAcara = await Event_getMasterTipeAcara();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ export default async function Page({ params }: { params: { id: string } }) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Event_DetailKontribusi
|
<Event_DetailKontribusi
|
||||||
dataEvent={dataEvent as any}
|
eventId={eventId}
|
||||||
listKontributor={listKontributor as any}
|
|
||||||
totalPeserta={totalPeserta}
|
totalPeserta={totalPeserta}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,27 +1,18 @@
|
|||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
|
||||||
import { Event_DetailMain } from "@/app_modules/event";
|
import { Event_DetailMain } from "@/app_modules/event";
|
||||||
import { Event_countTotalPesertaById } from "@/app_modules/event/fun/count/count_total_peserta_by_id";
|
import { Event_countTotalPesertaById } from "@/app_modules/event/fun/count/count_total_peserta_by_id";
|
||||||
import { Event_CekUserJoinById } from "@/app_modules/event/fun/get/cek_user_join_by_id";
|
|
||||||
import { Event_getListPesertaById } from "@/app_modules/event/fun/get/get_list_peserta_by_id";
|
|
||||||
import { event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id";
|
|
||||||
|
|
||||||
export default async function Page({ params }: { params: { id: string } }) {
|
export default async function Page({ params }: { params: { id: string } }) {
|
||||||
let eventId = params.id;
|
let eventId = params.id;
|
||||||
const userLoginId : any= await funGetUserIdByToken();
|
const userLoginId = await newFunGetUserId();
|
||||||
|
|
||||||
const dataEvent = await event_getOneById(eventId);
|
|
||||||
const listPeserta = await Event_getListPesertaById(eventId);
|
|
||||||
const isJoin = await Event_CekUserJoinById(eventId, userLoginId);
|
|
||||||
const totalPeserta = await Event_countTotalPesertaById(eventId);
|
const totalPeserta = await Event_countTotalPesertaById(eventId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Event_DetailMain
|
<Event_DetailMain
|
||||||
dataEvent={dataEvent as any}
|
|
||||||
listPeserta={listPeserta as any}
|
|
||||||
userLoginId={userLoginId as string}
|
userLoginId={userLoginId as string}
|
||||||
isJoin={isJoin}
|
|
||||||
totalPeserta={totalPeserta as any}
|
totalPeserta={totalPeserta as any}
|
||||||
|
eventId={eventId}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,15 +6,14 @@ import { event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id";
|
|||||||
export default async function Page({ params }: { params: { id: string } }) {
|
export default async function Page({ params }: { params: { id: string } }) {
|
||||||
let eventId = params.id;
|
let eventId = params.id;
|
||||||
const dataEvent = await event_getOneById(eventId);
|
const dataEvent = await event_getOneById(eventId);
|
||||||
const listPeserta = await Event_getListPesertaById(eventId);
|
|
||||||
const totalPeserta = await Event_countTotalPesertaById(eventId);
|
const totalPeserta = await Event_countTotalPesertaById(eventId);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Event_DetailPublish
|
<Event_DetailPublish
|
||||||
dataEvent={dataEvent as any}
|
dataEvent={dataEvent as any}
|
||||||
listPeserta={listPeserta}
|
|
||||||
totalPeserta={totalPeserta}
|
totalPeserta={totalPeserta}
|
||||||
|
eventId={eventId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
|
|
||||||
import { Event_DetailRiwayat } from "@/app_modules/event";
|
import { Event_DetailRiwayat } from "@/app_modules/event";
|
||||||
import { Event_countTotalPesertaById } from "@/app_modules/event/fun/count/count_total_peserta_by_id";
|
import { Event_countTotalPesertaById } from "@/app_modules/event/fun/count/count_total_peserta_by_id";
|
||||||
import { Event_getListPesertaById } from "@/app_modules/event/fun/get/get_list_peserta_by_id";
|
|
||||||
import { event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id";
|
|
||||||
|
|
||||||
export default async function Page({ params }: { params: { id: string } }) {
|
export default async function Page({ params }: { params: { id: string } }) {
|
||||||
let eventId = params.id;
|
let eventId = params.id;
|
||||||
const dataEvent = await event_getOneById(eventId);
|
|
||||||
const listPeserta = await Event_getListPesertaById(eventId);
|
|
||||||
const totalPeserta = await Event_countTotalPesertaById(eventId);
|
const totalPeserta = await Event_countTotalPesertaById(eventId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Event_DetailRiwayat
|
<Event_DetailRiwayat
|
||||||
dataEvent={dataEvent as any}
|
|
||||||
listPeserta={listPeserta as any}
|
|
||||||
totalPeserta={totalPeserta as any}
|
totalPeserta={totalPeserta as any}
|
||||||
|
eventId={eventId}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
22
src/app/dev/event/konfirmasi/[id]/page.tsx
Normal file
22
src/app/dev/event/konfirmasi/[id]/page.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
|
||||||
|
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
||||||
|
import Ui_Konfirmasi from "@/app_modules/event/_ui/konfirmasi";
|
||||||
|
import { event_funCheckPesertaByUserId } from "@/app_modules/event/fun";
|
||||||
|
import { event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id";
|
||||||
|
import moment from "moment";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
export default async function Page({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const eventId = (await params).id;
|
||||||
|
const userLoginId = await newFunGetUserId();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Ui_Konfirmasi userLoginId={userLoginId as string} eventId={eventId} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
import { Event_Beranda } from "@/app_modules/event";
|
import { Event_Beranda } from "@/app_modules/event";
|
||||||
import { event_getListAllPublish } from "@/app_modules/event/fun/get/get_list_all_publish";
|
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const dataEvent = await event_getListAllPublish({ page: 1 });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Event_Beranda dataEvent={dataEvent as any} />
|
<Event_Beranda />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default async function Page({ params }: { params: { id: string } }) {
|
|||||||
page: 1,
|
page: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
dataPosting?.isActive === false && redirect(RouterForum.beranda);
|
// dataPosting?.isActive === false && redirect(RouterForum.beranda);
|
||||||
|
|
||||||
const countKomentar = await forum_countTotalKomenById(postingId);
|
const countKomentar = await forum_countTotalKomenById(postingId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
|
||||||
import { HomeView } from "@/app_modules/home";
|
|
||||||
import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
|
|
||||||
import { job_getTwoForHomeView } from "@/app_modules/job/fun/get/get_two_for_home_view";
|
|
||||||
import notifikasi_countUserNotifikasi from "@/app_modules/notifikasi/fun/count/fun_count_by_id";
|
|
||||||
|
|
||||||
export default async function Page() {
|
|
||||||
const userLoginId = await funGetUserIdByToken();
|
|
||||||
const dataUser = await user_getOneByUserId(userLoginId as string);
|
|
||||||
const dataJob = await job_getTwoForHomeView();
|
|
||||||
const countNotifikasi = await notifikasi_countUserNotifikasi();
|
|
||||||
|
|
||||||
// console.log(userLoginId, "ini di home");
|
|
||||||
// console.log(dataUser, "ini di home");
|
|
||||||
|
|
||||||
// if (dataUser?.active === false) {
|
|
||||||
// return redirect(RouterHome.home_user_non_active);
|
|
||||||
// }
|
|
||||||
// if (dataUser?.masterUserRoleId === "2" || dataUser?.masterUserRoleId === "3")
|
|
||||||
// return redirect(RouterAdminDashboard.splash_admin);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<HomeView
|
|
||||||
dataUser={dataUser as any}
|
|
||||||
dataJob={dataJob as any}
|
|
||||||
countNotifikasi={countNotifikasi}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,29 +1,24 @@
|
|||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
import { LayoutKatalogNew } from "@/app_modules/katalog/main";
|
||||||
import { KatalogLayout } from "@/app_modules/katalog/main";
|
|
||||||
import { Profile_getOneProfileAndUserById } from "@/app_modules/katalog/profile/fun/get/get_one_user_profile";
|
|
||||||
|
|
||||||
export default async function Layout({
|
export default async function Layout({ children, params, }: { children: any; params: { id: string } }) {
|
||||||
children,
|
// const profileId = params.id;
|
||||||
params,
|
// const dataProfile = await Profile_getOneProfileAndUserById(profileId);
|
||||||
}: {
|
// const authorId = dataProfile?.userId;
|
||||||
children: any;
|
|
||||||
params: { id: string };
|
|
||||||
}) {
|
|
||||||
const profileId = params.id;
|
|
||||||
const dataProfile = await Profile_getOneProfileAndUserById(profileId);
|
|
||||||
const authorId = dataProfile?.userId;
|
|
||||||
|
|
||||||
const userLoginId = await funGetUserIdByToken();
|
// const userLoginId = await funGetUserIdByToken();
|
||||||
|
// const userRoleId = dataProfile?.User?.masterUserRoleId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<KatalogLayout
|
{/* <KatalogLayout
|
||||||
profileId={profileId}
|
profileId={profileId}
|
||||||
userLoginId={userLoginId as string}
|
userLoginId={userLoginId as string}
|
||||||
authorId={authorId as any}
|
authorId={authorId as any}
|
||||||
|
userRoleId={userRoleId as string}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</KatalogLayout>
|
</KatalogLayout> */}
|
||||||
|
<LayoutKatalogNew>{children}</LayoutKatalogNew>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
import { ViewKatalogNew } from "@/app_modules/katalog";
|
||||||
import { Katalog_MainView } from "@/app_modules/katalog";
|
|
||||||
import { funGetListPortofolio } from "@/app_modules/katalog/portofolio/fun/get/get_list_portofolio";
|
|
||||||
import { Profile_getOneProfileAndUserById } from "@/app_modules/katalog/profile/fun/get/get_one_user_profile";
|
|
||||||
|
|
||||||
export default async function Page({ params }: { params: { id: string } }) {
|
export default async function Page({ params }: { params: { id: string } }) {
|
||||||
let profileId = params.id;
|
// let profileId = params.id;
|
||||||
const userLoginId = await funGetUserIdByToken();
|
// const userLoginId = await funGetUserIdByToken();
|
||||||
|
|
||||||
const listPorto = await funGetListPortofolio(profileId);
|
// const listPorto = await funGetListPortofolio(profileId);
|
||||||
const dataProfile = await Profile_getOneProfileAndUserById(profileId);
|
// const dataProfile = await Profile_getOneProfileAndUserById(profileId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Katalog_MainView
|
{/* <Katalog_MainView
|
||||||
profile={dataProfile as any}
|
profile={dataProfile as any}
|
||||||
listPorto={listPorto as any}
|
listPorto={listPorto as any}
|
||||||
userLoginId={userLoginId as any}
|
userLoginId={userLoginId as any}
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
|
<ViewKatalogNew />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,21 @@
|
|||||||
import { CheckCookies_UiLayout } from "@/app_modules/check_cookies";
|
|
||||||
import { RealtimeProvider } from "../lib";
|
import { RealtimeProvider } from "../lib";
|
||||||
import { funCheckCookies } from "@/app_modules/_global/fun/get/fun_check_cookies";
|
import { newFunGetUserId } from "../lib/new_fun_user_id";
|
||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
|
||||||
import { ServerEnv } from "../lib/server_env";
|
import { ServerEnv } from "../lib/server_env";
|
||||||
import { funGlobal_getUserById } from "@/app_modules/_global/fun/get/fun_get_user_by_id";
|
|
||||||
import { RouterHome } from "../lib/router_hipmi/router_home";
|
|
||||||
import { RouterAdminDashboard } from "../lib/router_hipmi/router_admin";
|
|
||||||
import { redirect } from "next/navigation";
|
|
||||||
|
|
||||||
export default async function Layout({
|
export default async function Layout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
const checkCookies = await funCheckCookies();
|
|
||||||
if (!checkCookies) return redirect("/");
|
|
||||||
|
|
||||||
const userLoginId = await funGetUserIdByToken();
|
|
||||||
const WIBU_REALTIME_TOKEN = process.env.NEXT_PUBLIC_WIBU_REALTIME_TOKEN;
|
|
||||||
// console.log(WIBU_REALTIME_TOKEN, "check cookies di layout dalam");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<RealtimeProvider
|
<RealtimeProvider
|
||||||
userLoginId={userLoginId as string}
|
|
||||||
WIBU_REALTIME_TOKEN={
|
WIBU_REALTIME_TOKEN={
|
||||||
ServerEnv.value?.NEXT_PUBLIC_WIBU_REALTIME_TOKEN as string
|
ServerEnv.value?.NEXT_PUBLIC_WIBU_REALTIME_TOKEN as string
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
{/* <CheckCookies_UiLayout dataUser={dataUser as any}>
|
|
||||||
{children}
|
|
||||||
</CheckCookies_UiLayout> */}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { Portofolio_ViewListDetail } from "@/app_modules/katalog/portofolio";
|
import { ListDetailPortofolioNew } from "@/app_modules/katalog/portofolio";
|
||||||
import { portofolio_funGetAllDaftarByid } from "@/app_modules/katalog/portofolio/fun/get/get_all_portofolio";
|
|
||||||
|
|
||||||
export default async function Page({ params }: { params: { id: string } }) {
|
export default async function Page({ params }: { params: { id: string } }) {
|
||||||
const profileId = params.id;
|
// const profileId = params.id;
|
||||||
const dataPortofolio = await portofolio_funGetAllDaftarByid({
|
// const dataPortofolio = await portofolio_funGetAllDaftarByid({
|
||||||
profileId,
|
// profileId,
|
||||||
page: 1,
|
// page: 1,
|
||||||
});
|
// });
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Portofolio_ViewListDetail dataPortofolio={dataPortofolio as any} profileId={profileId} />
|
{/* <Portofolio_ViewListDetail dataPortofolio={dataPortofolio as any} profileId={profileId} /> */}
|
||||||
|
<ListDetailPortofolioNew />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,5 @@
|
|||||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
|
||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
|
||||||
import { Home_UserNonActive } from "@/app_modules/home";
|
import { Home_UserNonActive } from "@/app_modules/home";
|
||||||
import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
|
|
||||||
// import { redirect } from "next/navigation";
|
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const userLoginId = await funGetUserIdByToken();
|
|
||||||
|
|
||||||
const dataUser = await user_getOneByUserId(userLoginId as string);
|
|
||||||
|
|
||||||
// if (dataUser?.active === true) {
|
|
||||||
// return redirect(RouterHome.main_home);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Home_UserNonActive />
|
<Home_UserNonActive />
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default async function Layout({
|
|||||||
<>
|
<>
|
||||||
<LayoutVote_DetailSemuaRiwayat
|
<LayoutVote_DetailSemuaRiwayat
|
||||||
votingId={votingId}
|
votingId={votingId}
|
||||||
userLoginId={userLoginId}
|
userLoginId={userLoginId as string}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</LayoutVote_DetailSemuaRiwayat>
|
</LayoutVote_DetailSemuaRiwayat>
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
import MqttLoader from "@/util/mqtt_loader";
|
|
||||||
import RootStyleRegistry from "./emotion";
|
import RootStyleRegistry from "./emotion";
|
||||||
// import "./globals.css";
|
// import "./globals.css";
|
||||||
import { TokenProvider } from "./lib/token";
|
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import { ServerEnv } from "./lib/server_env";
|
import { ServerEnv } from "./lib/server_env";
|
||||||
import { RealtimeProvider } from "./lib";
|
import { TokenProvider } from "./lib/token";
|
||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
|
||||||
import { funCheckCookies } from "@/app_modules/_global/fun/get/fun_check_cookies";
|
|
||||||
import { redirect } from "next/navigation";
|
|
||||||
dotenv.config({
|
dotenv.config({
|
||||||
path: ".env",
|
path: ".env",
|
||||||
});
|
});
|
||||||
|
|||||||
10
src/app/lib/api_user_router/route_api_event.ts
Normal file
10
src/app/lib/api_user_router/route_api_event.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export const API_RouteEvent = {
|
||||||
|
get_all: ({ page }: { page: number }) => `/api/event/get-all?page=${page}`,
|
||||||
|
get_one_by_id: ({ eventId }: { eventId: string }) =>
|
||||||
|
`/api/event/get-one-by-id?eventId=${eventId}`,
|
||||||
|
check_kehadiran: ({ eventId, userId }: { eventId: string; userId: string }) =>
|
||||||
|
`/api/event/check-kehadiran?eventId=${eventId}&userId=${userId}`,
|
||||||
|
check_peserta: ({ eventId, userId }: { eventId: string; userId: string }) =>
|
||||||
|
`/api/event/check-peserta?eventId=${eventId}&userId=${userId}`,
|
||||||
|
list_peserta: ({ eventId, page }: { eventId: string, page: number }) => `/api/event/list-peserta?eventId=${eventId}&page=${page}`,
|
||||||
|
};
|
||||||
21
src/app/lib/new_fun_user_id.ts
Normal file
21
src/app/lib/new_fun_user_id.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
"use server"
|
||||||
|
|
||||||
|
import _ from "lodash";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
import { decrypt } from "../auth/_lib/decrypt";
|
||||||
|
|
||||||
|
export async function newFunGetUserId() {
|
||||||
|
const c = cookies().get(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!);
|
||||||
|
|
||||||
|
if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = c.value;
|
||||||
|
const dataUser = await decrypt({
|
||||||
|
token: token,
|
||||||
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
|
});
|
||||||
|
|
||||||
|
return dataUser?.id;
|
||||||
|
}
|
||||||
@@ -1,17 +1,26 @@
|
|||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
const prismaClientSingleton = () => {
|
|
||||||
return new PrismaClient()
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrismaClientSingleton = ReturnType<typeof prismaClientSingleton>
|
|
||||||
|
|
||||||
|
// Singleton PrismaClient untuk pengembangan
|
||||||
const globalForPrisma = globalThis as unknown as {
|
const globalForPrisma = globalThis as unknown as {
|
||||||
prisma: PrismaClientSingleton | undefined
|
__prisma__: PrismaClient | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const prisma = globalForPrisma.__prisma__ ?? new PrismaClient({
|
||||||
|
// log: process.env.NODE_ENV === 'development' ? ['query', 'info', 'warn', 'error'] : [],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Gunakan PrismaClient yang sama jika sudah ada
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
if (!globalForPrisma.__prisma__) {
|
||||||
|
console.log('PrismaClient initialized in development mode');
|
||||||
|
}
|
||||||
|
globalForPrisma.__prisma__ = prisma;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prisma = globalForPrisma.prisma ?? prismaClientSingleton()
|
process.on('SIGINT', async () => {
|
||||||
|
console.log('Disconnecting PrismaClient...');
|
||||||
|
await prisma.$disconnect();
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
export default prisma
|
export default prisma;
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import {
|
|||||||
gs_votingTiggerBeranda,
|
gs_votingTiggerBeranda,
|
||||||
IRealtimeData,
|
IRealtimeData,
|
||||||
} from "./global_state";
|
} from "./global_state";
|
||||||
|
import { newFunGetUserId } from "./new_fun_user_id";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
// const WIBU_REALTIME_TOKEN: string | undefined =
|
// const WIBU_REALTIME_TOKEN: string | undefined =
|
||||||
// process.env.NEXT_PUBLIC_WIBU_REALTIME_TOKEN;
|
// process.env.NEXT_PUBLIC_WIBU_REALTIME_TOKEN;
|
||||||
@@ -30,12 +32,11 @@ export type TypeNotification = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function RealtimeProvider({
|
export default function RealtimeProvider({
|
||||||
userLoginId,
|
|
||||||
WIBU_REALTIME_TOKEN,
|
WIBU_REALTIME_TOKEN,
|
||||||
}: {
|
}: {
|
||||||
userLoginId: string;
|
|
||||||
WIBU_REALTIME_TOKEN: string;
|
WIBU_REALTIME_TOKEN: string;
|
||||||
}) {
|
}) {
|
||||||
|
const [userLoginId, setUserLoginId] = useState("");
|
||||||
const [dataRealtime, setDataRealtime] = useAtom(gs_realtimeData);
|
const [dataRealtime, setDataRealtime] = useAtom(gs_realtimeData);
|
||||||
const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf);
|
const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf);
|
||||||
const [newUserNtf, setNewUserNtf] = useAtom(gs_user_ntf);
|
const [newUserNtf, setNewUserNtf] = useAtom(gs_user_ntf);
|
||||||
@@ -71,8 +72,15 @@ export default function RealtimeProvider({
|
|||||||
gs_donasiTriggerBeranda
|
gs_donasiTriggerBeranda
|
||||||
);
|
);
|
||||||
|
|
||||||
|
async function loadUserId() {
|
||||||
|
const userId = await newFunGetUserId();
|
||||||
|
|
||||||
|
setUserLoginId(userId as string);
|
||||||
|
}
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
// if (WIBU_REALTIME_TOKEN === undefined) return alert("gak dapet key");
|
loadUserId();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
WibuRealtime.init({
|
WibuRealtime.init({
|
||||||
project: "hipmi",
|
project: "hipmi",
|
||||||
@@ -201,7 +209,7 @@ export default function RealtimeProvider({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log("Error!:", error);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,14 @@
|
|||||||
import { funCheckCookies } from "@/app_modules/_global/fun/get/fun_check_cookies";
|
"use client";
|
||||||
import PageSplash from "./dev/auth/splash/page";
|
|
||||||
import { redirect } from "next/navigation";
|
|
||||||
import { Login, SplashScreen } from "@/app_modules/auth";
|
|
||||||
import { RouterAuth } from "./lib/router_hipmi/router_auth";
|
|
||||||
import versionUpdate from "../../package.json";
|
|
||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
|
||||||
import { funGlobal_getUserById } from "@/app_modules/_global/fun/get/fun_get_user_by_id";
|
|
||||||
import { RouterHome } from "./lib/router_hipmi/router_home";
|
|
||||||
import { RouterAdminDashboard } from "./lib/router_hipmi/router_admin";
|
|
||||||
|
|
||||||
export default async function Page() {
|
import { SplashScreen } from "@/app_modules/auth";
|
||||||
const version = versionUpdate.version;
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
|
||||||
const checkCookies = await funCheckCookies();
|
export default function Page() {
|
||||||
// console.log(checkCookies, "ini check cookies di page awal");
|
useShallowEffect(() => {
|
||||||
if (checkCookies) return redirect("/dev/check-cookies");
|
setTimeout(() => {
|
||||||
return redirect("/login");
|
window.location.replace("/dev/home");
|
||||||
// const WIBU_REALTIME_TOKEN = process.env.NEXT_PUBLIC_WIBU_REALTIME_TOKEN;
|
}, 1000);
|
||||||
|
}, []);
|
||||||
|
|
||||||
// return <Login version={version} />;
|
return <SplashScreen />;
|
||||||
// return <SplashScreen checkCookies={checkCookies} />;
|
|
||||||
return <PageSplash />;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export function ComponentGlobal_AvatarAndUsername({
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
) : (
|
) : (
|
||||||
<ComponentGlobal_LoaderAvatar
|
<ComponentGlobal_LoaderAvatar
|
||||||
fileId={profile.imageId as any}
|
fileId={profile?.imageId as any}
|
||||||
sizeAvatar={sizeAvatar}
|
sizeAvatar={sizeAvatar}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -52,11 +52,13 @@ export async function generate_seeder() {
|
|||||||
nomor: i.nomor,
|
nomor: i.nomor,
|
||||||
username: i.name,
|
username: i.name,
|
||||||
masterUserRoleId: i.masterUserRoleId,
|
masterUserRoleId: i.masterUserRoleId,
|
||||||
|
active: i.active,
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
nomor: i.nomor,
|
nomor: i.nomor,
|
||||||
username: i.name,
|
username: i.name,
|
||||||
masterUserRoleId: i.masterUserRoleId,
|
masterUserRoleId: i.masterUserRoleId,
|
||||||
|
active: i.active,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import { prisma } from "@/app/lib";
|
||||||
|
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
||||||
|
import { permanentRedirect } from "next/navigation";
|
||||||
|
|
||||||
|
export async function funGlobal_checkActivationUseById({
|
||||||
|
userId,
|
||||||
|
}: {
|
||||||
|
userId: string;
|
||||||
|
}) {
|
||||||
|
const data = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return data?.active;
|
||||||
|
}
|
||||||
@@ -1,20 +1,31 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
|
import { prisma } from "@/app/lib";
|
||||||
import { ServerEnv } from "@/app/lib/server_env";
|
import { ServerEnv } from "@/app/lib/server_env";
|
||||||
import { unsealData } from "iron-session";
|
import { unsealData } from "iron-session";
|
||||||
|
import { jwtVerify } from "jose";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
export async function funGetUserIdByToken() {
|
export async function funGetUserIdByToken() {
|
||||||
const c = cookies().get("mySession");
|
const SESSION_KEY = process.env.NEXT_PUBLIC_BASE_SESSION_KEY!;
|
||||||
|
// console.log("SESSION_KEY", SESSION_KEY);
|
||||||
|
const c = cookies().get("hipmi-key");
|
||||||
|
|
||||||
const token = JSON.parse(
|
const cekUser = await decrypt({
|
||||||
await unsealData(c?.value as string, {
|
token: c?.value as string,
|
||||||
password: process.env.WIBU_PWD as string,
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
})
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return token.id;
|
// console.log("userid" , cekUser?.id)
|
||||||
// const token = c?.value
|
|
||||||
|
// const token = JSON.parse(
|
||||||
|
// await unsealData(c?.value as string, {
|
||||||
|
// password: process.env.WIBU_PWD as string,
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
// return token.id;
|
||||||
|
|
||||||
|
// const token = c?.value;
|
||||||
// const cekToken = await prisma.userSession.findFirst({
|
// const cekToken = await prisma.userSession.findFirst({
|
||||||
// where: {
|
// where: {
|
||||||
// token: token,
|
// token: token,
|
||||||
@@ -22,5 +33,24 @@ export async function funGetUserIdByToken() {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
// if (cekToken === null) return null
|
// if (cekToken === null) return null
|
||||||
// return cekToken.userId;
|
return cekUser?.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function decrypt({
|
||||||
|
token,
|
||||||
|
encodedKey,
|
||||||
|
}: {
|
||||||
|
token: string;
|
||||||
|
encodedKey: string;
|
||||||
|
}): Promise<Record<string, any> | null> {
|
||||||
|
try {
|
||||||
|
const enc = new TextEncoder().encode(encodedKey);
|
||||||
|
const { payload } = await jwtVerify(token, enc, {
|
||||||
|
algorithms: ["HS256"],
|
||||||
|
});
|
||||||
|
return (payload.user as Record<string, any>) || null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Gagal verifikasi session", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
|
||||||
import { Warna } from "@/app/lib/warna";
|
import { Warna } from "@/app/lib/warna";
|
||||||
import { AccentColor } from "@/app_modules/_global/color";
|
import { AccentColor } from "@/app_modules/_global/color";
|
||||||
import {
|
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global";
|
||||||
ComponentGlobal_NotifikasiBerhasil,
|
|
||||||
ComponentGlobal_NotifikasiPeringatan,
|
|
||||||
} from "@/app_modules/_global/notif_global";
|
|
||||||
import { auth_Logout } from "@/app_modules/auth/fun/fun_logout";
|
|
||||||
import { gs_kodeId } from "@/app_modules/auth/state/state";
|
|
||||||
import { MODEL_USER } from "@/app_modules/home/model/interface";
|
import { MODEL_USER } from "@/app_modules/home/model/interface";
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
@@ -20,12 +14,12 @@ import {
|
|||||||
Menu,
|
Menu,
|
||||||
Modal,
|
Modal,
|
||||||
Popover,
|
Popover,
|
||||||
|
SimpleGrid,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
Title,
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { IconPhone, IconUser, IconUserCircle } from "@tabler/icons-react";
|
import { IconPhone, IconUser, IconUserCircle } from "@tabler/icons-react";
|
||||||
import { useAtom } from "jotai";
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
@@ -38,21 +32,18 @@ export function Admin_ComponentButtonUserCircle({
|
|||||||
const [isOpenMenuUser, setOpenMenuUser] = useState(false);
|
const [isOpenMenuUser, setOpenMenuUser] = useState(false);
|
||||||
const [openPop, setOpenPop] = useState(false);
|
const [openPop, setOpenPop] = useState(false);
|
||||||
const [openModal, setOpenModal] = useState(false);
|
const [openModal, setOpenModal] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [kodeId, setKodeId] = useAtom(gs_kodeId);
|
|
||||||
const [loadingLogout, setLoadingLogout] = useState(false);
|
const [loadingLogout, setLoadingLogout] = useState(false);
|
||||||
|
|
||||||
async function onClickLogout() {
|
async function onClickLogout() {
|
||||||
const res = await auth_Logout();
|
setLoadingLogout(true);
|
||||||
|
const res = await fetch(`/api/auth/logout?id=${dataUser.id}`, {
|
||||||
|
method: "GET",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await res.json();
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
console.log(res);
|
ComponentGlobal_NotifikasiBerhasil(result.message);
|
||||||
setLoadingLogout(true);
|
router.push("/", { scroll: false });
|
||||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
|
||||||
setKodeId("");
|
|
||||||
setOpenModal(false);
|
|
||||||
router.push(RouterAuth.login, { scroll: false });
|
|
||||||
} else {
|
|
||||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,11 +83,21 @@ export function Admin_ComponentButtonUserCircle({
|
|||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<Center>
|
<SimpleGrid cols={2}>
|
||||||
<Button radius={"xl"} onClick={() => setOpenModal(true)}>
|
<Button
|
||||||
|
radius={"xl"}
|
||||||
|
onClick={() => router.push("/dev/home", { scroll: false })}
|
||||||
|
>
|
||||||
|
User Access
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
radius={"xl"}
|
||||||
|
color="red"
|
||||||
|
onClick={() => setOpenModal(true)}
|
||||||
|
>
|
||||||
Keluar
|
Keluar
|
||||||
</Button>
|
</Button>
|
||||||
</Center>
|
</SimpleGrid>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Popover.Dropdown>
|
</Popover.Dropdown>
|
||||||
</Popover>
|
</Popover>
|
||||||
@@ -114,7 +115,6 @@ export function Admin_ComponentButtonUserCircle({
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenModal(false);
|
setOpenModal(false);
|
||||||
setLoading(false);
|
|
||||||
}}
|
}}
|
||||||
radius={50}
|
radius={50}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ import adminNotifikasi_funCreateToUser from "../../notifikasi/fun/create/fun_cre
|
|||||||
import { adminEvent_funGetListReview } from "../fun";
|
import { adminEvent_funGetListReview } from "../fun";
|
||||||
import { AdminEvent_funEditStatusPublishById } from "../fun/edit/fun_edit_status_publish_by_id";
|
import { AdminEvent_funEditStatusPublishById } from "../fun/edit/fun_edit_status_publish_by_id";
|
||||||
import { AdminEvent_funEditCatatanById } from "../fun/edit/fun_edit_status_reject_by_id";
|
import { AdminEvent_funEditCatatanById } from "../fun/edit/fun_edit_status_reject_by_id";
|
||||||
|
import { event_checkStatus } from "@/app_modules/event/fun/get/fun_check_status_by_id";
|
||||||
|
import { ComponentAdminGlobal_NotifikasiPeringatan } from "../../_admin_global/admin_notifikasi/notifikasi_peringatan";
|
||||||
|
|
||||||
export default function AdminEvent_ComponentTableReview({
|
export default function AdminEvent_ComponentTableReview({
|
||||||
listData,
|
listData,
|
||||||
@@ -104,51 +106,65 @@ export default function AdminEvent_ComponentTableReview({
|
|||||||
setIsAdminTriggerReview(false);
|
setIsAdminTriggerReview(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onPublish(eventId: string, tanggal: Date) {
|
async function onPublish({
|
||||||
if (moment(tanggal).diff(Date.now(), "minutes") < 0)
|
eventId,
|
||||||
return ComponentGlobal_NotifikasiPeringatan(
|
tanggal,
|
||||||
"Waktu acara telah lewat, Report untuk memberitahu user !"
|
}: {
|
||||||
);
|
eventId: string;
|
||||||
|
tanggal: Date;
|
||||||
|
}) {
|
||||||
|
const checkStatus = await event_checkStatus({ id: eventId });
|
||||||
|
|
||||||
const res = await AdminEvent_funEditStatusPublishById(eventId, "1");
|
if (checkStatus) {
|
||||||
if (res.status === 200) {
|
if (moment(tanggal).diff(Date.now(), "minutes") < 0)
|
||||||
const dataNotifikasi: IRealtimeData = {
|
return ComponentGlobal_NotifikasiPeringatan(
|
||||||
appId: res.data?.id as any,
|
"Waktu acara telah lewat, Report untuk memberitahu user !"
|
||||||
status: res.data?.EventMaster_Status?.name as any,
|
);
|
||||||
userId: res.data?.authorId as any,
|
|
||||||
pesan: res.data?.title as any,
|
|
||||||
kategoriApp: "EVENT",
|
|
||||||
title: "Event publish",
|
|
||||||
};
|
|
||||||
|
|
||||||
const notif = await adminNotifikasi_funCreateToUser({
|
const res = await AdminEvent_funEditStatusPublishById(eventId, "1");
|
||||||
data: dataNotifikasi as any,
|
if (res.status === 200) {
|
||||||
});
|
const dataNotifikasi: IRealtimeData = {
|
||||||
|
appId: res.data?.id as any,
|
||||||
|
status: res.data?.EventMaster_Status?.name as any,
|
||||||
|
userId: res.data?.authorId as any,
|
||||||
|
pesan: res.data?.title as any,
|
||||||
|
kategoriApp: "EVENT",
|
||||||
|
title: "Event publish",
|
||||||
|
};
|
||||||
|
|
||||||
if (notif.status === 201) {
|
const notif = await adminNotifikasi_funCreateToUser({
|
||||||
WibuRealtime.setData({
|
data: dataNotifikasi as any,
|
||||||
type: "notification",
|
|
||||||
pushNotificationTo: "USER",
|
|
||||||
dataMessage: dataNotifikasi,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
WibuRealtime.setData({
|
if (notif.status === 201) {
|
||||||
type: "trigger",
|
WibuRealtime.setData({
|
||||||
pushNotificationTo: "USER",
|
type: "notification",
|
||||||
dataMessage: dataNotifikasi,
|
pushNotificationTo: "USER",
|
||||||
|
dataMessage: dataNotifikasi,
|
||||||
|
});
|
||||||
|
|
||||||
|
WibuRealtime.setData({
|
||||||
|
type: "trigger",
|
||||||
|
pushNotificationTo: "USER",
|
||||||
|
dataMessage: dataNotifikasi,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadData = await adminEvent_funGetListReview({
|
||||||
|
search: isSearch,
|
||||||
|
page: isActivePage,
|
||||||
});
|
});
|
||||||
|
setData(loadData.data as any);
|
||||||
|
setNPage(loadData.nPage);
|
||||||
|
|
||||||
|
ComponentAdminGlobal_NotifikasiBerhasil("Berhasil update status");
|
||||||
|
} else {
|
||||||
|
ComponentAdminGlobal_NotifikasiGagal(res.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadData = await adminEvent_funGetListReview({
|
|
||||||
search: isSearch,
|
|
||||||
page: isActivePage,
|
|
||||||
});
|
|
||||||
setData(loadData.data as any);
|
|
||||||
setNPage(loadData.nPage);
|
|
||||||
|
|
||||||
ComponentAdminGlobal_NotifikasiBerhasil("Berhasil update status");
|
|
||||||
} else {
|
} else {
|
||||||
ComponentAdminGlobal_NotifikasiGagal(res.message);
|
ComponentAdminGlobal_NotifikasiPeringatan(
|
||||||
|
"Review di batalkan oleh user, reload halaman review !"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,19 +234,40 @@ export default function AdminEvent_ComponentTableReview({
|
|||||||
<Text>{e.EventMaster_TipeAcara.name}</Text>
|
<Text>{e.EventMaster_TipeAcara.name}</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<Center w={200}>
|
<Center w={200}>
|
||||||
{e.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}
|
<Text align="center">
|
||||||
|
{" "}
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Center w={200}>
|
<Center w={200}>
|
||||||
{e.tanggal.toLocaleTimeString([], {
|
<Text align="center">
|
||||||
timeStyle: "short",
|
{" "}
|
||||||
hourCycle: "h24",
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
})}
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<Center w={400}>
|
<Center w={400}>
|
||||||
<Spoiler hideLabel="sembunyikan" maxHeight={50} showLabel="tampilkan">
|
<Spoiler hideLabel="sembunyikan" maxHeight={50} showLabel="tampilkan">
|
||||||
@@ -246,7 +283,12 @@ export default function AdminEvent_ComponentTableReview({
|
|||||||
color={"green"}
|
color={"green"}
|
||||||
leftIcon={<IconCircleCheck />}
|
leftIcon={<IconCircleCheck />}
|
||||||
radius={"xl"}
|
radius={"xl"}
|
||||||
onClick={() => onPublish(e.id, e.tanggal)}
|
onClick={() =>
|
||||||
|
onPublish({
|
||||||
|
eventId: e.id,
|
||||||
|
tanggal: e.tanggal,
|
||||||
|
})
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Publish
|
Publish
|
||||||
</Button>
|
</Button>
|
||||||
@@ -254,9 +296,17 @@ export default function AdminEvent_ComponentTableReview({
|
|||||||
color={"red"}
|
color={"red"}
|
||||||
leftIcon={<IconBan />}
|
leftIcon={<IconBan />}
|
||||||
radius={"xl"}
|
radius={"xl"}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
open();
|
const checkStatus = await event_checkStatus({ id: e.id });
|
||||||
setEventId(e.id);
|
|
||||||
|
if (checkStatus) {
|
||||||
|
open();
|
||||||
|
setEventId(e.id);
|
||||||
|
} else {
|
||||||
|
ComponentAdminGlobal_NotifikasiPeringatan(
|
||||||
|
"Review di batalkan oleh user, muat kembali halaman ini !"
|
||||||
|
);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Reject
|
Reject
|
||||||
@@ -334,10 +384,10 @@ export default function AdminEvent_ComponentTableReview({
|
|||||||
<Center>Tipe Acara</Center>
|
<Center>Tipe Acara</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Tanggal</Center>
|
<Center>Tanggal & Waktu Mulai</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Jam</Center>
|
<Center>Tanggal & Waktu Selesai</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Deskripsi</Center>
|
<Center>Deskripsi</Center>
|
||||||
|
|||||||
@@ -1,19 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { RouterAdminEvent } from "@/app/lib/router_admin/router_admin_event";
|
import { RouterAdminEvent } from "@/app/lib/router_admin/router_admin_event";
|
||||||
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
|
import { MODEL_EVENT } from "@/app_modules/event/model/interface";
|
||||||
import {
|
import {
|
||||||
MODEL_EVENT,
|
|
||||||
MODEL_EVENT_PESERTA,
|
|
||||||
} from "@/app_modules/event/model/interface";
|
|
||||||
import {
|
|
||||||
Avatar,
|
|
||||||
Button,
|
Button,
|
||||||
Center,
|
Center,
|
||||||
Divider,
|
|
||||||
Grid,
|
|
||||||
Group,
|
Group,
|
||||||
Modal,
|
|
||||||
Pagination,
|
Pagination,
|
||||||
Paper,
|
Paper,
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
@@ -24,7 +16,6 @@ import {
|
|||||||
TextInput,
|
TextInput,
|
||||||
Title,
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useDisclosure } from "@mantine/hooks";
|
|
||||||
import { IconCircleCheck, IconSearch } from "@tabler/icons-react";
|
import { IconCircleCheck, IconSearch } from "@tabler/icons-react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@@ -80,11 +71,14 @@ function DetailRiwayat({ listRiwayat }: { listRiwayat: any }) {
|
|||||||
<tr key={i}>
|
<tr key={i}>
|
||||||
<td>
|
<td>
|
||||||
<Button
|
<Button
|
||||||
|
loaderPosition="center"
|
||||||
loading={e.id === eventId && loading ? true : false}
|
loading={e.id === eventId && loading ? true : false}
|
||||||
color={"green"}
|
color={"green"}
|
||||||
leftIcon={<IconCircleCheck />}
|
leftIcon={<IconCircleCheck />}
|
||||||
radius={"xl"}
|
radius={"xl"}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
setEventId(e.id);
|
||||||
|
setLoading(true);
|
||||||
router.push(RouterAdminEvent.detail_peserta + e.id);
|
router.push(RouterAdminEvent.detail_peserta + e.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -112,19 +106,40 @@ function DetailRiwayat({ listRiwayat }: { listRiwayat: any }) {
|
|||||||
<Text>{e.EventMaster_TipeAcara.name}</Text>
|
<Text>{e.EventMaster_TipeAcara.name}</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<Center w={200}>
|
<Center w={200}>
|
||||||
{e.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}
|
<Text align="center">
|
||||||
|
{" "}
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Center w={200}>
|
<Center w={200}>
|
||||||
{e.tanggal.toLocaleTimeString([], {
|
<Text align="center">
|
||||||
timeStyle: "short",
|
{" "}
|
||||||
hourCycle: "h24",
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
})}
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<Center w={400}>
|
<Center w={400}>
|
||||||
<Spoiler hideLabel="sembunyikan" maxHeight={50} showLabel="tampilkan">
|
<Spoiler hideLabel="sembunyikan" maxHeight={50} showLabel="tampilkan">
|
||||||
@@ -183,10 +198,10 @@ function DetailRiwayat({ listRiwayat }: { listRiwayat: any }) {
|
|||||||
<Center>Tipe Acara</Center>
|
<Center>Tipe Acara</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Tanggal</Center>
|
<Center>Tanggal & Waktu Mulai</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Jam</Center>
|
<Center>Tanggal & Waktu Selesai</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Deskripsi</Center>
|
<Center>Deskripsi</Center>
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ export default async function AdminEvent_funCountByStatusId(statusId: string) {
|
|||||||
const count = await prisma.event.count({
|
const count = await prisma.event.count({
|
||||||
where: {
|
where: {
|
||||||
eventMaster_StatusId: "1",
|
eventMaster_StatusId: "1",
|
||||||
tanggal: {
|
isArsip: false
|
||||||
gte: new Date
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return count;
|
return count;
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ export async function AdminEvent_funCountRiwayat() {
|
|||||||
const data = await prisma.event.count({
|
const data = await prisma.event.count({
|
||||||
where: {
|
where: {
|
||||||
eventMaster_StatusId: "1",
|
eventMaster_StatusId: "1",
|
||||||
tanggal: {
|
isArsip: true,
|
||||||
lte: new Date(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ export async function adminEvent_funGetListAllRiwayat({
|
|||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
eventMaster_StatusId: "1",
|
eventMaster_StatusId: "1",
|
||||||
tanggal: {
|
isArsip: true,
|
||||||
lte: new Date(),
|
|
||||||
},
|
|
||||||
title: {
|
title: {
|
||||||
contains: search,
|
contains: search,
|
||||||
mode: "insensitive",
|
mode: "insensitive",
|
||||||
@@ -49,9 +47,7 @@ export async function adminEvent_funGetListAllRiwayat({
|
|||||||
const nCount = await prisma.event.count({
|
const nCount = await prisma.event.count({
|
||||||
where: {
|
where: {
|
||||||
eventMaster_StatusId: "1",
|
eventMaster_StatusId: "1",
|
||||||
tanggal: {
|
isArsip: true,
|
||||||
lte: new Date(),
|
|
||||||
},
|
|
||||||
title: {
|
title: {
|
||||||
contains: search,
|
contains: search,
|
||||||
mode: "insensitive",
|
mode: "insensitive",
|
||||||
|
|||||||
@@ -1,146 +0,0 @@
|
|||||||
"use server";
|
|
||||||
|
|
||||||
import prisma from "@/app/lib/prisma";
|
|
||||||
|
|
||||||
export async function AdminEvent_getListTableByStatusId(statudId: string) {
|
|
||||||
if (statudId === "1") {
|
|
||||||
const getPublish = await prisma.event.findMany({
|
|
||||||
orderBy: {
|
|
||||||
tanggal: "desc",
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
eventMaster_StatusId: "1",
|
|
||||||
tanggal: {
|
|
||||||
gte: new Date(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
title: true,
|
|
||||||
lokasi: true,
|
|
||||||
tanggal: true,
|
|
||||||
deskripsi: true,
|
|
||||||
Author: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
username: true,
|
|
||||||
Profile: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventMaster_Status: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventMaster_TipeAcara: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Event_Peserta: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return getPublish;
|
|
||||||
}
|
|
||||||
if (statudId === "2") {
|
|
||||||
const getReview = await prisma.event.findMany({
|
|
||||||
orderBy: {
|
|
||||||
updatedAt: "desc",
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
eventMaster_StatusId: "2",
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
title: true,
|
|
||||||
lokasi: true,
|
|
||||||
tanggal: true,
|
|
||||||
deskripsi: true,
|
|
||||||
Author: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
username: true,
|
|
||||||
Profile: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventMaster_Status: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventMaster_TipeAcara: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return getReview;
|
|
||||||
}
|
|
||||||
if (statudId === "3") {
|
|
||||||
const getDraft = await prisma.event.findMany({
|
|
||||||
orderBy: {
|
|
||||||
updatedAt: "desc",
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
eventMaster_StatusId: "3",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return getDraft;
|
|
||||||
}
|
|
||||||
if (statudId === "4") {
|
|
||||||
const getReject = await prisma.event.findMany({
|
|
||||||
orderBy: {
|
|
||||||
updatedAt: "desc",
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
eventMaster_StatusId: "4",
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
title: true,
|
|
||||||
lokasi: true,
|
|
||||||
tanggal: true,
|
|
||||||
deskripsi: true,
|
|
||||||
Author: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
username: true,
|
|
||||||
Profile: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventMaster_Status: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventMaster_TipeAcara: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
catatan: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return getReject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
import prisma from "@/app/lib/prisma";
|
import prisma from "@/app/lib/prisma";
|
||||||
|
import { ComponentAdminGlobal_NotifikasiPeringatan } from "@/app_modules/admin/_admin_global/admin_notifikasi/notifikasi_peringatan";
|
||||||
import { ceil } from "lodash";
|
import { ceil } from "lodash";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
export async function adminEvent_funGetListPublish({
|
export async function adminEvent_funGetListPublish({
|
||||||
page,
|
page,
|
||||||
@@ -10,6 +12,27 @@ export async function adminEvent_funGetListPublish({
|
|||||||
page: number;
|
page: number;
|
||||||
search?: string;
|
search?: string;
|
||||||
}) {
|
}) {
|
||||||
|
const getAllData = await prisma.event.findMany({
|
||||||
|
where: {
|
||||||
|
active: true,
|
||||||
|
eventMaster_StatusId: "1",
|
||||||
|
isArsip: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i of getAllData) {
|
||||||
|
if (moment(i.tanggalSelesai).diff(moment(), "minutes") < 0) {
|
||||||
|
await prisma.event.update({
|
||||||
|
where: {
|
||||||
|
id: i.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
isArsip: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let takeData = 10;
|
let takeData = 10;
|
||||||
let skipData = page * takeData - takeData;
|
let skipData = page * takeData - takeData;
|
||||||
|
|
||||||
@@ -21,9 +44,7 @@ export async function adminEvent_funGetListPublish({
|
|||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
eventMaster_StatusId: "1",
|
eventMaster_StatusId: "1",
|
||||||
tanggal: {
|
isArsip: false,
|
||||||
gte: new Date(),
|
|
||||||
},
|
|
||||||
title: {
|
title: {
|
||||||
contains: search,
|
contains: search,
|
||||||
mode: "insensitive",
|
mode: "insensitive",
|
||||||
@@ -49,9 +70,7 @@ export async function adminEvent_funGetListPublish({
|
|||||||
const nCount = await prisma.event.count({
|
const nCount = await prisma.event.count({
|
||||||
where: {
|
where: {
|
||||||
eventMaster_StatusId: "1",
|
eventMaster_StatusId: "1",
|
||||||
tanggal: {
|
isArsip: false,
|
||||||
gte: new Date(),
|
|
||||||
},
|
|
||||||
title: {
|
title: {
|
||||||
contains: search,
|
contains: search,
|
||||||
mode: "insensitive",
|
mode: "insensitive",
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { RouterAdminEvent } from "@/app/lib/router_admin/router_admin_event";
|
||||||
|
import { MODEL_EVENT } from "@/app_modules/event/model/interface";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Center,
|
Center,
|
||||||
Divider,
|
|
||||||
Grid,
|
|
||||||
Group,
|
Group,
|
||||||
Modal,
|
|
||||||
Pagination,
|
Pagination,
|
||||||
Paper,
|
Paper,
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
@@ -19,20 +17,14 @@ import {
|
|||||||
TextInput,
|
TextInput,
|
||||||
Title,
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { IconCircleCheck, IconEyeShare, IconSearch } from "@tabler/icons-react";
|
import { IconCircleCheck, IconSearch } from "@tabler/icons-react";
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { useDisclosure } from "@mantine/hooks";
|
|
||||||
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
|
|
||||||
import {
|
|
||||||
MODEL_EVENT,
|
|
||||||
MODEL_EVENT_PESERTA,
|
|
||||||
} from "@/app_modules/event/model/interface";
|
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate";
|
import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate";
|
||||||
import { adminEvent_getListPesertaById } from "../fun/get/get_list_peserta_by_id";
|
|
||||||
import { adminEvent_funGetListPublish } from "../fun";
|
import { adminEvent_funGetListPublish } from "../fun";
|
||||||
import { RouterAdminEvent } from "@/app/lib/router_admin/router_admin_event";
|
import QRCode from "react-qr-code";
|
||||||
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
|
||||||
export default function AdminEvent_TablePublish({
|
export default function AdminEvent_TablePublish({
|
||||||
listPublish,
|
listPublish,
|
||||||
@@ -58,6 +50,21 @@ function TableStatus({ listPublish }: { listPublish: any }) {
|
|||||||
const [eventId, setEventId] = useState("");
|
const [eventId, setEventId] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const [origin, setOrigin] = useState("");
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
console.log(window.location.origin);
|
||||||
|
setOrigin(window.location.origin);
|
||||||
|
}
|
||||||
|
}, [setOrigin]);
|
||||||
|
|
||||||
|
// async function onLoadOrigin(setOrigin: any) {
|
||||||
|
// const res = await fetch("/api/origin-url");
|
||||||
|
// const result = await res.json();
|
||||||
|
// setOrigin(result.origin);
|
||||||
|
// }
|
||||||
|
|
||||||
async function onSearch(s: string) {
|
async function onSearch(s: string) {
|
||||||
setSearch(s);
|
setSearch(s);
|
||||||
const loadData = await adminEvent_funGetListPublish({
|
const loadData = await adminEvent_funGetListPublish({
|
||||||
@@ -78,64 +85,137 @@ function TableStatus({ listPublish }: { listPublish: any }) {
|
|||||||
setNPage(loadData.nPage);
|
setNPage(loadData.nPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TableRows = data.map((e, i) => (
|
const TableRows = _.isEmpty(data) ? (
|
||||||
<tr key={i}>
|
<tr>
|
||||||
<td>
|
<td colSpan={12}>
|
||||||
<Center w={200}>
|
<Center>Belum Ada Data</Center>
|
||||||
<Text>{e?.Author?.username}</Text>
|
|
||||||
</Center>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Center w={200}>
|
|
||||||
<Text lineClamp={2}>{e.title}</Text>
|
|
||||||
</Center>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Center w={200}>
|
|
||||||
<Text>{e.lokasi}</Text>
|
|
||||||
</Center>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Center w={200}>
|
|
||||||
<Text>{e.EventMaster_TipeAcara.name}</Text>
|
|
||||||
</Center>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Center w={200}>
|
|
||||||
{e.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}
|
|
||||||
</Center>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Center w={200}>
|
|
||||||
{e.tanggal.toLocaleTimeString([], {
|
|
||||||
timeStyle: "short",
|
|
||||||
hourCycle: "h24",
|
|
||||||
})}
|
|
||||||
</Center>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Center w={400}>
|
|
||||||
<Spoiler hideLabel="sembunyikan" maxHeight={50} showLabel="tampilkan">
|
|
||||||
{e.deskripsi}
|
|
||||||
</Spoiler>
|
|
||||||
</Center>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<Button
|
|
||||||
loading={e.id === eventId ? (loading === true ? true : false) : false}
|
|
||||||
color={"green"}
|
|
||||||
leftIcon={<IconCircleCheck />}
|
|
||||||
radius={"xl"}
|
|
||||||
onClick={async () => {
|
|
||||||
router.push(RouterAdminEvent.detail_peserta + e.id);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Lihat Peserta
|
|
||||||
</Button>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
));
|
) : (
|
||||||
|
data.map((e, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<QRCode
|
||||||
|
id={e.id}
|
||||||
|
style={{ height: 70, width: 70 }}
|
||||||
|
value={`${origin}/dev/event/konfirmasi/${e.id}`}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<input
|
||||||
|
type="button"
|
||||||
|
value="Download QR"
|
||||||
|
onClick={() => {
|
||||||
|
const svg: any = document.getElementById(e.id);
|
||||||
|
const svgData = new XMLSerializer().serializeToString(svg);
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
const ctx: any = canvas.getContext("2d");
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
canvas.width = img.width;
|
||||||
|
canvas.height = img.height;
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
const pngFile = canvas.toDataURL("image/png");
|
||||||
|
const downloadLink = document.createElement("a");
|
||||||
|
downloadLink.download = `QRCode ${e.title}`;
|
||||||
|
downloadLink.href = `${pngFile}`;
|
||||||
|
downloadLink.click();
|
||||||
|
};
|
||||||
|
img.src = `data:image/svg+xml;base64,${btoa(svgData)}`;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<Text>{e?.Author?.username}</Text>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<Text lineClamp={2}>{e.title}</Text>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<Text>{e.lokasi}</Text>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<Text>{e.EventMaster_TipeAcara.name}</Text>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<Text align="center">
|
||||||
|
{" "}
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Center w={200}>
|
||||||
|
<Text align="center">
|
||||||
|
{" "}
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<Center w={400}>
|
||||||
|
<Spoiler
|
||||||
|
hideLabel="sembunyikan"
|
||||||
|
maxHeight={50}
|
||||||
|
showLabel="tampilkan"
|
||||||
|
>
|
||||||
|
{e.deskripsi}
|
||||||
|
</Spoiler>
|
||||||
|
</Center>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<Button
|
||||||
|
loaderPosition="center"
|
||||||
|
loading={
|
||||||
|
e.id === eventId ? (loading === true ? true : false) : false
|
||||||
|
}
|
||||||
|
color={"green"}
|
||||||
|
leftIcon={<IconCircleCheck />}
|
||||||
|
radius={"xl"}
|
||||||
|
onClick={async () => {
|
||||||
|
setEventId(e.id);
|
||||||
|
setLoading(true);
|
||||||
|
router.push(RouterAdminEvent.detail_peserta + e.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Lihat Peserta
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -169,6 +249,13 @@ function TableStatus({ listPublish }: { listPublish: any }) {
|
|||||||
>
|
>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>
|
||||||
|
<Center>QR Code</Center>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<Center>Download QR</Center>
|
||||||
|
</th>
|
||||||
|
|
||||||
<th>
|
<th>
|
||||||
<Center>Username</Center>
|
<Center>Username</Center>
|
||||||
</th>
|
</th>
|
||||||
@@ -182,11 +269,12 @@ function TableStatus({ listPublish }: { listPublish: any }) {
|
|||||||
<Center>Tipe Acara</Center>
|
<Center>Tipe Acara</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Tanggal</Center>
|
<Center>Tanggal & Waktu Mulai</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Jam</Center>
|
<Center>Tanggal & Waktu Selesai</Center>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th>
|
<th>
|
||||||
<Center>Deskripsi</Center>
|
<Center>Deskripsi</Center>
|
||||||
</th>
|
</th>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
Spoiler,
|
Spoiler,
|
||||||
Stack,
|
Stack,
|
||||||
Table,
|
Table,
|
||||||
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
TextInput,
|
TextInput,
|
||||||
Title,
|
Title,
|
||||||
@@ -106,19 +107,40 @@ function TableStatus({ listReject }: { listReject: any }) {
|
|||||||
<td>
|
<td>
|
||||||
<Center w={200}>{e.EventMaster_TipeAcara.name}</Center>
|
<Center w={200}>{e.EventMaster_TipeAcara.name}</Center>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<Center w={200}>
|
<Center w={200}>
|
||||||
{e.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}
|
<Text align="center">
|
||||||
|
{" "}
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggal)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Center w={100}>
|
<Center w={200}>
|
||||||
{e.tanggal.toLocaleTimeString([], {
|
<Text align="center">
|
||||||
timeStyle: "short",
|
{" "}
|
||||||
hourCycle: "h24",
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
})}
|
dateStyle: "full",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(e?.tanggalSelesai)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
</Center>
|
</Center>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<Center w={500}>
|
<Center w={500}>
|
||||||
<Spoiler hideLabel="sembunyikan" maxHeight={50} showLabel="tampilkan">
|
<Spoiler hideLabel="sembunyikan" maxHeight={50} showLabel="tampilkan">
|
||||||
@@ -197,10 +219,10 @@ function TableStatus({ listReject }: { listReject: any }) {
|
|||||||
<Center>Tipe Acara</Center>
|
<Center>Tipe Acara</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Tanggal</Center>
|
<Center>Tanggal & Waktu Mulai</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Jam</Center>
|
<Center>Tanggal & Waktu Selesai</Center>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Center>Cacatan</Center>
|
<Center>Cacatan</Center>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { gs_admin_ntf } from "@/app/lib/global_state";
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
AppShell,
|
AppShell,
|
||||||
|
Button,
|
||||||
Divider,
|
Divider,
|
||||||
Drawer,
|
Drawer,
|
||||||
Grid,
|
Grid,
|
||||||
@@ -18,8 +19,10 @@ import {
|
|||||||
import { useMediaQuery, useShallowEffect } from "@mantine/hooks";
|
import { useMediaQuery, useShallowEffect } from "@mantine/hooks";
|
||||||
import { IconBell } from "@tabler/icons-react";
|
import { IconBell } from "@tabler/icons-react";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { AccentColor } from "../_global/color";
|
import { AccentColor } from "../_global/color";
|
||||||
|
import { ComponentGlobal_NotifikasiBerhasil } from "../_global/notif_global";
|
||||||
import { MODEL_USER } from "../home/model/interface";
|
import { MODEL_USER } from "../home/model/interface";
|
||||||
import { MODEL_NOTIFIKASI } from "../notifikasi/model/interface";
|
import { MODEL_NOTIFIKASI } from "../notifikasi/model/interface";
|
||||||
import {
|
import {
|
||||||
@@ -47,6 +50,7 @@ export function Admin_NewLayout({
|
|||||||
listNotifikasi: MODEL_NOTIFIKASI[];
|
listNotifikasi: MODEL_NOTIFIKASI[];
|
||||||
version: string;
|
version: string;
|
||||||
}) {
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
const matches = useMediaQuery("(min-width: 1024px)");
|
const matches = useMediaQuery("(min-width: 1024px)");
|
||||||
const [dataUser, setDataUser] = useState(user);
|
const [dataUser, setDataUser] = useState(user);
|
||||||
const userRoleId = dataUser.masterUserRoleId;
|
const userRoleId = dataUser.masterUserRoleId;
|
||||||
@@ -72,6 +76,20 @@ export function Admin_NewLayout({
|
|||||||
setDrawerNotifikasi(true);
|
setDrawerNotifikasi(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [loadingLogout, setLoadingLogout] = useState(false);
|
||||||
|
async function onClickLogout() {
|
||||||
|
setLoadingLogout(true);
|
||||||
|
const res = await fetch(`/api/auth/logout?id=${user.id}`, {
|
||||||
|
method: "GET",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await res.json();
|
||||||
|
if (res.status === 200) {
|
||||||
|
ComponentGlobal_NotifikasiBerhasil(result.message);
|
||||||
|
router.push("/", { scroll: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AppShell
|
<AppShell
|
||||||
@@ -168,6 +186,7 @@ export function Admin_NewLayout({
|
|||||||
<Title order={4} align="center">
|
<Title order={4} align="center">
|
||||||
View Only Available For Desktop
|
View Only Available For Desktop
|
||||||
</Title>
|
</Title>
|
||||||
|
<Button onClick={() => onClickLogout()}>Logout</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
) : (
|
) : (
|
||||||
children
|
children
|
||||||
|
|||||||
@@ -2,12 +2,15 @@
|
|||||||
|
|
||||||
import prisma from "@/app/lib/prisma";
|
import prisma from "@/app/lib/prisma";
|
||||||
|
|
||||||
export async function auth_funDeleteAktivasiKodeOtpById({
|
export async function auth_funDeleteAktivasiKodeOtpByNomor({
|
||||||
nomor,
|
nomor,
|
||||||
}: {
|
}: {
|
||||||
nomor: string;
|
nomor: string;
|
||||||
}) {
|
}) {
|
||||||
// console.log(otpId);
|
// console.log(otpId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const updt = await prisma.kodeOtp.deleteMany({
|
const updt = await prisma.kodeOtp.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
nomor: nomor,
|
nomor: nomor,
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import SplashScreen from "./splash/view";
|
|||||||
import Login from "./login/view";
|
import Login from "./login/view";
|
||||||
import Validasi from "./validasi/view";
|
import Validasi from "./validasi/view";
|
||||||
import Register from "./register/view";
|
import Register from "./register/view";
|
||||||
import Component_Logout from "./logout/view";
|
import Component_ButtonLogout from "./logout/view";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
SplashScreen,
|
SplashScreen,
|
||||||
Login,
|
Login,
|
||||||
Validasi,
|
Validasi,
|
||||||
Register,
|
Register,
|
||||||
Component_Logout as Logout,
|
Component_ButtonLogout as Logout,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
|
||||||
import {
|
import {
|
||||||
AccentColor,
|
AccentColor,
|
||||||
MainColor,
|
MainColor,
|
||||||
@@ -8,10 +7,10 @@ import {
|
|||||||
import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input";
|
import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input";
|
||||||
import {
|
import {
|
||||||
ComponentGlobal_NotifikasiBerhasil,
|
ComponentGlobal_NotifikasiBerhasil,
|
||||||
|
ComponentGlobal_NotifikasiGagal,
|
||||||
ComponentGlobal_NotifikasiPeringatan,
|
ComponentGlobal_NotifikasiPeringatan,
|
||||||
} from "@/app_modules/_global/notif_global";
|
} from "@/app_modules/_global/notif_global";
|
||||||
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
||||||
import { auth_funLogin } from "@/app_modules/auth/fun/fun_login";
|
|
||||||
import { Box, Button, Center, Stack, Text, Title } from "@mantine/core";
|
import { Box, Button, Center, Stack, Text, Title } from "@mantine/core";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@@ -28,23 +27,28 @@ export default function Login({ version }: { version: string }) {
|
|||||||
const nomor = phone.substring(1);
|
const nomor = phone.substring(1);
|
||||||
if (nomor.length <= 4) return setError(true);
|
if (nomor.length <= 4) return setError(true);
|
||||||
|
|
||||||
const res = await auth_funLogin({ nomor: nomor });
|
setLoading(true);
|
||||||
if (res.status === 200) {
|
try {
|
||||||
setLoading(true);
|
const res = await fetch("/api/auth/login", {
|
||||||
ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
|
method: "POST",
|
||||||
// router.push(RouterAuth.validasi + res.kodeId, { scroll: false });
|
body: JSON.stringify({ nomor: nomor }),
|
||||||
router.push("/validasi/" + res.kodeId, { scroll: false });
|
headers: {
|
||||||
} else {
|
"Content-Type": "application/json",
|
||||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
},
|
||||||
}
|
});
|
||||||
|
|
||||||
// await fetch(ApiHipmi.login, {
|
const result = await res.json();
|
||||||
// method: "POST",
|
if (res.status === 200) {
|
||||||
// headers: {
|
localStorage.setItem("hipmi_auth_code_id", result.kodeId);
|
||||||
// "Content-Type": "application/json",
|
ComponentGlobal_NotifikasiBerhasil(result.message, 2000);
|
||||||
// },
|
router.push("/validasi", { scroll: false });
|
||||||
// body: JSON.stringify(body),
|
} else {
|
||||||
// })
|
ComponentGlobal_NotifikasiPeringatan(result.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
ComponentGlobal_NotifikasiGagal("Terjadi Kesalahan");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -96,16 +100,11 @@ export default function Login({ version }: { version: string }) {
|
|||||||
|
|
||||||
<Box pos={"fixed"} bottom={10}>
|
<Box pos={"fixed"} bottom={10}>
|
||||||
<Text fw={"bold"} c={"white"} fs={"italic"} fz={"xs"}>
|
<Text fw={"bold"} c={"white"} fs={"italic"} fz={"xs"}>
|
||||||
V.{version}
|
v {version}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
</UIGlobal_LayoutDefault>
|
</UIGlobal_LayoutDefault>
|
||||||
{/* <BackgroundImage
|
|
||||||
src={"/aset/global/main_background.png"}
|
|
||||||
h={"100vh"}
|
|
||||||
// pos={"static"}
|
|
||||||
></BackgroundImage> */}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,18 +11,21 @@ import { useState } from "react";
|
|||||||
import { auth_Logout } from "../fun/fun_logout";
|
import { auth_Logout } from "../fun/fun_logout";
|
||||||
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
||||||
|
|
||||||
export default function Component_Logout() {
|
export default function Component_ButtonLogout({userId}: {userId: string}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [opened, setOpened] = useState(false);
|
const [opened, setOpened] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
async function onClickLogout() {
|
async function onClickLogout() {
|
||||||
const res = await auth_Logout();
|
setLoading(true);
|
||||||
|
const res = await fetch(`/api/auth/logout?id=${userId}`, {
|
||||||
|
method: "GET",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await res.json();
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
ComponentGlobal_NotifikasiBerhasil(result.message);
|
||||||
router.push("/login", { scroll: false });
|
router.push("/", { scroll: false });
|
||||||
} else {
|
|
||||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +52,6 @@ export default function Component_Logout() {
|
|||||||
bg={Warna.merah}
|
bg={Warna.merah}
|
||||||
color="red"
|
color="red"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setLoading(true);
|
|
||||||
onClickLogout();
|
onClickLogout();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
19
src/app_modules/auth/register/skeleton.tsx
Normal file
19
src/app_modules/auth/register/skeleton.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { Stack, Skeleton } from "@mantine/core";
|
||||||
|
|
||||||
|
export default function Register_SkeletonView() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack h={"100vh"} align="center" justify="center" spacing={50}>
|
||||||
|
<Skeleton h={30} w={250} radius={"xl"} />
|
||||||
|
|
||||||
|
<Skeleton h={100} w={100} radius={"50%"} />
|
||||||
|
|
||||||
|
<Stack spacing={"sm"}>
|
||||||
|
<Skeleton h={20} w={300} radius={"xl"} />
|
||||||
|
<Skeleton h={50} w={300} radius={"sm"} />
|
||||||
|
<Skeleton h={50} w={300} radius={"sm"} />
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,76 +1,95 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
import { MainColor } from "@/app_modules/_global/color/color_pallet";
|
||||||
import { GlobalEnv } from "@/app/lib/token";
|
|
||||||
import {
|
|
||||||
AccentColor,
|
|
||||||
MainColor,
|
|
||||||
} from "@/app_modules/_global/color/color_pallet";
|
|
||||||
import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input";
|
import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input";
|
||||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
||||||
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
||||||
import {
|
import { Button, Stack, Text, TextInput, Title } from "@mantine/core";
|
||||||
Button,
|
import { useFocusTrap, useShallowEffect } from "@mantine/hooks";
|
||||||
Center,
|
|
||||||
Stack,
|
|
||||||
Text,
|
|
||||||
TextInput,
|
|
||||||
Title
|
|
||||||
} from "@mantine/core";
|
|
||||||
import { useFocusTrap } from "@mantine/hooks";
|
|
||||||
import { IconUserCircle } from "@tabler/icons-react";
|
import { IconUserCircle } from "@tabler/icons-react";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { auth_funDeleteAktivasiKodeOtpById } from "../fun/fun_edit_aktivasi_kode_otp_by_id";
|
import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id";
|
||||||
import { Auth_funRegister } from "../fun/fun_register";
|
import Register_SkeletonView from "./skeleton";
|
||||||
|
|
||||||
export default function Register({ dataOtp }: { dataOtp: any }) {
|
export default function Register() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [nomor, setNomor] = useState(dataOtp.nomor);
|
const [nomor, setNomor] = useState("");
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [isValue, setIsValue] = useState(false);
|
const [isValue, setIsValue] = useState(false);
|
||||||
const focusTrapRef = useFocusTrap();
|
const focusTrapRef = useFocusTrap();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
const kodeId = localStorage.getItem("hipmi_auth_code_id");
|
||||||
|
if (kodeId != null) {
|
||||||
|
onCheckAuthCode({ kodeId: kodeId as string, onSetData: setNomor });
|
||||||
|
} else {
|
||||||
|
console.log("code id not found");
|
||||||
|
}
|
||||||
|
}, [setNomor]);
|
||||||
|
|
||||||
|
async function onCheckAuthCode({
|
||||||
|
kodeId,
|
||||||
|
onSetData,
|
||||||
|
}: {
|
||||||
|
kodeId: string;
|
||||||
|
onSetData: any;
|
||||||
|
}) {
|
||||||
|
const res = await fetch(`/api/auth/check?id=${kodeId}`);
|
||||||
|
const result = await res.json();
|
||||||
|
|
||||||
|
onSetData(result.data.nomor);
|
||||||
|
}
|
||||||
|
|
||||||
async function onRegistarsi() {
|
async function onRegistarsi() {
|
||||||
const body = {
|
const data = {
|
||||||
username: value,
|
username: value,
|
||||||
nomor: nomor,
|
nomor: nomor,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (body.username === "") {
|
try {
|
||||||
setIsValue(true);
|
setLoading(true);
|
||||||
return null;
|
const res = await fetch("/api/auth/register", {
|
||||||
}
|
method: "POST",
|
||||||
if (body.username.length < 5) return null;
|
body: JSON.stringify({
|
||||||
if (_.values(body.username).includes(" ")) return null;
|
data,
|
||||||
|
}),
|
||||||
const res = await Auth_funRegister({
|
headers: {
|
||||||
data: body,
|
"Content-Type": "application/json",
|
||||||
HIPMI_PWD: GlobalEnv.value?.WIBU_PWD as string,
|
},
|
||||||
});
|
|
||||||
if (res.status === 200) {
|
|
||||||
await auth_funDeleteAktivasiKodeOtpById({ nomor: nomor }).then((val) => {
|
|
||||||
if (val.status === 200) {
|
|
||||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
|
||||||
setLoading(true);
|
|
||||||
router.push(RouterHome.main_home, { scroll: false });
|
|
||||||
} else {
|
|
||||||
ComponentGlobal_NotifikasiPeringatan(val.message);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
const result = await res.json();
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
localStorage.removeItem("hipmi_auth_code_id");
|
||||||
|
ComponentGlobal_NotifikasiBerhasil(result.message);
|
||||||
|
router.push("/dev/home", { scroll: false });
|
||||||
|
|
||||||
|
await auth_funDeleteAktivasiKodeOtpByNomor({
|
||||||
|
nomor: data.nomor,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === 400) {
|
||||||
|
setLoading(false);
|
||||||
|
ComponentGlobal_NotifikasiPeringatan(result.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<UIGlobal_LayoutDefault>
|
<UIGlobal_LayoutDefault>
|
||||||
<Center h={"100vh"}>
|
{nomor == "" ? (
|
||||||
<Stack h={"100%"} align="center" justify="center" spacing={70}>
|
<Register_SkeletonView />
|
||||||
|
) : (
|
||||||
|
<Stack h={"100vh"} align="center" justify="center" spacing={50}>
|
||||||
<Title order={2} c={MainColor.yellow}>
|
<Title order={2} c={MainColor.yellow}>
|
||||||
REGISTRASI
|
REGISTRASI
|
||||||
</Title>
|
</Title>
|
||||||
@@ -78,7 +97,7 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
|
|||||||
<IconUserCircle size={100} color="white" />
|
<IconUserCircle size={100} color="white" />
|
||||||
|
|
||||||
<Stack spacing={"sm"} w={300}>
|
<Stack spacing={"sm"} w={300}>
|
||||||
<Text fz={10} c={"white"}>
|
<Text align="center" c={"white"}>
|
||||||
Anda akan terdaftar dengan nomor berikut{" "}
|
Anda akan terdaftar dengan nomor berikut{" "}
|
||||||
<Text inherit span fw={"bold"}>
|
<Text inherit span fw={"bold"}>
|
||||||
+{nomor}
|
+{nomor}
|
||||||
@@ -109,6 +128,11 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
|
|||||||
/>
|
/>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Button
|
<Button
|
||||||
|
disabled={
|
||||||
|
value === "" ||
|
||||||
|
value.length < 5 ||
|
||||||
|
_.values(value).includes(" ")
|
||||||
|
}
|
||||||
loading={loading ? true : false}
|
loading={loading ? true : false}
|
||||||
loaderPosition="center"
|
loaderPosition="center"
|
||||||
radius={"md"}
|
radius={"md"}
|
||||||
@@ -117,9 +141,6 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
|
|||||||
c={"black"}
|
c={"black"}
|
||||||
bg={MainColor.yellow}
|
bg={MainColor.yellow}
|
||||||
color={"yellow"}
|
color={"yellow"}
|
||||||
style={{
|
|
||||||
borderColor: AccentColor.yellow,
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onRegistarsi();
|
onRegistarsi();
|
||||||
}}
|
}}
|
||||||
@@ -129,7 +150,7 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Center>
|
)}
|
||||||
</UIGlobal_LayoutDefault>
|
</UIGlobal_LayoutDefault>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,63 +1,22 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
|
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
||||||
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
|
||||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
|
||||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
|
||||||
import { funGlobal_getUserById } from "@/app_modules/_global/fun/get/fun_get_user_by_id";
|
|
||||||
import { MODEL_USER } from "@/app_modules/home/model/interface";
|
|
||||||
import { Avatar, BackgroundImage, Center, Image, Stack } from "@mantine/core";
|
import { Avatar, BackgroundImage, Center, Image, Stack } from "@mantine/core";
|
||||||
import { useShallowEffect } from "@mantine/hooks";
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
export default function SplashScreen({
|
export default function SplashScreen() {
|
||||||
checkCookies,
|
|
||||||
}: {
|
|
||||||
checkCookies: boolean;
|
|
||||||
}) {
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
useShallowEffect(() => {
|
// useShallowEffect(() => {
|
||||||
// if (!checkCookies) return router.push(RouterAuth.login, { scroll: false });
|
// setTimeout(() => {
|
||||||
// onCheckUser();
|
// router.push("/dev/home", { scroll: false });
|
||||||
|
// }, 1000);
|
||||||
// setTimeout(() => {
|
// }, []);
|
||||||
// router.push(RouterAuth.login, { scroll: false });
|
|
||||||
// }, 1000);
|
|
||||||
// if (!userLoginId) {
|
|
||||||
// setTimeout(() => {
|
|
||||||
// router.push(RouterAuth.login, { scroll: false });
|
|
||||||
// }, 1000);
|
|
||||||
// } else {
|
|
||||||
// dataUser.masterUserRoleId === "1"
|
|
||||||
// ? setTimeout(() => {
|
|
||||||
// return router.push(RouterHome.main_home, { scroll: false });
|
|
||||||
// }, 1000)
|
|
||||||
// : setTimeout(() => {
|
|
||||||
// return router.push(RouterAdminDashboard.splash_admin, {
|
|
||||||
// scroll: false,
|
|
||||||
// });
|
|
||||||
// }, 1000);
|
|
||||||
// }
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// async function onCheckUser() {
|
|
||||||
// const userLoginId = await funGetUserIdByToken();
|
|
||||||
// const dataUser = await funGlobal_getUserById({ userId: userLoginId });
|
|
||||||
|
|
||||||
// if (dataUser?.masterUserRoleId == "1")
|
|
||||||
// return router.push(RouterHome.main_home);
|
|
||||||
|
|
||||||
// return router.push(RouterAdminDashboard.splash_admin);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BackgroundImage
|
<UIGlobal_LayoutDefault>
|
||||||
src={"/aset/global/main_background.png"}
|
|
||||||
h={"100vh"}
|
|
||||||
// pos={"static"}
|
|
||||||
>
|
|
||||||
<Center h={"100vh"}>
|
<Center h={"100vh"}>
|
||||||
<Stack align="center" justify="center" p={"md"}>
|
<Stack align="center" justify="center" p={"md"}>
|
||||||
{/* <Title c={"#002e59"}>Welcome to</Title> */}
|
{/* <Title c={"#002e59"}>Welcome to</Title> */}
|
||||||
@@ -71,7 +30,7 @@ export default function SplashScreen({
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Center>
|
</Center>
|
||||||
</BackgroundImage>
|
</UIGlobal_LayoutDefault>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/app_modules/auth/validasi/skeleton.tsx
Normal file
25
src/app_modules/auth/validasi/skeleton.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { Stack, Skeleton, Group } from "@mantine/core";
|
||||||
|
|
||||||
|
export default function Validasi_SkeletonView() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack align="center" justify="center" h={"100vh"} spacing={50}>
|
||||||
|
<Skeleton h={30} w={250} radius={"xl"} />
|
||||||
|
<Stack>
|
||||||
|
<Skeleton h={20} w={250} radius={"xl"} />
|
||||||
|
<Skeleton h={20} w={250} radius={"xl"} />
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Group>
|
||||||
|
{Array.from({ length: 4 }).map((_, i) => (
|
||||||
|
<Skeleton key={i} h={50} w={50} radius={"sm"} />
|
||||||
|
))}
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Skeleton h={20} w={250} radius={"xl"} />
|
||||||
|
|
||||||
|
<Skeleton h={50} w={250} radius={"sm"} />
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
|
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 { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
||||||
import { GlobalEnv } from "@/app/lib/token";
|
|
||||||
import {
|
import {
|
||||||
AccentColor,
|
AccentColor,
|
||||||
MainColor,
|
MainColor,
|
||||||
@@ -12,107 +10,175 @@ import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_
|
|||||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
||||||
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
|
||||||
Box,
|
|
||||||
Button,
|
Button,
|
||||||
Center,
|
Center,
|
||||||
|
Loader,
|
||||||
PinInput,
|
PinInput,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
Title,
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useFocusTrap, useShallowEffect } 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 { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useEffect, 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";
|
|
||||||
|
|
||||||
export default function Validasi({
|
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global";
|
||||||
dataOtp,
|
import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id";
|
||||||
}: {
|
import Validasi_SkeletonView from "./skeleton";
|
||||||
dataOtp: Prisma.KodeOtpSelect;
|
|
||||||
}) {
|
export default function Validasi() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const nomor = dataOtp.nomor as any;
|
|
||||||
const code = dataOtp.otp as any;
|
|
||||||
const [inputCode, setInputOtp] = useState("");
|
const [inputCode, setInputOtp] = useState("");
|
||||||
const focusTrapRef = useFocusTrap();
|
const focusTrapRef = useFocusTrap();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const [counter, setCounter] = useState(60);
|
const [counter, setCounter] = useState(60);
|
||||||
|
const [loadingResend, setLoadingResend] = useState(false);
|
||||||
|
const [triggerOtp, setTriggerOtp] = useState(false);
|
||||||
|
|
||||||
|
const [data, setData] = useState({
|
||||||
|
nomor: "",
|
||||||
|
code: "",
|
||||||
|
});
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
|
const kodeId = localStorage.getItem("hipmi_auth_code_id");
|
||||||
|
if (kodeId != null) {
|
||||||
|
onCheckAuthCode({ kodeId: kodeId as string, onSetData: setData });
|
||||||
|
} else {
|
||||||
|
console.log("code id not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerOtp) {
|
||||||
|
const kodeId = localStorage.getItem("hipmi_auth_code_id");
|
||||||
|
if (kodeId != null) {
|
||||||
|
onCheckAuthCode({ kodeId: kodeId as string, onSetData: setData });
|
||||||
|
} else {
|
||||||
|
console.log("code id not found");
|
||||||
|
}
|
||||||
|
setTriggerOtp(false);
|
||||||
|
}
|
||||||
|
}, [triggerOtp, setData, setTriggerOtp]);
|
||||||
|
|
||||||
|
async function onCheckAuthCode({
|
||||||
|
kodeId,
|
||||||
|
onSetData,
|
||||||
|
}: {
|
||||||
|
kodeId: string;
|
||||||
|
onSetData: any;
|
||||||
|
}) {
|
||||||
|
const res = await fetch(`/api/auth/check?id=${kodeId}`);
|
||||||
|
const result = await res.json();
|
||||||
|
|
||||||
|
onSetData({
|
||||||
|
nomor: result.data.nomor,
|
||||||
|
code: result.data.otp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
counter > 0 && setTimeout(() => setCounter(counter - 1), 1000);
|
counter > 0 && setTimeout(() => setCounter(counter - 1), 1000);
|
||||||
}, [counter]);
|
}, [counter]);
|
||||||
|
|
||||||
async function onVerifikasi() {
|
async function onVerifikasi() {
|
||||||
if (!inputCode)
|
if (!inputCode)
|
||||||
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Kode");
|
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Kode");
|
||||||
if (code != inputCode)
|
if (data.code != inputCode)
|
||||||
return ComponentGlobal_NotifikasiPeringatan("Kode Salah");
|
return ComponentGlobal_NotifikasiPeringatan("Kode Salah");
|
||||||
|
|
||||||
const res = await auth_funValidasi({
|
try {
|
||||||
nomor: nomor,
|
setLoading(true);
|
||||||
HIPMI_PWD: GlobalEnv.value?.WIBU_PWD as string,
|
const res = await fetch("/api/auth/validasi", {
|
||||||
});
|
method: "POST",
|
||||||
if (res.status === 200) {
|
body: JSON.stringify({
|
||||||
const resAktivasi = await auth_funDeleteAktivasiKodeOtpById(
|
nomor: data.nomor,
|
||||||
dataOtp.id as any
|
}),
|
||||||
);
|
headers: {
|
||||||
if (resAktivasi.status === 200) {
|
"Content-Type": "application/json",
|
||||||
if (res.role === "1") {
|
},
|
||||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
});
|
||||||
setLoading(true);
|
|
||||||
|
const result = await res.json();
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
localStorage.removeItem("hipmi_auth_code_id");
|
||||||
|
|
||||||
|
if (result.roleId === "1") {
|
||||||
|
ComponentGlobal_NotifikasiBerhasil(result.message);
|
||||||
router.push(RouterHome.main_home, { scroll: false });
|
router.push(RouterHome.main_home, { scroll: false });
|
||||||
|
// if (result.active === true) {
|
||||||
|
// } else {
|
||||||
|
// ComponentGlobal_NotifikasiBerhasil(result.message);
|
||||||
|
// router.push("/waiting-room", { scroll: false });
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
ComponentGlobal_NotifikasiBerhasil("Admin Logged in");
|
ComponentGlobal_NotifikasiBerhasil("Admin Logged in");
|
||||||
setLoading(true);
|
|
||||||
router.push(RouterAdminDashboard.splash_admin, { scroll: false });
|
router.push(RouterAdminDashboard.splash_admin, { scroll: false });
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ComponentGlobal_NotifikasiPeringatan(resAktivasi.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status === 400) {
|
await auth_funDeleteAktivasiKodeOtpByNomor({
|
||||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
nomor: data.nomor,
|
||||||
router.push("/register/" + dataOtp.id, { scroll: false });
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status === 401) {
|
|
||||||
const resAktivasi = await auth_funDeleteAktivasiKodeOtpById({
|
|
||||||
nomor: nomor,
|
|
||||||
});
|
|
||||||
if (resAktivasi.status === 200) {
|
|
||||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
|
||||||
router.push("/login", { scroll: false });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.status === 404) {
|
||||||
|
ComponentGlobal_NotifikasiBerhasil(result.message);
|
||||||
|
router.push("/register", { scroll: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === 400) {
|
||||||
|
ComponentGlobal_NotifikasiPeringatan(result.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onBack() {
|
async function onBack() {
|
||||||
await auth_funDeleteAktivasiKodeOtpById({ nomor: nomor });
|
localStorage.removeItem("hipmi_auth_code_id");
|
||||||
|
await auth_funDeleteAktivasiKodeOtpByNomor({ nomor: data.nomor });
|
||||||
router.back();
|
router.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onResendCode() {
|
async function onResendCode() {
|
||||||
const res = await auth_funResendCode({ nomor: nomor });
|
setLoadingResend(true);
|
||||||
if (res.status === 200) {
|
localStorage.removeItem("hipmi_auth_code_id");
|
||||||
ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
|
|
||||||
router.push("/validasi/" + res.kodeId, { scroll: false });
|
try {
|
||||||
} else {
|
const res = await fetch("/api/auth/resend", {
|
||||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
method: "POST",
|
||||||
|
body: JSON.stringify({ nomor: data.nomor }),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await res.json();
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
localStorage.setItem("hipmi_auth_code_id", result.kodeId);
|
||||||
|
ComponentGlobal_NotifikasiBerhasil("Kode Berhasil Dikirim", 2000);
|
||||||
|
setTriggerOtp(true);
|
||||||
|
setCounter(60);
|
||||||
|
setLoadingResend(false);
|
||||||
|
// router.push("/validasi", { scroll: false });
|
||||||
|
} else {
|
||||||
|
setLoadingResend(false);
|
||||||
|
ComponentGlobal_NotifikasiPeringatan(result.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
setLoadingResend(false);
|
||||||
|
ComponentGlobal_NotifikasiGagal("Terjadi Kesalahan");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// console.log(data.code);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<UIGlobal_LayoutDefault>
|
<UIGlobal_LayoutDefault>
|
||||||
<Stack h={"100vh"}>
|
<Stack h={"100vh"}>
|
||||||
<Box
|
{/* <Box
|
||||||
pt={"md"}
|
pt={"md"}
|
||||||
px={"md"}
|
px={"md"}
|
||||||
style={{
|
style={{
|
||||||
@@ -123,70 +189,84 @@ export default function Validasi({
|
|||||||
<ActionIcon variant="transparent" onClick={() => onBack()}>
|
<ActionIcon variant="transparent" onClick={() => onBack()}>
|
||||||
<IconChevronLeft color="white" />
|
<IconChevronLeft color="white" />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Box>
|
</Box> */}
|
||||||
|
{data.nomor == "" && data.code == "" ? (
|
||||||
|
<Validasi_SkeletonView />
|
||||||
|
) : (
|
||||||
|
<Stack align="center" justify="center" h={"100vh"} spacing={50}>
|
||||||
|
<Title order={2} color={MainColor.yellow}>
|
||||||
|
Verifikasi Kode OTP
|
||||||
|
</Title>
|
||||||
|
|
||||||
<Stack align="center" justify="center" h={"100vh"} spacing={50}>
|
<Stack spacing={"md"} align="center">
|
||||||
<Title order={2} color={MainColor.yellow}>
|
<Stack spacing={0} align="center">
|
||||||
Verifikasi Kode OTP
|
<Text c={"white"}>Masukan 4 digit kode otp</Text>
|
||||||
</Title>
|
<Text c={"white"}>
|
||||||
|
Yang dikirim ke{" "}
|
||||||
<Stack spacing={"md"} align="center">
|
<Text span inherit fw={"bold"}>
|
||||||
<Stack spacing={0} align="center">
|
{" "}
|
||||||
<Text c={"white"}>Masukan 4 digit kode otp</Text>
|
+{data.nomor}
|
||||||
<Text c={"white"}>
|
</Text>
|
||||||
Yang dikirim ke{" "}
|
|
||||||
<Text span inherit fw={"bold"}>
|
|
||||||
{" "}
|
|
||||||
+{nomor}
|
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Stack>
|
||||||
|
<Center>
|
||||||
|
<PinInput
|
||||||
|
size="xl"
|
||||||
|
type={"number"}
|
||||||
|
ref={focusTrapRef}
|
||||||
|
spacing={"md"}
|
||||||
|
mt={"md"}
|
||||||
|
onChange={(val) => {
|
||||||
|
setInputOtp(val);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
|
||||||
|
<Stack h={"5vh"} align="center" justify="center">
|
||||||
|
<Text fs="italic" c={"white"}>
|
||||||
|
Tidak menerima kode ?{" "}
|
||||||
|
{counter > 0 ? (
|
||||||
|
<Text fw={"bold"} inherit span>
|
||||||
|
{counter + "s"}
|
||||||
|
</Text>
|
||||||
|
) : loadingResend ? (
|
||||||
|
<Loader ml={"sm"} size={"xs"} color="yellow" />
|
||||||
|
) : (
|
||||||
|
<Text
|
||||||
|
inherit
|
||||||
|
span
|
||||||
|
onClick={() => {
|
||||||
|
onResendCode();
|
||||||
|
}}
|
||||||
|
fw={"bold"}
|
||||||
|
>
|
||||||
|
Kirim ulang
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Center>
|
<Button
|
||||||
<PinInput
|
w={300}
|
||||||
size="xl"
|
loading={loading ? true : false}
|
||||||
type={"number"}
|
loaderPosition="center"
|
||||||
ref={focusTrapRef}
|
radius={"md"}
|
||||||
spacing={"md"}
|
compact
|
||||||
mt={"md"}
|
h={40}
|
||||||
onChange={(val) => {
|
c={"black"}
|
||||||
setInputOtp(val);
|
bg={MainColor.yellow}
|
||||||
}}
|
color={"yellow"}
|
||||||
/>
|
style={{
|
||||||
</Center>
|
borderColor: AccentColor.yellow,
|
||||||
|
}}
|
||||||
<Text fs="italic" mt={"sm"} c={"white"}>
|
onClick={() => {
|
||||||
Tidak menerima kode ?{" "}
|
onVerifikasi();
|
||||||
{counter > 0 ? (
|
}}
|
||||||
<Text fw={"bold"} inherit span>
|
>
|
||||||
{counter + "s"}
|
<Text>VERIFIKASI</Text>
|
||||||
</Text>
|
</Button>
|
||||||
) : (
|
|
||||||
<Text inherit span onClick={() => onResendCode()}>
|
|
||||||
Kirim ulang
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
<Button
|
)}
|
||||||
w={300}
|
|
||||||
loading={loading ? true : false}
|
|
||||||
loaderPosition="center"
|
|
||||||
radius={"md"}
|
|
||||||
compact
|
|
||||||
h={40}
|
|
||||||
c={"black"}
|
|
||||||
bg={MainColor.yellow}
|
|
||||||
color={"yellow"}
|
|
||||||
style={{
|
|
||||||
borderColor: AccentColor.yellow,
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
onVerifikasi();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text>VERIFIKASI</Text>
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</UIGlobal_LayoutDefault>
|
</UIGlobal_LayoutDefault>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
import { RouterAuth } from "@/app/lib/router_hipmi/router_auth";
|
||||||
import { useShallowEffect } from "@mantine/hooks";
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
import { useRouter } from "next/navigation";
|
import { redirect, useRouter } from "next/navigation";
|
||||||
import { MODEL_USER } from "../home/model/interface";
|
import { MODEL_USER } from "../home/model/interface";
|
||||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
||||||
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
|
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
|
||||||
@@ -16,6 +16,12 @@ export function CheckCookies_UiLayout({
|
|||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
// if (dataUser.active == false){
|
||||||
|
// router.push(RouterHome.home_user_non_active, { scroll: false });
|
||||||
|
// return children
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
// useShallowEffect(() => {
|
// useShallowEffect(() => {
|
||||||
// onCheckCookies();
|
// onCheckCookies();
|
||||||
// }, []);
|
// }, []);
|
||||||
@@ -38,5 +44,5 @@ export function CheckCookies_UiLayout({
|
|||||||
// router.push(RouterAdminDashboard.splash_admin, { scroll: false });
|
// router.push(RouterAdminDashboard.splash_admin, { scroll: false });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return children;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
|
|||||||
451
src/app_modules/event/_ui/konfirmasi.tsx
Normal file
451
src/app_modules/event/_ui/konfirmasi.tsx
Normal file
@@ -0,0 +1,451 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {
|
||||||
|
UIGlobal_LayoutDefault,
|
||||||
|
UIGlobal_LayoutTamplate,
|
||||||
|
} from "@/app_modules/_global/ui";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Center,
|
||||||
|
Group,
|
||||||
|
Paper,
|
||||||
|
Skeleton,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
Title,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { MODEL_EVENT } from "../model/interface";
|
||||||
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
import { AccentColor, MainColor } from "@/app_modules/_global/color";
|
||||||
|
import { event_funCheckKehadiran, event_funUpdateKehadiran } from "../fun";
|
||||||
|
import {
|
||||||
|
ComponentGlobal_NotifikasiBerhasil,
|
||||||
|
ComponentGlobal_NotifikasiGagal,
|
||||||
|
} from "@/app_modules/_global/notif_global";
|
||||||
|
import { redirect, useRouter } from "next/navigation";
|
||||||
|
import { RouterEvent } from "@/app/lib/router_hipmi/router_event";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { API_RouteEvent } from "@/app/lib/api_user_router/route_api_event";
|
||||||
|
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
|
||||||
|
import moment from "moment";
|
||||||
|
import { gs_event_hotMenu } from "../global_state";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import { Event_funJoinEvent } from "../fun/create/fun_join_event";
|
||||||
|
import { Event_funJoinAndConfirmEvent } from "../fun/create/fun_join_and_confirm";
|
||||||
|
|
||||||
|
export default function Ui_Konfirmasi({
|
||||||
|
userLoginId,
|
||||||
|
eventId,
|
||||||
|
}: {
|
||||||
|
userLoginId: string;
|
||||||
|
eventId: string;
|
||||||
|
}) {
|
||||||
|
// console.log(dataEvent);
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const [data, setData] = useState<MODEL_EVENT | null>(null);
|
||||||
|
const [isJoin, setIsJoin] = useState<boolean | null>(null);
|
||||||
|
const [isPresent, setIsPresent] = useState<boolean | null>(null);
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
onLoadData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function onLoadData() {
|
||||||
|
const data = await fetch(
|
||||||
|
API_RouteEvent.get_one_by_id({ eventId: eventId })
|
||||||
|
);
|
||||||
|
const res = await data.json();
|
||||||
|
setData(res.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CEK PESERTA
|
||||||
|
useShallowEffect(() => {
|
||||||
|
onCheckPeserta();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function onCheckPeserta() {
|
||||||
|
const res = await fetch(
|
||||||
|
API_RouteEvent.check_peserta({ eventId: eventId, userId: userLoginId })
|
||||||
|
);
|
||||||
|
const data = await res.json();
|
||||||
|
console.log("cek peserta", data);
|
||||||
|
setIsJoin(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CEK KEHADIRAN
|
||||||
|
useShallowEffect(() => {
|
||||||
|
onLoadKehadiran();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function onLoadKehadiran() {
|
||||||
|
const res = await fetch(
|
||||||
|
API_RouteEvent.check_kehadiran({ eventId: eventId, userId: userLoginId })
|
||||||
|
);
|
||||||
|
const data = await res.json();
|
||||||
|
setIsPresent(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("kehadiran:", isPresent);
|
||||||
|
// console.log("data:", data);
|
||||||
|
|
||||||
|
if (data == null && isPresent == null) {
|
||||||
|
return <SkeletonIsDataNull />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DataNotFound />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moment(data?.tanggal).diff(moment(), "minute") < 0) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<EventAlreadyDone title={data?.title} eventId={eventId} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isJoin == false) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UserNotJoin
|
||||||
|
title={data?.title}
|
||||||
|
eventId={eventId}
|
||||||
|
userLoginId={userLoginId}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPresent && data) {
|
||||||
|
return <UserAlreadyConfirm title={data.title} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPresent == false && data) {
|
||||||
|
return (
|
||||||
|
<UserNotConfirm
|
||||||
|
title={data.title}
|
||||||
|
eventId={eventId}
|
||||||
|
userLoginId={userLoginId}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// const tgl = moment(data?.tanggal).diff(moment(), "minute") < 0;
|
||||||
|
// return (
|
||||||
|
// <>
|
||||||
|
// <UIGlobal_LayoutDefault>
|
||||||
|
// <Stack h={"100vh"} justify="center" c={"white"}>
|
||||||
|
// {JSON.stringify(tgl)}
|
||||||
|
// </Stack>
|
||||||
|
// </UIGlobal_LayoutDefault>
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
function DataNotFound() {
|
||||||
|
const router = useRouter();
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UIGlobal_LayoutDefault>
|
||||||
|
<Stack h={"100vh"} justify="center">
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack>
|
||||||
|
<Text fw={"bold"} align="center">
|
||||||
|
Data Event Tidak Ditemukan
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
loading={isLoading}
|
||||||
|
loaderPosition="center"
|
||||||
|
radius={"xl"}
|
||||||
|
color="green"
|
||||||
|
c={"black"}
|
||||||
|
onClick={() => {
|
||||||
|
setHotMenu(0);
|
||||||
|
setLoading(true);
|
||||||
|
router.push(RouterEvent.beranda, { scroll: false });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Kembali Ke Beranda
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</Stack>
|
||||||
|
</UIGlobal_LayoutDefault>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SkeletonIsDataNull() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UIGlobal_LayoutDefault>
|
||||||
|
<Stack h={"100vh"} justify="center">
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack>
|
||||||
|
<Skeleton height={20} width={"100%"} radius={"xl"} />{" "}
|
||||||
|
<Skeleton height={20} width={"100%"} radius={"xl"} />{" "}
|
||||||
|
<Skeleton height={20} width={"100%"} radius={"xl"} />
|
||||||
|
<Center>
|
||||||
|
<Skeleton height={40} width={"40%"} radius={"sm"} />
|
||||||
|
</Center>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</Stack>
|
||||||
|
</UIGlobal_LayoutDefault>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function UserNotJoin({
|
||||||
|
title,
|
||||||
|
eventId,
|
||||||
|
userLoginId,
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
eventId: string;
|
||||||
|
userLoginId: string;
|
||||||
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
async function onJoinAndKonfirmasi() {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
eventId: eventId,
|
||||||
|
userId: userLoginId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await Event_funJoinAndConfirmEvent(body as any);
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
|
||||||
|
router.push(RouterEvent.detail_main + eventId);
|
||||||
|
} else {
|
||||||
|
setLoading(false);
|
||||||
|
ComponentGlobal_NotifikasiGagal(res.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UIGlobal_LayoutDefault>
|
||||||
|
<Stack h={"100vh"} justify="center">
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack align="center" justify="center">
|
||||||
|
<Text align="center">
|
||||||
|
Halo, Bapak/Ibu. Kami mencatat bahwa Anda belum melakukan
|
||||||
|
registrasi melalui aplikasi untuk mengikuti acara{" "}
|
||||||
|
<Text inherit span fw={"bold"}>
|
||||||
|
{title}.
|
||||||
|
</Text>{" "}
|
||||||
|
Mohon segera lakukan registrasi melalui Event App agar dapat
|
||||||
|
mengikuti acara ini. Jika membutuhkan bantuan, jangan ragu untuk
|
||||||
|
menghubungi tim kami. Terima kasih Terima kasih atas kehadiran
|
||||||
|
Anda di acara pada hari ini. Mohon untuk mengonfirmasi kehadiran
|
||||||
|
Anda dengan menekan tombol {"Join & Konfirmasi"}
|
||||||
|
atau fitur konfirmasi yang tersedia di bawah. Terima kasih dan
|
||||||
|
selamat menikmati acara.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
loading={isLoading}
|
||||||
|
loaderPosition="center"
|
||||||
|
radius={"xs"}
|
||||||
|
bg={MainColor.yellow}
|
||||||
|
color="yellow"
|
||||||
|
c={"black"}
|
||||||
|
onClick={() => {
|
||||||
|
onJoinAndKonfirmasi();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Join & Konfirmasi
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</Stack>
|
||||||
|
</UIGlobal_LayoutDefault>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EventAlreadyDone({
|
||||||
|
title,
|
||||||
|
eventId,
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
eventId: string;
|
||||||
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
const [isLoadingDetail, setLoadingDetail] = useState(false);
|
||||||
|
const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UIGlobal_LayoutDefault>
|
||||||
|
<Stack h={"100vh"} justify="center">
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack align="center" justify="center">
|
||||||
|
<Text align="center">
|
||||||
|
Kami mohon maaf, Bapak/Ibu, acara{" "}
|
||||||
|
<Text inherit span fw={"bold"}>
|
||||||
|
{title}
|
||||||
|
</Text>{" "}
|
||||||
|
telah selesai, sehingga konfirmasi kehadiran sudah tidak dapat
|
||||||
|
dilakukan. Terima kasih atas perhatian dan minat Anda. Kami
|
||||||
|
berharap dapat bertemu di acara kami berikutnya. Terima kasih,
|
||||||
|
Bapak/Ibu, kehadiran Anda di acara.
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
<Group grow mt={"lg"}>
|
||||||
|
<Button
|
||||||
|
loading={isLoading}
|
||||||
|
loaderPosition="center"
|
||||||
|
radius={"xl"}
|
||||||
|
color="green"
|
||||||
|
c={"black"}
|
||||||
|
onClick={() => {
|
||||||
|
setHotMenu(0);
|
||||||
|
setLoading(true);
|
||||||
|
router.push(RouterEvent.beranda, { scroll: false });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Beranda
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
loading={isLoadingDetail}
|
||||||
|
loaderPosition="center"
|
||||||
|
radius={"xl"}
|
||||||
|
c={"black"}
|
||||||
|
onClick={() => {
|
||||||
|
setHotMenu(3);
|
||||||
|
setLoadingDetail(true);
|
||||||
|
router.push(RouterEvent.detail_riwayat + eventId, {
|
||||||
|
scroll: false,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Riwayat Event
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</Stack>
|
||||||
|
</UIGlobal_LayoutDefault>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function UserNotConfirm({
|
||||||
|
title,
|
||||||
|
eventId,
|
||||||
|
userLoginId,
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
eventId: string;
|
||||||
|
userLoginId: string;
|
||||||
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
async function onUpdateKonfirmasi() {
|
||||||
|
setLoading(true);
|
||||||
|
const res = await event_funUpdateKehadiran({
|
||||||
|
eventId: eventId,
|
||||||
|
userId: userLoginId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
|
||||||
|
router.push(RouterEvent.detail_main + eventId);
|
||||||
|
} else {
|
||||||
|
setLoading(false);
|
||||||
|
ComponentGlobal_NotifikasiGagal(res.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UIGlobal_LayoutDefault>
|
||||||
|
<Stack h={"100vh"} justify="center">
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack align="center" justify="center">
|
||||||
|
<Text align="center">
|
||||||
|
Terima kasih atas kehadiran Anda di acara{" "}
|
||||||
|
<Text inherit span fw={"bold"}>
|
||||||
|
{title}
|
||||||
|
</Text>{" "}
|
||||||
|
pada hari ini. Mohon untuk mengonfirmasi kehadiran Anda dengan
|
||||||
|
menekan tombol {"Hadir"} atau fitur konfirmasi yang tersedia di
|
||||||
|
bawah. Terima kasih dan selamat menikmati acara.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
loading={isLoading}
|
||||||
|
loaderPosition="center"
|
||||||
|
radius={"xs"}
|
||||||
|
bg={MainColor.yellow}
|
||||||
|
color="yellow"
|
||||||
|
c={"black"}
|
||||||
|
onClick={() => {
|
||||||
|
onUpdateKonfirmasi();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
HADIR
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</Stack>
|
||||||
|
</UIGlobal_LayoutDefault>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function UserAlreadyConfirm({ title }: { title: string }) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UIGlobal_LayoutDefault>
|
||||||
|
<Stack h={"100vh"} justify="center">
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack align="center" justify="center">
|
||||||
|
<Text align="center">
|
||||||
|
Terima kasih, Bapak/Ibu, kehadiran Anda di acara{" "}
|
||||||
|
<Text inherit span fw={"bold"}>
|
||||||
|
{title}
|
||||||
|
</Text>{" "}
|
||||||
|
telah berhasil dikonfirmasi. Kami senang menyambut Anda dan
|
||||||
|
semoga acara ini memberikan manfaat yang maksimal. Selamat
|
||||||
|
mengikuti kegiatan.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
loading={isLoading}
|
||||||
|
loaderPosition="center"
|
||||||
|
radius={"xl"}
|
||||||
|
color="green"
|
||||||
|
c={"black"}
|
||||||
|
onClick={() => {
|
||||||
|
setHotMenu(0);
|
||||||
|
setLoading(true);
|
||||||
|
router.push(RouterEvent.beranda, { scroll: false });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Beranda
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</Stack>
|
||||||
|
</UIGlobal_LayoutDefault>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import { MainColor } from "@/app_modules/_global/color";
|
|||||||
import {
|
import {
|
||||||
ComponentGlobal_NotifikasiBerhasil,
|
ComponentGlobal_NotifikasiBerhasil,
|
||||||
ComponentGlobal_NotifikasiGagal,
|
ComponentGlobal_NotifikasiGagal,
|
||||||
|
ComponentGlobal_NotifikasiPeringatan,
|
||||||
} from "@/app_modules/_global/notif_global";
|
} from "@/app_modules/_global/notif_global";
|
||||||
import { notifikasiToAdmin_funCreate } from "@/app_modules/notifikasi/fun";
|
import { notifikasiToAdmin_funCreate } from "@/app_modules/notifikasi/fun";
|
||||||
import { Button } from "@mantine/core";
|
import { Button } from "@mantine/core";
|
||||||
@@ -14,13 +15,23 @@ import { useState } from "react";
|
|||||||
import { WibuRealtime } from "wibu-pkg";
|
import { WibuRealtime } from "wibu-pkg";
|
||||||
import { Event_funCreate } from "../../fun/create/fun_create";
|
import { Event_funCreate } from "../../fun/create/fun_create";
|
||||||
import { gs_event_hotMenu } from "../../global_state";
|
import { gs_event_hotMenu } from "../../global_state";
|
||||||
|
import { event_checkStatus } from "../../fun/get/fun_check_status_by_id";
|
||||||
|
|
||||||
export default function Event_ComponentCreateButton({ value }: { value: any }) {
|
export default function Event_ComponentCreateButton({
|
||||||
|
value,
|
||||||
|
diffTimeStart,
|
||||||
|
diffTimeEnd,
|
||||||
|
}: {
|
||||||
|
value: any;
|
||||||
|
diffTimeStart: number;
|
||||||
|
diffTimeEnd: number;
|
||||||
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu);
|
const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu);
|
||||||
const [isLoading, setLoading] = useState(false);
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
async function onSave() {
|
async function onSave() {
|
||||||
|
|
||||||
const res = await Event_funCreate(value);
|
const res = await Event_funCreate(value);
|
||||||
|
|
||||||
if (res.status === 201) {
|
if (res.status === 201) {
|
||||||
@@ -71,7 +82,8 @@ export default function Event_ComponentCreateButton({ value }: { value: any }) {
|
|||||||
value.deskripsi === "" ||
|
value.deskripsi === "" ||
|
||||||
value.eventMaster_TipeAcaraId === 0 ||
|
value.eventMaster_TipeAcaraId === 0 ||
|
||||||
value.tanggal === "function Date() { [native code] }" ||
|
value.tanggal === "function Date() { [native code] }" ||
|
||||||
moment(value.tanggal).diff(moment(), "minutes") < 0
|
// moment(value.tanggal).diff(moment(), "minutes") < 0
|
||||||
|
diffTimeEnd - 1 < diffTimeStart
|
||||||
}
|
}
|
||||||
loaderPosition="center"
|
loaderPosition="center"
|
||||||
loading={isLoading ? true : false}
|
loading={isLoading ? true : false}
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ export function ComponentEvent_CardBeranda({ data }: { data: any }) {
|
|||||||
<Title order={5} lineClamp={1}>
|
<Title order={5} lineClamp={1}>
|
||||||
{data.title}
|
{data.title}
|
||||||
</Title>
|
</Title>
|
||||||
<Text align="right" fz={"sm"} lineClamp={1}>
|
{/* <Text align="right" fz={"sm"} lineClamp={1}>
|
||||||
{new Intl.DateTimeFormat("id-ID", {
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
dateStyle: "medium",
|
dateStyle: "medium",
|
||||||
}).format(data.tanggal)}
|
}).format(data?.tanggal)}
|
||||||
</Text>
|
</Text> */}
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Text fz={"sm"} lineClamp={2}>
|
<Text fz={"sm"} lineClamp={2}>
|
||||||
|
|||||||
@@ -9,26 +9,16 @@ export default function ComponentEvent_DetailData({
|
|||||||
}: {
|
}: {
|
||||||
data: MODEL_EVENT;
|
data: MODEL_EVENT;
|
||||||
}) {
|
}) {
|
||||||
const tgl = data.tanggal;
|
|
||||||
const hari = tgl.toLocaleString("id-ID", { dateStyle: "full" });
|
|
||||||
|
|
||||||
const jam = tgl.toLocaleTimeString([], {
|
|
||||||
timeStyle: "short",
|
|
||||||
hourCycle: "h24",
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ComponentGlobal_CardStyles marginBottom={"16px"}>
|
<ComponentGlobal_CardStyles marginBottom={"16px"}>
|
||||||
<Stack px={"sm"} spacing={"lg"}>
|
<Stack px={"sm"} spacing={"xl"}>
|
||||||
<Title lineClamp={2} align="center" w={"100%"} order={4}>
|
<Title lineClamp={2} align="center" w={"100%"} order={4}>
|
||||||
{data ? data?.title : null}
|
{data ? data?.title : null}
|
||||||
</Title>
|
</Title>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={4}>
|
<Grid.Col span={4}>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
<Text fw={"bold"}>Lokasi</Text>
|
||||||
Lokasi
|
|
||||||
</Text>
|
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
<Grid.Col span={"auto"}>
|
<Grid.Col span={"auto"}>
|
||||||
@@ -37,37 +27,59 @@ export default function ComponentEvent_DetailData({
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={4}>
|
<Grid.Col span={4}>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
<Text fw={"bold"}>Tipe Acara</Text>
|
||||||
Tipe Acara
|
|
||||||
</Text>
|
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
<Grid.Col span={"auto"}>
|
<Grid.Col span={"auto"}>
|
||||||
<Text>{data ? data.EventMaster_TipeAcara?.name : null}</Text>
|
<Text>{data ? data.EventMaster_TipeAcara?.name : null}</Text>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid>
|
<Stack spacing={"xs"}>
|
||||||
<Grid.Col span={4}>
|
<Text fw={"bold"}>Tanggal & Waktu</Text>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
<Grid>
|
||||||
Tanggal
|
<Grid.Col span={4}>
|
||||||
</Text>
|
<Text fw={"bold"}>Mulai</Text>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
<Grid.Col span={"auto"}>{hari ? hari : ""}</Grid.Col>
|
<Grid.Col span={"auto"}>
|
||||||
</Grid>
|
<Text>
|
||||||
<Grid>
|
{" "}
|
||||||
<Grid.Col span={4}>
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
dateStyle: "full",
|
||||||
Jam
|
}).format(data?.tanggal)}
|
||||||
</Text>
|
,{" "}
|
||||||
</Grid.Col>
|
<Text span inherit>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
<Grid.Col span={"auto"}>{jam ? jam : ""}</Grid.Col>
|
timeStyle: "short",
|
||||||
</Grid>
|
}).format(data?.tanggal)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
<Grid>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<Text fw={"bold"}>Selesai</Text>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
|
<Grid.Col span={"auto"}>
|
||||||
|
<Text>
|
||||||
|
{" "}
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
dateStyle: "full",
|
||||||
|
}).format(data?.tanggalSelesai)}
|
||||||
|
,{" "}
|
||||||
|
<Text span inherit>
|
||||||
|
{new Intl.DateTimeFormat("id-ID", {
|
||||||
|
timeStyle: "short",
|
||||||
|
}).format(data?.tanggalSelesai)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
<Text fw={"bold"}>Deskripsi</Text>
|
||||||
Deskripsi
|
|
||||||
</Text>
|
|
||||||
<Text>{data ? data?.deskripsi : null}</Text>
|
<Text>{data ? data?.deskripsi : null}</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -4,83 +4,110 @@ import {
|
|||||||
ComponentGlobal_AvatarAndUsername,
|
ComponentGlobal_AvatarAndUsername,
|
||||||
ComponentGlobal_CardStyles,
|
ComponentGlobal_CardStyles,
|
||||||
} from "@/app_modules/_global/component";
|
} from "@/app_modules/_global/component";
|
||||||
import { Grid, Stack, Text, Title } from "@mantine/core";
|
import { Center, Grid, Skeleton, Stack, Text, Title } from "@mantine/core";
|
||||||
import { MODEL_EVENT } from "../../model/interface";
|
import { MODEL_EVENT } from "../../model/interface";
|
||||||
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { API_RouteEvent } from "@/app/lib/api_user_router/route_api_event";
|
||||||
|
import { Event_ComponentSkeletonDetail } from "../skeleton/comp_skeleton_detail";
|
||||||
|
import moment from "moment";
|
||||||
|
import "moment/locale/id";
|
||||||
|
|
||||||
export default function ComponentEvent_DetailMainData({
|
export default function ComponentEvent_DetailMainData({
|
||||||
data,
|
eventId,
|
||||||
}: {
|
}: {
|
||||||
data: MODEL_EVENT;
|
eventId: string;
|
||||||
}) {
|
}) {
|
||||||
const tgl = data.tanggal;
|
const [data, setData] = useState<MODEL_EVENT | null>(null);
|
||||||
const hari = tgl.toLocaleString("id-ID", { dateStyle: "full" });
|
|
||||||
|
|
||||||
const jam = tgl.toLocaleTimeString([], {
|
useShallowEffect(() => {
|
||||||
timeStyle: "short",
|
onLoadData();
|
||||||
hourCycle: "h24",
|
}, []);
|
||||||
});
|
|
||||||
|
async function onLoadData() {
|
||||||
|
const data = await fetch(
|
||||||
|
API_RouteEvent.get_one_by_id({ eventId: eventId })
|
||||||
|
);
|
||||||
|
const res = await data.json();
|
||||||
|
setData(res.data);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ComponentGlobal_CardStyles>
|
{data == null ? (
|
||||||
<Stack px={"xs"} spacing={"xl"}>
|
<Event_ComponentSkeletonDetail />
|
||||||
<ComponentGlobal_AvatarAndUsername
|
) : (
|
||||||
profile={data?.Author?.Profile as any}
|
<ComponentGlobal_CardStyles>
|
||||||
/>
|
<Stack px={"xs"} spacing={"xl"}>
|
||||||
|
<ComponentGlobal_AvatarAndUsername
|
||||||
|
profile={data?.Author?.Profile as any}
|
||||||
|
/>
|
||||||
|
|
||||||
<Stack>
|
<Stack spacing={"xl"}>
|
||||||
<Title align="center" order={4}>
|
<Title align="center" order={4}>
|
||||||
{data ? data.title : null}
|
{data ? data.title : null}
|
||||||
</Title>
|
</Title>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={4}>
|
<Grid.Col span={4}>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
<Text fw={"bold"}>Lokasi</Text>
|
||||||
Lokasi
|
</Grid.Col>
|
||||||
</Text>
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
</Grid.Col>
|
<Grid.Col span={"auto"}>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
<Text>{data ? data.lokasi : null}</Text>
|
||||||
<Grid.Col span={"auto"}>
|
</Grid.Col>
|
||||||
<Text>{data ? data.lokasi : null}</Text>
|
</Grid>
|
||||||
</Grid.Col>
|
<Grid>
|
||||||
</Grid>
|
<Grid.Col span={4}>
|
||||||
<Grid>
|
<Text fw={"bold"}>Tipe Acara</Text>
|
||||||
<Grid.Col span={4}>
|
</Grid.Col>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
Tipe Acara
|
<Grid.Col span={"auto"}>
|
||||||
</Text>
|
<Text>{data ? data.EventMaster_TipeAcara.name : null}</Text>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
</Grid>
|
||||||
<Grid.Col span={"auto"}>
|
|
||||||
<Text>{data ? data.EventMaster_TipeAcara.name : null}</Text>
|
<Stack spacing={"xs"}>
|
||||||
</Grid.Col>
|
<Text fw={"bold"}>Tanggal & Waktu</Text>
|
||||||
</Grid>
|
<Grid>
|
||||||
<Grid>
|
<Grid.Col span={4}>
|
||||||
<Grid.Col span={4}>
|
<Text fw={"bold"}>Mulai</Text>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
</Grid.Col>
|
||||||
Tanggal
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
</Text>
|
<Grid.Col span={"auto"}>
|
||||||
</Grid.Col>
|
<Text>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
{moment(
|
||||||
<Grid.Col span={"auto"}>{hari}</Grid.Col>
|
data.tanggal?.toLocaleString("id-ID", {
|
||||||
</Grid>
|
dateStyle: "full",
|
||||||
<Grid>
|
})
|
||||||
<Grid.Col span={4}>
|
).format("dddd, DD MMMM YYYY, LT")}
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
</Text>
|
||||||
Jam
|
</Grid.Col>
|
||||||
</Text>
|
</Grid>
|
||||||
</Grid.Col>
|
<Grid>
|
||||||
<Grid.Col span={1}>:</Grid.Col>
|
<Grid.Col span={4}>
|
||||||
<Grid.Col span={"auto"}>{jam}</Grid.Col>
|
<Text fw={"bold"}>Selesai</Text>
|
||||||
</Grid>
|
</Grid.Col>
|
||||||
<Stack spacing={2}>
|
<Grid.Col span={1}>:</Grid.Col>
|
||||||
<Text fw={"bold"} fz={"sm"}>
|
<Grid.Col span={"auto"}>
|
||||||
Deskripsi
|
<Text>
|
||||||
</Text>
|
{moment(
|
||||||
<Text>{data ? data?.deskripsi : null}</Text>
|
data.tanggalSelesai?.toLocaleString("id-ID", {
|
||||||
|
dateStyle: "full",
|
||||||
|
})
|
||||||
|
).format("dddd, DD MMMM YYYY, LT")}
|
||||||
|
</Text>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Stack spacing={2}>
|
||||||
|
<Text fw={"bold"}>Deskripsi</Text>
|
||||||
|
<Text>{data ? data?.deskripsi : null}</Text>
|
||||||
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</ComponentGlobal_CardStyles>
|
||||||
</ComponentGlobal_CardStyles>
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,202 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ActionIcon,
|
||||||
|
Avatar,
|
||||||
Center,
|
Center,
|
||||||
|
Grid,
|
||||||
|
Group,
|
||||||
|
Skeleton,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
Title
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ComponentGlobal_AvatarAndUsername,
|
ComponentGlobal_AvatarAndUsername,
|
||||||
ComponentGlobal_CardStyles,
|
ComponentGlobal_CardStyles,
|
||||||
|
ComponentGlobal_LoaderAvatar,
|
||||||
} from "@/app_modules/_global/component";
|
} from "@/app_modules/_global/component";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { MODEL_EVENT_PESERTA } from "../../model/interface";
|
import { MODEL_EVENT_PESERTA } from "../../model/interface";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
|
||||||
|
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||||
|
import { funGlobal_CheckProfile } from "@/app_modules/_global/fun/get";
|
||||||
|
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
|
||||||
|
import { useState } from "react";
|
||||||
|
import moment from "moment";
|
||||||
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
import { API_RouteEvent } from "@/app/lib/api_user_router/route_api_event";
|
||||||
|
import Event_ComponentSkeletonListPeserta from "../skeleton/comp_skeleton_list_peserta";
|
||||||
|
|
||||||
export default function ComponentEvent_ListPeserta({
|
export default function ComponentEvent_ListPeserta({
|
||||||
listPeserta,
|
|
||||||
total,
|
total,
|
||||||
|
eventId,
|
||||||
|
isNewPeserta,
|
||||||
}: {
|
}: {
|
||||||
listPeserta: MODEL_EVENT_PESERTA[];
|
|
||||||
total: number;
|
total: number;
|
||||||
|
eventId: string;
|
||||||
|
isNewPeserta?: boolean | null;
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [data, setData] = useState<MODEL_EVENT_PESERTA[] | null>(null);
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
onLoadPeserta();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
if (isNewPeserta !== null && isNewPeserta === true) {
|
||||||
|
onLoadPeserta();
|
||||||
|
}
|
||||||
|
}, [isNewPeserta]);
|
||||||
|
|
||||||
|
async function onLoadPeserta() {
|
||||||
|
const res = await fetch(
|
||||||
|
API_RouteEvent.list_peserta({ eventId: eventId, page: 1 })
|
||||||
|
);
|
||||||
|
const data = await res.json();
|
||||||
|
setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ComponentGlobal_CardStyles>
|
{data === null ? (
|
||||||
<Stack spacing={"md"} px={"sm"}>
|
<Event_ComponentSkeletonListPeserta />
|
||||||
<Center>
|
) : (
|
||||||
<Title order={5}>Daftar Peserta ({total})</Title>
|
<ComponentGlobal_CardStyles>
|
||||||
</Center>
|
<Stack spacing={"md"} px={"sm"}>
|
||||||
|
|
||||||
{_.isEmpty(listPeserta) ? (
|
|
||||||
<Center>
|
<Center>
|
||||||
<Text fz={"xs"} fw={"bold"}>
|
<Title order={5}>Daftar Peserta ({total})</Title>
|
||||||
- Tidak ada peserta -
|
|
||||||
</Text>
|
|
||||||
</Center>
|
</Center>
|
||||||
) : (
|
|
||||||
<Stack>
|
{_.isEmpty(data) ? (
|
||||||
{listPeserta.map((e, i) => (
|
<Center>
|
||||||
<Stack key={i} spacing={"sm"}>
|
<Text fz={"xs"} fw={"bold"}>
|
||||||
<ComponentGlobal_AvatarAndUsername
|
- Tidak ada peserta -
|
||||||
profile={e.User.Profile as any}
|
</Text>
|
||||||
sizeAvatar={30}
|
</Center>
|
||||||
fontSize={"sm"}
|
) : (
|
||||||
/>
|
<Stack>
|
||||||
{/* <Divider /> */}
|
{data.map((e, i) => (
|
||||||
</Stack>
|
<Stack key={i} spacing={"sm"}>
|
||||||
))}
|
<ComponentEvent_AvatarAndUsername
|
||||||
</Stack>
|
profile={e?.User?.Profile as any}
|
||||||
)}
|
sizeAvatar={30}
|
||||||
</Stack>
|
fontSize={"sm"}
|
||||||
</ComponentGlobal_CardStyles>
|
tanggalMulai={e?.Event?.tanggal}
|
||||||
|
tanggalSelesai={e?.Event?.tanggalSelesai}
|
||||||
|
isPresent={e?.isPresent}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <Divider /> */}
|
||||||
|
</Stack>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type IFontSize = "xs" | "sm" | "md" | "lg" | "xl";
|
||||||
|
|
||||||
|
function ComponentEvent_AvatarAndUsername({
|
||||||
|
profile,
|
||||||
|
component,
|
||||||
|
sizeAvatar,
|
||||||
|
fontSize,
|
||||||
|
tanggalMulai,
|
||||||
|
tanggalSelesai,
|
||||||
|
isPresent,
|
||||||
|
}: {
|
||||||
|
profile: Prisma.ProfileSelect;
|
||||||
|
component?: React.ReactNode;
|
||||||
|
sizeAvatar?: number;
|
||||||
|
fontSize?: IFontSize | {};
|
||||||
|
tanggalMulai?: Date;
|
||||||
|
tanggalSelesai?: Date;
|
||||||
|
isPresent?: boolean;
|
||||||
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
|
async function onCheckProfile() {
|
||||||
|
const res = await funGlobal_CheckProfile({ profileId: profile.id as any });
|
||||||
|
|
||||||
|
if (res !== null) {
|
||||||
|
setVisible(true);
|
||||||
|
router.push(RouterProfile.katalog({ id: profile.id as any }));
|
||||||
|
} else {
|
||||||
|
ComponentGlobal_NotifikasiPeringatan("Id tidak ditemukan");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tglMulai = moment(tanggalMulai).diff(moment(), "minutes");
|
||||||
|
|
||||||
|
const tglSelesai = moment(tanggalSelesai).diff(moment(), "minutes");
|
||||||
|
|
||||||
|
// console.log("mulai:", tglMulai, "selesai:", tglSelesai);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Grid align="flex-start" justify="space-around">
|
||||||
|
<Grid.Col span={2} style={{ minHeight: 50 }}>
|
||||||
|
<ActionIcon
|
||||||
|
radius={"xl"}
|
||||||
|
variant="transparent"
|
||||||
|
onClick={() => onCheckProfile()}
|
||||||
|
>
|
||||||
|
{visible ? (
|
||||||
|
<Avatar radius={"xl"} size={40}>
|
||||||
|
<ComponentGlobal_Loader />
|
||||||
|
</Avatar>
|
||||||
|
) : (
|
||||||
|
<ComponentGlobal_LoaderAvatar
|
||||||
|
fileId={profile?.imageId as any}
|
||||||
|
sizeAvatar={sizeAvatar}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ActionIcon>
|
||||||
|
</Grid.Col>
|
||||||
|
|
||||||
|
<Grid.Col span={"auto"} style={{ minHeight: 50 }}>
|
||||||
|
<Stack justify="center" h={30}>
|
||||||
|
<Text
|
||||||
|
fw={"bold"}
|
||||||
|
fz={fontSize ? fontSize : "sm"}
|
||||||
|
lineClamp={1}
|
||||||
|
onClick={() => onCheckProfile()}
|
||||||
|
>
|
||||||
|
{profile?.name}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Grid.Col>
|
||||||
|
|
||||||
|
{/* {component && (
|
||||||
|
<Grid.Col span={"auto"} style={{ minHeight: 50 }}>
|
||||||
|
<Stack justify="center" h={30}>
|
||||||
|
{component}
|
||||||
|
</Stack>
|
||||||
|
</Grid.Col>
|
||||||
|
)} */}
|
||||||
|
|
||||||
|
{tglMulai < 0 && (
|
||||||
|
<Grid.Col span={3} style={{ minHeight: 50 }}>
|
||||||
|
<Group position="right">
|
||||||
|
<Stack justify="center" h={30}>
|
||||||
|
<Text fw={"bold"} fz={fontSize ? fontSize : "sm"}>
|
||||||
|
{isPresent ? "Hadir" : "-"}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
</Grid.Col>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import Event_ComponentCreateButton from "./button/button_create_event";
|
import Event_ComponentCreateButton from "./button/button_create_event";
|
||||||
|
import Event_ComponentSkeletonBeranda from "./skeleton/comp_skeleton_beranda";
|
||||||
|
import { Event_ComponentSkeletonDetail } from "./skeleton/comp_skeleton_detail";
|
||||||
import { Event_ComponentSkeletonDetailData } from "./skeleton/comp_skeleton_detail_data";
|
import { Event_ComponentSkeletonDetailData } from "./skeleton/comp_skeleton_detail_data";
|
||||||
|
import Event_ComponentSkeletonListPeserta from "./skeleton/comp_skeleton_list_peserta";
|
||||||
|
|
||||||
export { Event_ComponentSkeletonDetailData };
|
export { Event_ComponentSkeletonDetailData };
|
||||||
export { Event_ComponentCreateButton };
|
export { Event_ComponentCreateButton };
|
||||||
|
export { Event_ComponentSkeletonBeranda };
|
||||||
|
export { Event_ComponentSkeletonDetail };
|
||||||
|
export { Event_ComponentSkeletonListPeserta };
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { AccentColor } from "@/app_modules/_global/color";
|
||||||
|
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
|
||||||
|
import { Grid, Group, Paper, Skeleton, Stack, Text } from "@mantine/core";
|
||||||
|
|
||||||
|
export default function Event_ComponentSkeletonBeranda() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{Array.from({ length: 10 }).map((_, index) => (
|
||||||
|
<ComponentGlobal_CardStyles key={index} marginBottom={"16px"}>
|
||||||
|
<Stack>
|
||||||
|
<Grid align="center">
|
||||||
|
<Grid.Col span={"content"}>
|
||||||
|
<Skeleton radius={"100%"} h={50} w={50} />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={"auto"}>
|
||||||
|
<Skeleton h={20} w={"50%"} />
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Stack>
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
|
||||||
|
import { Stack, Center, Skeleton, Grid } from "@mantine/core";
|
||||||
|
|
||||||
|
export function Event_ComponentSkeletonDetail() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack>
|
||||||
|
<Grid align="center">
|
||||||
|
<Grid.Col span={"content"}>
|
||||||
|
<Skeleton radius={"100%"} h={50} w={50} />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={"auto"}>
|
||||||
|
<Skeleton h={20} w={"50%"} />
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
<Stack spacing={"xl"}>
|
||||||
|
<Center>
|
||||||
|
<Skeleton h={20} w={"50%"} />
|
||||||
|
</Center>
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
<Skeleton h={20} w={"50%"} />
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
<Stack>
|
||||||
|
<Skeleton h={20} w={"50%"} />
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
<Skeleton h={20} w={"100%"} />
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
|
||||||
|
import { Stack, Center, Skeleton, Grid } from "@mantine/core";
|
||||||
|
|
||||||
|
export default function Event_ComponentSkeletonListPeserta() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ComponentGlobal_CardStyles>
|
||||||
|
<Stack spacing={"lg"}>
|
||||||
|
<Center>
|
||||||
|
<Skeleton height={20} width={"50%"} />
|
||||||
|
</Center>
|
||||||
|
|
||||||
|
<Stack>
|
||||||
|
{Array.from(new Array(3)).map((e, i) => (
|
||||||
|
<Grid key={i} align="center">
|
||||||
|
<Grid.Col span={"content"}>
|
||||||
|
<Skeleton radius={"100%"} h={30} w={30} />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={"auto"}>
|
||||||
|
<Skeleton h={20} w={"50%"} />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={2}>
|
||||||
|
<Skeleton h={20} w={"50%"} />
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</ComponentGlobal_CardStyles>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user